module Mitamirri class VisitorProfileReport # 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.sessions end def criteria _criteria = self.sessions.to_hash _criteria.delete(:sort) _criteria end def sessions @sessions ||= TrackableSession.search( :action_kind => self.action_kind, :site => self.site, :time_period => self.time_period, :visit_kind => self.visit_kind ) 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 locations_by_frequency(args) TrackableSession.locations_histogram(args).inject([]){|a,v| a << LocationStat.new(:name => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24] end def user_agents_by_frequency(args) TrackableSession.user_agents_histogram(args).inject([]){|a,v| a << UserAgentStat.new(:user_agent => v[0], :count => v[1]); a}.sort{|a,b| a.count <=> b.count}.reverse[0..24] end # Inner stat classes class Visitor attr_accessor :user_agent_stats attr_accessor :location_stats def initialize(args) args.each{ |k,v| self.send("#{k}=", v) } end end class UserAgentStat attr_accessor :user_agent attr_accessor :count def initialize(args) args.each{ |k,v| self.send("#{k}=", v) } end end class LocationStat attr_accessor :name attr_accessor :latitude attr_accessor :longitude attr_accessor :count def initialize(args) args.each{ |k,v| self.send("#{k}=", v) } geocode end def geocode if _location = TrackableLocation.where(:location => self.name).first self.latitude = _location.latitude self.longitude = _location.longitude else begin _coords = Geokit::Geocoders::MultiGeocoder.geocode(self.name) rescue end if _coords && _coords.success self.latitude = _coords.lat self.longitude = _coords.lng TrackableLocation.create(:location => self.name, :latitude => self.latitude, :longitude => self.longitude) end end end def geocoded? self.latitude && self.longitude end def sanitized_name self.name.gsub(/'/,"\\'") end end end end