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