module Mitamirri class StatReport # Search params attr_accessor :action_kind attr_accessor :site attr_accessor :time_period attr_accessor :visit_kind # Initialization def initialize(args = {}) args.each{|k,v| self.send("#{k}=",v) if self.respond_to?(k)} self.time_period = args[:time_period] || 'past 6 months' self.stats end def stats if self.site && self.site.downcase != 'all sites' @stats ||= TrackableStat.by_site(self.site).for_date_range(dates.first, dates.last.end_of_month) else @stats ||= TrackableStat.for_date_range(dates.first, dates.last.end_of_month) end end # Generate an array of dates spanning the appropriate time period. def dates return @dates if @dates @dates = [] case self.time_period when 'past month' _increment = 1 when 'past 3 months' _increment = 2 when 'past 6 months' _increment = 5 when 'past 12 months' _increment = 11 else 'all time' _increment = 24 end (1.._increment).each{ |i| @dates << (Time.zone.now - i.months).beginning_of_month } @dates.reverse! @dates << Time.zone.now.end_of_month @dates end # Graphing data def self.keywords_by_frequency(args) TrackableSession.keywords_histogram(args).inject([]){|a,v| a << KeywordStat.new(:keyword => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24] end def self.top_referrers(args) TrackableSession.referrers_histogram(args).inject([]){|a,v| a << ReferrerStat.new(:referrer => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24] end def visits(args) _visits = [] _visits << Visit.new(:kind => 'All', :stats => visit_stats(args)) _visits << Visit.new(:kind => 'Direct Traffic', :stats => visit_stats(args.merge(:visit_kind => 'direct'))) _visits << Visit.new(:kind => 'Referring Sites', :stats => visit_stats(args.merge(:visit_kind => 'natural'))) _visits << Visit.new(:kind => 'Organic Search', :stats => visit_stats(args.merge(:visit_kind => 'search'))) _visits << Visit.new(:kind => 'Paid Search', :stats => visit_stats(args.merge(:visit_kind => 'paid'))) _visits end def visit_stats(args) _visit_stats = [] dates.each do |date| _visit_stats << VisitStat.new(:date => date, :visits => TrackableSession.search_without_date(args).for_month(date).count) end _visit_stats end # Statistics def average_pages_per_visit sprintf("%.1f", total_pageviews / total_visits.to_f) end def average_time_on_site average = total_duration / total_visits.to_f average > 60 ? sprintf("%.1f minutes", average / 60.0) : sprintf("%.1f seconds", average) end def bounce_rate bounce_rate = total_bounces / total_visits.to_f sprintf("%.1f%", bounce_rate * 100) end def conversion_rate conversion_rate = total_conversions / total_visits.to_f sprintf("%.1f%", conversion_rate * 100) end def total_bounces @total_bounces ||= stats.fields(:bounces).map{|s| s.bounces}.sum end def total_clickthroughs @total_clickthroughs ||= stats.fields(:clickthroughs).map{|s| s.clickthroughs}.sum end def total_clickthroughs_percentage sprintf("%.1f%", (total_clickthroughs / total_visits.to_f) * 100) end def total_conversions @total_conversions ||= stats.fields(:conversions).map{|s| s.conversions}.sum end def total_direct_visits @total_direct_visits ||= stats.fields(:direct_visits).map{|s| s.direct_visits}.sum end def total_direct_visits_percentage sprintf("%.1f%", (total_direct_visits / total_visits.to_f) * 100) end def total_duration @total_duration ||= stats.fields(:duration).map{|s| s.duration}.sum end def total_new_visits @total_new_visits ||= stats.fields(:new_visits).map{|s| s.new_visits}.sum end def total_new_visits_percentage sprintf("%.1f%", (total_new_visits / total_visits.to_f) * 100) end def total_organic_visits @total_organic_visits ||= stats.fields(:organic_visits).map{|s| s.organic_visits}.sum end def total_organic_visits_percentage sprintf("%.1f%", (total_organic_visits / total_visits.to_f) * 100) end def total_pageviews @total_pageviews ||= stats.fields(:pageviews).map{|s| s.pageviews}.sum end def total_ppc_visits @total_ppc_visits ||= stats.fields(:ppc_visits).map{|s| s.ppc_visits}.sum end def total_ppc_visits_percentage sprintf("%.1f%", (total_ppc_visits / total_visits.to_f) * 100) end def total_return_visits @total_return_visits ||= stats.fields(:return_visits).map{|s| s.return_visits}.sum end def total_return_visits_percentage sprintf("%.1f%", (total_return_visits / total_visits.to_f) * 100) end def total_search_visits @total_search_visits ||= stats.fields(:search_visits).map{|s| s.search_visits}.sum end def total_search_visits_percentage sprintf("%.1f%", (total_search_visits / total_visits.to_f) * 100) end def total_visits @total_visits ||= stats.fields(:visits).map{|s| s.visits}.sum end # Inner stat classes class KeywordStat attr_accessor :keyword attr_accessor :count def initialize(args) args.each{ |k,v| self.send("#{k}=", v) } end end class ReferrerStat attr_accessor :referrer attr_accessor :count def initialize(args) args.each{ |k,v| self.send("#{k}=", v) } end end class Visit attr_accessor :kind attr_accessor :date attr_accessor :stats def initialize(args) args.each{ |k,v| self.send("#{k}=", v) } end end class VisitStat attr_accessor :date attr_accessor :visits def initialize(args) args.each{ |k,v| self.send("#{k}=", v) } end def short_date self.date.to_s(:month_year) end end end end