app/models/trackable_session.rb in mitamirri-0.13.8 vs app/models/trackable_session.rb in mitamirri-2.0.8

- old
+ new

@@ -1,331 +1,415 @@ -class TrackableSession +# Tracks user activity to a given site. +class TrackableSession < TrackableBase - include MongoMapper::Document + # Mongoid Config ================================================================================= - # MongoMapper Setup ============================================================================== + include Mongoid::Document + include Mongoid::Timestamps - belongs_to :trackable_stat - many :trackable_actions, :order => :created_at + referenced_in :trackable_stat + references_many :trackable_actions - key :bounce, Boolean, :index => true - key :clickthrough_destination, String - key :duration, Integer - key :entrance_page, String - key :exit_page, String - key :has_clicks, Boolean, :index => true - key :has_clickthroughs, Boolean, :index => true - key :has_conversions, Boolean - key :has_mouseovers, Boolean, :index => true - key :has_scrolls, Boolean, :index => true - key :initial_request_url, String - key :ip_address, String, :index => true - key :kind, String, :index => true - key :location, String - key :new_visit, Boolean, :index => true - key :referrer, String, :index => true - key :referring_keywords, String - key :session_id, String, :index => true - key :site, String, :index => true - key :spider, Boolean, :index => true - key :trackable_stat_id, ObjectId - key :user_agent, String - key :views_count, Integer - timestamps! - ensure_index :created_at - + field :bounce, :type => Boolean + field :clickthrough_destination + field :duration, :type => Integer + field :entrance_page + field :exit_page + field :has_clicks, :type => Boolean + field :has_clickthroughs, :type => Boolean + field :has_conversions, :type => Boolean + field :has_mouseovers, :type => Boolean + field :has_scrolls, :type => Boolean + field :initial_request_url + field :ip_address + field :kind + field :location + field :new_visit, :type => Boolean + field :referrer + field :referring_keywords + field :session_id + field :site + field :spider, :type => Boolean + field :user_agent + field :views_count, :type => Integer + field :visit_kind + + index :bounce, :unique => false + index :created_at, :unique => false + index :has_clicks, :unique => false + index :has_clickthroughs, :unique => false + index :has_mouseovers, :unique => false + index :has_scrolls, :unique => false + index :ip_address, :unique => false + index :kind, :unique => false + index :new_visit, :unique => false + index :referrer, :unique => false + index :session_id, :unique => false + index :site, :unique => false + index :spider, :unique => false + index :visit_kind, :unique => false + # Callbacks ====================================================================================== before_create :init - + # Constants ====================================================================================== KINDS = ['direct', 'natural', 'paid', 'search'] HUMAN_USER_AGENTS = ['Chrome', 'Firefox', 'Gecko', 'Mozilla', 'MSIE', 'Opera','Safari'] # Scopes ========================================================================================= - scope :by_ip_address, lambda { |ip| { :conditions => { :ip_address => ip } } } - scope :of_kind, lambda { |k| { :conditions => { :kind => k } } } - scope :for_site, lambda { |s| { :conditions => { :site => s } } } - scope :for_month, lambda { |d| { :conditions => { :created_at => { '$gte' => d.beginning_of_month, '$lte' => d.end_of_month } } } } - scope :for_week, lambda { |d| { :conditions => { :created_at => { '$gte' => d.beginning_of_week, '$lte' => d.end_of_week } } } } - scope :for_date_range, lambda { |start_date,end_date| { :conditions => { :created_at => { '$gte' => start_date.beginning_of_month, '$lte' => end_date.end_of_month } } } } - scope :bounces, :conditions => {:bounce => true} - scope :direct_visits, :conditions => { :kind => 'direct' }, :order => 'created_at' - scope :new_visits, :conditions => { :new_visit => true }, :order => 'created_at' - scope :organic_visits, :conditions => { :kind => 'natural' }, :order => 'created_at' - scope :ppc_visits, :conditions => { :kind => 'paid' }, :order => 'created_at' - scope :spider_visits, :conditions => { :spider => true }, :order => 'created_at' - scope :recent_visits, :conditions => { :created_at => { '$gte' => Time.zone.now.beginning_of_month }}, :order => 'created_at DESC', :limit => 25 - scope :return_visits, :conditions => { :new_visit => false }, :order => 'created_at' - scope :search_visits, :conditions => { :kind => 'search' }, :order => 'created_at' + scope :by_ip_address, lambda { |ip| { :where => { :ip_address => ip } } } + scope :of_kind, lambda { |k| { :where => { :kind => k } } } + scope :for_site, lambda { |s| { :where => { :site => s } } } + scope :for_month, lambda { |d| { :where => { :created_at => { '$gte' => d.beginning_of_month, '$lte' => d.end_of_month } } } } + scope :for_week, lambda { |d| { :where => { :created_at => { '$gte' => d.beginning_of_week, '$lte' => d.end_of_week } } } } + scope :for_date_range, lambda { |start_date,end_date| { :where => { :created_at => { '$gte' => start_date.beginning_of_month, '$lte' => end_date.end_of_month } } } } + scope :bounces, :where => {:bounce => true} + scope :direct_visits, :where => { :kind => 'direct' }, :order => 'created_at' + scope :new_visits, :where => { :new_visit => true }, :order => 'created_at' + scope :organic_visits, :where => { :kind => 'natural' }, :order => 'created_at' + scope :ppc_visits, :where => { :kind => 'paid' }, :order => 'created_at' + scope :spider_visits, :where => { :spider => true }, :order => 'created_at' + scope :recent_visits, :where => { :created_at => { '$gte' => Time.zone.now.beginning_of_month }}, :order => 'created_at DESC', :limit => 25 + scope :return_visits, :where => { :new_visit => false }, :order => 'created_at' + scope :search_visits, :where => { :kind => 'search' }, :order => 'created_at' scope :with_any_actions - scope :with_clicks, :conditions => { :has_clicks => true }, :order => 'created_at' - scope :with_clickthroughs, :conditions => { :has_clickthroughs => true }, :order => 'created_at' - scope :with_conversions, :conditions => { :has_conversions => true }, :order => 'created_at' - scope :with_leads, :conditions => { :has_conversions => true }, :order => 'created_at' - scope :with_mouseovers, :conditions => { :has_mouseovers => true }, :order => 'created_at' - scope :with_scrolls, :conditions => { :has_scrolls => true }, :order => 'created_at' - scope :with_views, :conditions => { :views_count => { '$gte' => 1 } }, :order => 'created_at' + scope :with_clicks, :where => { :has_clicks => true }, :order => 'created_at' + scope :with_clickthroughs, :where => { :has_clickthroughs => true } + scope :with_conversions, :where => { :has_conversions => true }, :order => 'created_at' + scope :with_leads, :where => { :has_conversions => true }, :order => 'created_at' + scope :with_mouseovers, :where => { :has_mouseovers => true }, :order => 'created_at' + scope :with_scrolls, :where => { :has_scrolls => true }, :order => 'created_at' + scope :with_views, :where => { :views_count => { '$gte' => 1 } }, :order => 'created_at' # Class Methods ================================================================================== + # Returns the conversion rate for sessions matching the specified arguments, ie: percentage of the total number of visits that were conversions. + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.conversion_rate( :site => 'foo.com' ) def self.conversion_rate(args) (TrackableSession.search(args).with_conversions.count.to_f / TrackableSession.search(args).count) * 100 end - + + # Returns a histogram for the number of clickthroughs to each referred site(s). + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.clickthroughs_histogram( :site => 'foo.com' ) def self.clickthroughs_histogram(args) - conditions = TrackableSession.search(args).to_hash - TrackableSession.collection.group("function(x) { return { destination: x.clickthrough_destination }; }", conditions, { :count => 0}, "function(x,y){y.count++}", true).inject({}){|h,k| h[k['destination']] = k['count'] unless k['destination'].blank?; h} + conditions = TrackableSession.search(args).selector + TrackableSession.collection.group(:keyf => "function(x) { return { destination: x.clickthrough_destination }; }", :cond => conditions, :initial => { :count => 0}, :reduce => "function(x,y){y.count++}").inject({}){|h,k| h[k['destination']] = k['count'] unless k['destination'].blank?; h} end + # Returns a histogram for the first page users visited for the specified site(s). + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.entrance_pages_histogram( :site => 'foo.com' ) def self.entrance_pages_histogram(args) - conditions = TrackableSession.search(args).to_hash - TrackableSession.collection.group("function(x) { return { entrance_page: x.entrance_page }; }", conditions, { :count => 0}, "function(x,y){y.count++}", true).inject({}){|h,k| h[k['entrance_page']] = k['count']; h}.sort{|a,b| a[1] <=> b[1]}.reverse + conditions = TrackableSession.search(args).selector + TrackableSession.collection.group(:keyf => "function(x) { return { entrance_page: x.entrance_page }; }", :cond => conditions, :initial => { :count => 0}, :reduce => "function(x,y){y.count++}").inject({}){|h,k| h[k['entrance_page']] = k['count']; h}.sort{|a,b| a[1] <=> b[1]}.reverse end + # Returns a histogram for the last page users visited for the specified site(s). + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.exit_pages_histogram( :site => 'foo.com' ) def self.exit_pages_histogram(args) - conditions = TrackableSession.search(args).to_hash - TrackableSession.collection.group("function(x) { return { exit_page: x.exit_page }; }", conditions, { :count => 0}, "function(x,y){y.count++}", true).inject({}){|h,k| h[k['exit_page']] = k['count']; h}.sort{|a,b| a[1] <=> b[1]}.reverse + conditions = TrackableSession.search(args).selector + TrackableSession.collection.group(:keyf => "function(x) { return { exit_page: x.exit_page }; }", :cond => conditions, :initial => { :count => 0}, :reduce => "function(x,y){y.count++}").inject({}){|h,k| h[k['exit_page']] = k['count']; h}.sort{|a,b| a[1] <=> b[1]}.reverse end + # Returns a histogram for the search terms users used to find the specified site(s). + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.keywords_histogram( :site => 'foo.com' ) def self.keywords_histogram(args) - conditions = TrackableSession.search(args).to_hash - TrackableSession.collection.group("function(x) { return { keyword: x.referring_keywords }; }", conditions, { :count => 0}, "function(x,y){y.count++}", true).inject({}){|h,k| h[k['keyword']] = k['count'] unless k['keyword'].blank?; h} + conditions = TrackableSession.search(args).selector + TrackableSession.collection.group(:keyf => "function(x) { return { keyword: x.referring_keywords }; }", :cond => conditions, :initial => { :count => 0}, :reduce => "function(x,y){y.count++}").inject({}){|h,k| h[k['keyword']] = k['count'] unless k['keyword'].blank?; h} end - + def self.kinds_for_select [['All', 'all']] | TrackableSession::KINDS.sort.map{|k| [k.titleize, k]} end - + + # Returns a histogram for the geocoded locations of visitors to the specified site(s). + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.locations_histogram( :site => 'foo.com' ) def self.locations_histogram(args) - conditions = TrackableSession.search(args).to_hash - TrackableSession.collection.group("function(x) { return { location: x.location }; }", conditions, { :count => 0}, "function(x,y){y.count++}", true).inject({}){|h,k| h[k['location']] = k['count'].to_i unless k['location'].blank? || k['location'] == 'Unknown'; h} + conditions = TrackableSession.search(args).selector + TrackableSession.collection.group(:keyf => "function(x) { return { location: x.location }; }", :cond => conditions, :initial => { :count => 0}, :reduce => "function(x,y){y.count++}").inject({}){|h,k| h[k['location']] = k['count'].to_i unless k['location'].blank? || k['location'] == 'Unknown'; h} end - + + # Returns a human-readable user agent for the browser. def self.parsed_user_agent(user_agent) begin _ua = Agent.new(user_agent) _user_agent = "#{_ua.name} #{_ua.version} (#{_ua.os})" rescue _user_agent = "Unknown" end _user_agent end - + + # Returns a histogram for the referrers for site(s) matching the specified arguments. + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.referrers_histogram( :site => 'foo.com' ) def self.referrers_histogram(args) - conditions = TrackableSession.search(args).to_hash - TrackableSession.collection.group("function(x) { return { referrer: x.referrer }; }", conditions, { :count => 0}, "function(x,y){y.count++}", true).inject({}){|h,k| h[k['referrer']] = k['count'] unless k['referrer'].blank?; h} + conditions = TrackableSession.search(args).selector + TrackableSession.collection.group(:keyf => "function(x) { return { referrer: x.referrer }; }", :cond => conditions, :initial => { :count => 0}, :reduce => "function(x,y){y.count++}").inject({}){|h,k| h[k['referrer']] = k['count'] unless k['referrer'].blank?; h} end - - def self.search(args = {}) - args[:site] ||= 'all sites' - args[:visit_kind] ||= 'all' - args[:action_kind] ||= 'any_action' - args[:action_kind] = args[:action_kind].pluralize - [:site, :action_kind, :visit_kind, :time_period].each{|a| args[a] = args[a].downcase if args[a]} - case args[:time_period] - when 'past 3 months' - args[:start_date] = (Time.zone.now - 2.months).beginning_of_month - args[:end_date] = Time.zone.now - when 'past 6 months' - args[:start_date] = (Time.zone.now - 5.months).beginning_of_month - args[:end_date] = Time.zone.now - when 'past 12 months' - args[:start_date] = (Time.zone.now - 11.months).beginning_of_month - args[:end_date] = Time.zone.now - else - args[:start_date] = TrackableSession.first.created_at - args[:end_date] = Time.zone.now - end - if args[:time_period] - if args[:visit_kind] == 'all' - if args[:site] == 'all sites' - TrackableSession.send("with_#{args[:action_kind]}").for_date_range(args[:start_date], args[:end_date]) - else - TrackableSession.for_site(args[:site]).send("with_#{args[:action_kind]}").for_date_range(args[:start_date], args[:end_date]) - end - else - if args[:site] == 'all sites' - TrackableSession.of_kind(args[:visit_kind]).send("with_#{args[:action_kind]}").for_date_range(args[:start_date], args[:end_date]) - else - TrackableSession.for_site(args[:site]).of_kind(args[:visit_kind]).send("with_#{args[:action_kind]}").for_date_range(args[:start_date], args[:end_date]) - end - end - else - if args[:visit_kind] == 'all' - if args[:site] == 'all sites' - TrackableSession.send("with_#{args[:action_kind]}") - else - TrackableSession.for_site(args[:site]).send("with_#{args[:action_kind]}") - end - else - if args[:site] == 'all sites' - TrackableSession.of_kind(args[:visit_kind]).send("with_#{args[:action_kind]}") - else - TrackableSession.for_site(args[:site]).of_kind(args[:visit_kind]).send("with_#{args[:action_kind]}") - end - end - end + + # Returns a scope based on time period, site, and visit kind. Null arguments returns all. + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.search( :site => 'foo.com' ) + def self.search(args) + (args[:start_date], args[:end_date]) = dates_from_time_period(args[:time_period]) + sessions = args[:time_period] ? TrackableSession.for_date_range(args[:start_date], args[:end_date]) : TrackableSession.all + sessions = sessions.send("with_#{args[:action_kind].pluralize.downcase}") if args[:action_kind] + sessions = sessions.for_site(args[:site].downcase) unless args[:site].downcase == 'all sites' + sessions = sessions.of_kind(args[:visit_kind].downcase) if args[:visit_kind] && args[:visit_kind].downcase != 'all' + sessions.desc(:created_at) end - - # Can't combine date conditions, so this is needed for SessionReport + + # Returns a scope based on site and visit kind only. + # + # ==== Attributes + # + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.search_without_date( :site => 'foo.com' ) def self.search_without_date(args = {}) - args[:site] ||= 'all sites' - args[:visit_kind] ||= 'all' - args[:action_kind] ||= 'any_action' - args[:action_kind] = args[:action_kind].pluralize - args[:time_period] ||= 'past 3 months' - [:site, :action_kind, :visit_kind].each{|a| args[a] = args[a].downcase} - if args[:visit_kind] == 'all' - if args[:site] == 'all sites' - TrackableSession.send("with_#{args[:action_kind]}") - else - TrackableSession.for_site(args[:site]).send("with_#{args[:action_kind]}") - end - else - if args[:site] == 'all sites' - TrackableSession.of_kind(args[:visit_kind]).send("with_#{args[:action_kind]}") - else - TrackableSession.for_site(args[:site]).of_kind(args[:visit_kind]).send("with_#{args[:action_kind]}") - end - end + args = args.clone + args.delete(:time_period) + self.search(args) end + # Returns a histogram for the user agents for site(s) matching the specified arguments. + # + # ==== Attributes + # + # * +:time_period+ - date range as a string: 'past 3 months', 'past 6 months', 'past 12 months' + # * +:site+ - name of a site + # * +:visit_kind+ - kind of visit as a string: 'direct', 'natural', 'paid', 'search' + # + # ==== Examples + # + # TrackableSession.user_agents_histogram( :site => 'foo.com' ) def self.user_agents_histogram(args) - conditions = TrackableSession.search(args).to_hash - _histogram = TrackableSession.collection.group("function(x) { return { user_agent: x.user_agent }; }", conditions, { :count => 0}, "function(x,y){y.count++}", true) + conditions = TrackableSession.search(args).selector + _histogram = TrackableSession.collection.group(:keyf => "function(x) { return { user_agent: x.user_agent }; }", :cond => conditions, :initial => { :count => 0}, :reduce => "function(x,y){y.count++}") _final = {} _histogram.each do |ua| _ua = parsed_user_agent(ua['user_agent']) _final[_ua] ||= 0 _final[_ua] += ua['count'].to_i unless ua['user_agent'].blank? || ua['user_agent'] == 'Unknown' end _final end - + # Instance Methods =============================================================================== + # Returns the number of non-view actions for this session. def actions self.trackable_actions.count - self.trackable_actions.views.count end - + + # Returns true if this is a new visit. def detect_new_visit - TrackableSession.find_by_ip_address(self.ip_address) ? false : true + TrackableSession.where(:ip_address => self.ip_address) ? false : true end - + + # Returns this session's duration in X minutes or Y seconds. def hr_duration return 0 unless self.duration self.duration > 60 ? sprintf("%.1f minutes", self.duration / 60.0) : sprintf("%.1f seconds", self.duration) end - + + # Initializes a new session. def init self.bounce = true self.kind ||= self.kind_by_referrer self.new_visit ||= self.detect_new_visit self.referring_keywords = self.sanitize_referring_keywords self.spider ||= spider_visit? begin + raise ArgumentError, "No IP address available" unless self.ip_address _location = Geokit::Geocoders::MultiGeocoder.geocode(self.ip_address) self.location ||= _location.success? ? "#{_location.city}, #{_location.state}" : "Unknown" rescue self.location = "Unknown" end end - + + # Returns whether this session was initiated by a direct (bookmark or typed URL), search, paid (landing page), or natural (non-search link) referrer. def kind_by_referrer return "direct" unless self.referrer unless self.referrer.blank? return 'search' if ['google','bing','yahoo'].include?(self.referrer.split('.')[-2]) return 'paid' if ppc_visit?(self.initial_request_url) end "natural" end - + + # Returns the number of page views associated with this session. def pageviews self.trackable_actions.views.count end + # Returns this session's human-readable user agent. def parsed_user_agent TrackableSession.parsed_user_agent(self.user_agent) end - + + # Returns the date of the last visit if this user visited before. def last_visit_date return nil if previous_visits_count.zero? - TrackableSession.by_ip_address(self.ip_address).fields(:created_at).map{|s| s.created_at.to_s(:concise)}.sort[-2] + TrackableSession.by_ip_address(self.ip_address).asc(:created_at).only(:created_at).map{|s| s.created_at}.sort[-2] end - + + # Returns the number of times this user has been here before. def previous_visits_count TrackableSession.by_ip_address(self.ip_address).count - 1 end - + + # Unescapes referring keywords for display. def sanitize_referring_keywords self.referring_keywords.to_s.gsub('+',' ') end - - # Update the record field based on continued session activity + + # Updates this session with whatever the user just did. + # + # ==== Attributes + # + # * +:action_kind+ - action as a string: 'click', 'clickthrough', 'conversion', 'mouseover', 'scroll', 'view' + # * +:destination+ - clickthrough destination + # * +:last_url+ - the referring URL + # + # ==== Examples + # + # trackable_session.touch( 'click', 'cnn.com', 'foo.com/cnn' ) def touch(action_kind = nil, destination = nil, last_url = nil) if action_kind && action_kind == 'scroll' self.update_attributes( :has_scrolls => true, :bounce => self.trackable_actions.count <= 1, - :updated_at => Time.zone.now, :duration => Time.zone.now - self.created_at ) elsif action_kind && action_kind == 'click' self.update_attributes( :has_clicks => true, :bounce => self.trackable_actions.count <= 1, - :updated_at => Time.zone.now, :duration => Time.zone.now - self.created_at ) elsif action_kind && action_kind == 'clickthrough' self.update_attributes( :has_clickthroughs => true, :clickthrough_destination => destination, :bounce => false, - :updated_at => Time.zone.now, :duration => Time.zone.now - self.created_at ) elsif action_kind && action_kind == 'conversion' self.update_attributes( :has_conversions => true, :bounce => self.trackable_actions.count <= 1, - :updated_at => Time.zone.now, :duration => Time.zone.now - self.created_at ) elsif action_kind && action_kind == 'mouseover' self.update_attributes( :has_mouseovers => true, :bounce => self.trackable_actions.count <= 1, - :updated_at => Time.zone.now, :duration => Time.zone.now - self.created_at ) else # View self.update_attributes(:updated_at => Time.zone.now, :duration => Time.zone.now - self.created_at, :views_count => self.views_count.to_i + 1, :exit_page => last_url, :bounce => self.trackable_actions.count > 1 ? false : true) end touch_stat end - + + # Returns whether this session is new or existing. def visit_type self.new_visit? ? "New" : "Returning" end + # Upserts stats associated with this session. Called every time this session is touched. def touch_stat # Upsert associated stat if trackable_stat = TrackableStat.by_site(self.site).by_date(self.created_at).first trackable_stat.touch(self, self.trackable_actions[-1], self.trackable_actions[-2]) else trackable_stat = TrackableStat.create(:site => self.site, :created_at => self.created_at) trackable_stat.touch(self, self.trackable_actions.last) end end - + private - + def ppc_visit?(url) begin _params = URI.parse(url).query.to_s.downcase rescue false @@ -337,16 +421,16 @@ return true if _params.include?('matchtype') # Generic return true if _params.include?('ppc') # Generic return true if _params.include?('cpc') # Generic return false end - + def spider_visit? _spider = true return false if self.user_agent == "Unknown" || self.user_agent.nil? unless self.user_agent.to_s.include?('bot') HUMAN_USER_AGENTS.each{ |ua| _spider = false if self.user_agent.to_s.include?(ua) } end _spider end - + end