app/models/cohortly/report.rb in cohortly-0.0.5 vs app/models/cohortly/report.rb in cohortly-0.0.6

- old
+ new

@@ -1,62 +1,80 @@ module Cohortly class Report # this is the reduced collection - attr_accessor :collection - def initialize(collection) - self.collection = collection + attr_accessor :collection, :weekly, :key_pattern, :groups, :tags + def initialize( tags = nil, groups = nil, weekly = true ) + self.collection = Cohortly::Metric.report_table_name(tags, groups, weekly) + self.groups = groups + self.tags = tags + self.weekly = weekly + self.key_pattern = self.weekly ? "%Y-%W" : "%Y-%m" end def data @data ||= (Cohortly::Metric.database[self.collection].find().collect {|x| x}).sort_by {|x| x['_id'] } end - def start_month + def fix_data_lines + data.each do |line| + period_cohorts_from(line['_id']).collect do |key| + if line["value"][key].nil? + line["value"][key] = { } + end + end + end + end + + def offset + self.weekly ? 1.week : 1.month + end + + def start_key data.first['_id'] end - def end_month - time_to_month(Time.now) + def end_key + time_to_key(Time.now.utc) end - def time_to_month(time) - time.strftime('%Y-%m') + def time_to_key(time) + time.strftime(self.key_pattern) end - def month_to_time(str_month) - year, month = str_month.split('-') - Time.utc(year.to_i, month.to_i) + def key_to_time(report_key) + DateTime.strptime(report_key, self.key_pattern).to_time.utc end - def user_count_in_cohort(str_month) - Cohortly::Metric.collection.distinct(:user_id, - { :user_start_date => { :$gt => month_to_time(str_month), - :$lt => (month_to_time(str_month) + 1.month)}}).length + def user_count_in_cohort(report_key) + params = { :user_start_date => { :$gt => key_to_time(report_key), + :$lt => (key_to_time(report_key) + self.offset)}} + params[:tags] = { :$in => groups } if self.groups + Cohortly::Metric.collection.distinct(:user_id, params).length end - def month_cohorts + def period_cohorts return [] unless data.first - start_time = month_to_time(start_month) - end_time = month_to_time(end_month) + start_time = key_to_time(start_key) + end_time = key_to_time(end_key) cur_time = start_time res = [] while(cur_time <= end_time) do - res << time_to_month(cur_time) - cur_time += 1.month + res << time_to_key(cur_time) + cur_time += self.offset end res end - - def month_cohorts_from(cohort_key) - index = month_cohorts.index(cohort_key) - month_cohorts[index..-1] + + def period_cohorts_from(cohort_key) + index = period_cohorts.index(cohort_key) + period_cohorts[index..-1] end def report_line(cohort_key) line = data.find {|x| x['_id'] == cohort_key} return [] unless line - month_cohorts_from(cohort_key).collect do |key| + period_cohorts_from(cohort_key).collect do |key| if line["value"][key] line["value"][key].keys.length else 0 end @@ -68,11 +86,22 @@ base = user_count_in_cohort(cohort_key) line.collect { |x| (x && base > 0.0 ) ? (x/base.to_f * 100).round : 0 }.unshift base end def report_totals - month_cohorts.collect do |cohort_key| + period_cohorts.collect do |cohort_key| report_line(cohort_key) end + end + + def base_n + @base_n ||= self.period_cohorts.inject({ }) { |accum, key| accum[key] = user_count_in_cohort(key); accum } + end + + def as_json(*args) + fix_data_lines + { :data => data, + :base_n => base_n + } end end end