Renamed extractors to deckhands
Andrew Kane
committed Jun 17, 2014
commit 62ed6df01f6ae95d0da263b0ac5d229cc705ade5
Showing 20
changed files with
256 additions
and 237 deletions
README.md
+2
-2
| @@ | @@ -168,9 +168,9 @@ end |
| ### Track Additional Values | |
| ```ruby | |
| - | def track_visit |
| + | def track_visit(options) |
| super do |visit| | |
| - | visit.gclid = ahoy.extractor.landing_params["gclid"] |
| + | visit.gclid = visit_properties.landing_params["gclid"] |
| end | |
| end | |
| ``` | |
ahoy.rb b/lib/ahoy.rb
+6
-5
| @@ | @@ -10,11 +10,12 @@ require "ahoy/version" |
| require "ahoy/tracker" | |
| require "ahoy/controller" | |
| require "ahoy/model" | |
| - | require "ahoy/extractor" |
| - | require "ahoy/extractors/traffic_source_extractor" |
| - | require "ahoy/extractors/utm_parameter_extractor" |
| - | require "ahoy/extractors/technology_extractor" |
| - | require "ahoy/extractors/location_extractor" |
| + | require "ahoy/visit_properties" |
| + | require "ahoy/deckhands/location_deckhand" |
| + | require "ahoy/deckhands/request_deckhand" |
| + | require "ahoy/deckhands/technology_deckhand" |
| + | require "ahoy/deckhands/traffic_source_deckhand" |
| + | require "ahoy/deckhands/utm_parameter_deckhand" |
| require "ahoy/stores/base_store" | |
| require "ahoy/stores/active_record_legacy_store" | |
| require "ahoy/stores/active_record_store" | |
ahoy/deckhands/location_deckhand.rb b/lib/ahoy/deckhands/location_deckhand.rb
+39
-0
| @@ | @@ -0,0 +1,39 @@ |
| + | module Ahoy |
| + | module Deckhands |
| + | class LocationDeckhand |
| + | |
| + | def initialize(ip) |
| + | @ip = ip |
| + | end |
| + | |
| + | def country |
| + | location.try(:country).presence |
| + | end |
| + | |
| + | def region |
| + | location.try(:state).presence |
| + | end |
| + | |
| + | def city |
| + | location.try(:city).presence |
| + | end |
| + | |
| + | protected |
| + | |
| + | def location |
| + | if !@checked |
| + | @location = |
| + | begin |
| + | Geocoder.search(@ip).first |
| + | rescue => e |
| + | $stderr.puts e.message |
| + | nil |
| + | end |
| + | @checked = true |
| + | end |
| + | @location |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
ahoy/deckhands/request_deckhand.rb b/lib/ahoy/deckhands/request_deckhand.rb
+41
-0
| @@ | @@ -0,0 +1,41 @@ |
| + | module Ahoy |
| + | module Deckhands |
| + | class RequestDeckhand |
| + | attr_reader :request |
| + | |
| + | def initialize(request, options = {}) |
| + | @request = request |
| + | @options = options |
| + | end |
| + | |
| + | def ip |
| + | request.remote_ip |
| + | end |
| + | |
| + | def user_agent |
| + | request.user_agent |
| + | end |
| + | |
| + | def referrer |
| + | @options[:api] ? request.params["referrer"] : request.referer |
| + | end |
| + | |
| + | def landing_page |
| + | @options[:api] ? request.params["landing_page"] : request.original_url |
| + | end |
| + | |
| + | def platform |
| + | request.params["platform"] |
| + | end |
| + | |
| + | def app_version |
| + | request.params["app_version"] |
| + | end |
| + | |
| + | def os_version |
| + | request.params["os_version"] |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
ahoy/deckhands/technology_deckhand.rb b/lib/ahoy/deckhands/technology_deckhand.rb
+49
-0
| @@ | @@ -0,0 +1,49 @@ |
| + | module Ahoy |
| + | module Deckhands |
| + | class TechnologyDeckhand |
| + | |
| + | def initialize(user_agent) |
| + | @user_agent = user_agent |
| + | end |
| + | |
| + | def browser |
| + | agent.name |
| + | end |
| + | |
| + | def os |
| + | agent.os.name |
| + | end |
| + | |
| + | def device_type |
| + | @device_type ||= begin |
| + | browser = Browser.new(ua: @user_agent) |
| + | if browser.bot? |
| + | "Bot" |
| + | elsif browser.tv? |
| + | "TV" |
| + | elsif browser.console? |
| + | "Console" |
| + | elsif browser.tablet? |
| + | "Tablet" |
| + | elsif browser.mobile? |
| + | "Mobile" |
| + | else |
| + | "Desktop" |
| + | end |
| + | end |
| + | end |
| + | |
| + | protected |
| + | |
| + | def agent |
| + | @agent ||= self.class.user_agent_parser.parse(@user_agent) |
| + | end |
| + | |
| + | # performance |
| + | def self.user_agent_parser |
| + | @user_agent_parser ||= UserAgentParser::Parser.new |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
ahoy/deckhands/traffic_source_deckhand.rb b/lib/ahoy/deckhands/traffic_source_deckhand.rb
+24
-0
| @@ | @@ -0,0 +1,24 @@ |
| + | module Ahoy |
| + | module Deckhands |
| + | class TrafficSourceDeckhand |
| + | |
| + | def initialize(referrer) |
| + | @referrer = referrer |
| + | end |
| + | |
| + | def referring_domain |
| + | @referring_domain ||= Addressable::URI.parse(@referrer).host.first(255) rescue nil |
| + | end |
| + | |
| + | def search_keyword |
| + | @search_keyword ||= (self.class.referrer_parser.parse(@referrer)[1].first(255) rescue nil).presence |
| + | end |
| + | |
| + | # performance hack for referer-parser |
| + | def self.referrer_parser |
| + | @referrer_parser ||= RefererParser::Referer.new("https://github.com/ankane/ahoy") |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
ahoy/deckhands/utm_parameter_deckhand.rb b/lib/ahoy/deckhands/utm_parameter_deckhand.rb
+24
-0
| @@ | @@ -0,0 +1,24 @@ |
| + | module Ahoy |
| + | module Deckhands |
| + | class UtmParameterDeckhand |
| + | |
| + | def initialize(landing_page) |
| + | @landing_page = landing_page |
| + | end |
| + | |
| + | def landing_params |
| + | @landing_params ||= begin |
| + | landing_uri = Addressable::URI.parse(@landing_page) rescue nil |
| + | (landing_uri && landing_uri.query_values) || {} |
| + | end |
| + | end |
| + | |
| + | %w[utm_source utm_medium utm_term utm_content utm_campaign].each do |name| |
| + | define_method name do |
| + | landing_params[name] |
| + | end |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
ahoy/extractor.rb b/lib/ahoy/extractor.rb
+0
-82
| @@ | @@ -1,82 +0,0 @@ |
| - | module Ahoy |
| - | class Extractor |
| - | attr_reader :request |
| - | |
| - | TRAFFIC_SOURCE_KEYS = [:referring_domain, :search_keyword] |
| - | UTM_PARAMETERS_KEYS = [:utm_source, :utm_medium, :utm_term, :utm_content, :utm_campaign] |
| - | TECHNOLOGY_KEYS = [:browser, :os, :device_type] |
| - | LOCATION_KEYS = [:country, :region, :city] |
| - | |
| - | KEYS = [:ip, :user_agent, :referrer, :landing_page, :platform, :app_version, :os_version] + |
| - | TRAFFIC_SOURCE_KEYS + UTM_PARAMETERS_KEYS + TECHNOLOGY_KEYS + LOCATION_KEYS |
| - | |
| - | delegate *TRAFFIC_SOURCE_KEYS, to: :traffic_source_extractor |
| - | delegate *(UTM_PARAMETERS_KEYS + [:landing_params]), to: :utm_parameter_extractor |
| - | delegate *TECHNOLOGY_KEYS, to: :technology_extractor |
| - | delegate *LOCATION_KEYS, to: :location_extractor |
| - | |
| - | def initialize(request, options = {}) |
| - | @request = request |
| - | @options = options |
| - | end |
| - | |
| - | def [](key) |
| - | send(key) |
| - | end |
| - | |
| - | def keys |
| - | KEYS |
| - | end |
| - | |
| - | def to_hash |
| - | keys.inject({}){|memo, key| memo[key] = send(key); memo } |
| - | end |
| - | |
| - | def ip |
| - | request.remote_ip |
| - | end |
| - | |
| - | def user_agent |
| - | request.user_agent |
| - | end |
| - | |
| - | def referrer |
| - | @options[:api] ? request.params["referrer"] : request.referer |
| - | end |
| - | |
| - | def landing_page |
| - | @options[:api] ? request.params["landing_page"] : request.original_url |
| - | end |
| - | |
| - | def platform |
| - | request.params["platform"] |
| - | end |
| - | |
| - | def app_version |
| - | request.params["app_version"] |
| - | end |
| - | |
| - | def os_version |
| - | request.params["os_version"] |
| - | end |
| - | |
| - | protected |
| - | |
| - | def traffic_source_extractor |
| - | @traffic_source_extractor ||= Extractors::TrafficSourceExtractor.new(referrer) |
| - | end |
| - | |
| - | def utm_parameter_extractor |
| - | @utm_parameters_extractor ||= Extractors::UtmParameterExtractor.new(landing_page) |
| - | end |
| - | |
| - | def technology_extractor |
| - | @technology_extractor ||= Extractors::TechnologyExtractor.new(user_agent) |
| - | end |
| - | |
| - | def location_extractor |
| - | @location_extractor ||= Extractors::LocationExtractor.new(ip) |
| - | end |
| - | |
| - | end |
| - | end |
ahoy/extractors/location_extractor.rb b/lib/ahoy/extractors/location_extractor.rb
+0
-39
| @@ | @@ -1,39 +0,0 @@ |
| - | module Ahoy |
| - | module Extractors |
| - | class LocationExtractor |
| - | |
| - | def initialize(ip) |
| - | @ip = ip |
| - | end |
| - | |
| - | def country |
| - | location.try(:country).presence |
| - | end |
| - | |
| - | def region |
| - | location.try(:state).presence |
| - | end |
| - | |
| - | def city |
| - | location.try(:city).presence |
| - | end |
| - | |
| - | protected |
| - | |
| - | def location |
| - | if !@checked |
| - | @location = |
| - | begin |
| - | Geocoder.search(@ip).first |
| - | rescue => e |
| - | $stderr.puts e.message |
| - | nil |
| - | end |
| - | @checked = true |
| - | end |
| - | @location |
| - | end |
| - | |
| - | end |
| - | end |
| - | end |
ahoy/extractors/technology_extractor.rb b/lib/ahoy/extractors/technology_extractor.rb
+0
-49
| @@ | @@ -1,49 +0,0 @@ |
| - | module Ahoy |
| - | module Extractors |
| - | class TechnologyExtractor |
| - | |
| - | def initialize(user_agent) |
| - | @user_agent = user_agent |
| - | end |
| - | |
| - | def browser |
| - | agent.name |
| - | end |
| - | |
| - | def os |
| - | agent.os.name |
| - | end |
| - | |
| - | def device_type |
| - | @device_type ||= begin |
| - | browser = Browser.new(ua: @user_agent) |
| - | if browser.bot? |
| - | "Bot" |
| - | elsif browser.tv? |
| - | "TV" |
| - | elsif browser.console? |
| - | "Console" |
| - | elsif browser.tablet? |
| - | "Tablet" |
| - | elsif browser.mobile? |
| - | "Mobile" |
| - | else |
| - | "Desktop" |
| - | end |
| - | end |
| - | end |
| - | |
| - | protected |
| - | |
| - | def agent |
| - | @agent ||= self.class.user_agent_parser.parse(@user_agent) |
| - | end |
| - | |
| - | # performance |
| - | def self.user_agent_parser |
| - | @user_agent_parser ||= UserAgentParser::Parser.new |
| - | end |
| - | |
| - | end |
| - | end |
| - | end |
ahoy/extractors/traffic_source_extractor.rb b/lib/ahoy/extractors/traffic_source_extractor.rb
+0
-24
| @@ | @@ -1,24 +0,0 @@ |
| - | module Ahoy |
| - | module Extractors |
| - | class TrafficSourceExtractor |
| - | |
| - | def initialize(referrer) |
| - | @referrer = referrer |
| - | end |
| - | |
| - | def referring_domain |
| - | @referring_domain ||= Addressable::URI.parse(@referrer).host.first(255) rescue nil |
| - | end |
| - | |
| - | def search_keyword |
| - | @search_keyword ||= (self.class.referrer_parser.parse(@referrer)[1].first(255) rescue nil).presence |
| - | end |
| - | |
| - | # performance hack for referer-parser |
| - | def self.referrer_parser |
| - | @referrer_parser ||= RefererParser::Referer.new("https://github.com/ankane/ahoy") |
| - | end |
| - | |
| - | end |
| - | end |
| - | end |
ahoy/extractors/utm_parameter_extractor.rb b/lib/ahoy/extractors/utm_parameter_extractor.rb
+0
-24
| @@ | @@ -1,24 +0,0 @@ |
| - | module Ahoy |
| - | module Extractors |
| - | class UtmParameterExtractor |
| - | |
| - | def initialize(landing_page) |
| - | @landing_page = landing_page |
| - | end |
| - | |
| - | def landing_params |
| - | @landing_params ||= begin |
| - | landing_uri = Addressable::URI.parse(@landing_page) rescue nil |
| - | (landing_uri && landing_uri.query_values) || {} |
| - | end |
| - | end |
| - | |
| - | %w[utm_source utm_medium utm_term utm_content utm_campaign].each do |name| |
| - | define_method name do |
| - | landing_params[name] |
| - | end |
| - | end |
| - | |
| - | end |
| - | end |
| - | end |
ahoy/model.rb b/lib/ahoy/model.rb
+1
-1
| @@ | @@ -29,7 +29,7 @@ module Ahoy |
| def landing_params | |
| @landing_params ||= begin | |
| warn "[DEPRECATION] landing_params is deprecated" | |
| - | ActiveSupport::HashWithIndifferentAccess.new(Extractors::UtmParameterExtractor.new(landing_page).landing_params) |
| + | Deckhands::UtmParameterDeckhand.new(landing_page).landing_params |
| end | |
| end | |
ahoy/stores/active_record_legacy_store.rb b/lib/ahoy/stores/active_record_legacy_store.rb
+2
-2
| @@ | @@ -11,8 +11,8 @@ module Ahoy |
| v.created_at = options[:started_at] | |
| end | |
| - | properties.keys.each do |key| |
| - | visit.send(:"#{key}=", properties[key]) if visit.respond_to?(:"#{key}=") |
| + | visit_properties.keys.each do |key| |
| + | visit.send(:"#{key}=", visit_properties[key]) if visit.respond_to?(:"#{key}=") |
| end | |
| yield(visit) if block_given? | |
ahoy/stores/active_record_store.rb b/lib/ahoy/stores/active_record_store.rb
+2
-2
| @@ | @@ -11,8 +11,8 @@ module Ahoy |
| v.started_at = options[:started_at] | |
| end | |
| - | properties.keys.each do |key| |
| - | visit.send(:"#{key}=", properties[key]) if visit.respond_to?(:"#{key}=") |
| + | visit_properties.keys.each do |key| |
| + | visit.send(:"#{key}=", visit_properties[key]) if visit.respond_to?(:"#{key}=") |
| end | |
| yield(visit) if block_given? | |
ahoy/stores/base_store.rb b/lib/ahoy/stores/base_store.rb
+2
-2
| @@ | @@ -55,8 +55,8 @@ module Ahoy |
| @ahoy ||= @options[:ahoy] | |
| end | |
| - | def properties |
| - | ahoy.extractor |
| + | def visit_properties |
| + | ahoy.visit_properties |
| end | |
| end | |
ahoy/stores/log_store.rb b/lib/ahoy/stores/log_store.rb
+1
-1
| @@ | @@ -6,7 +6,7 @@ module Ahoy |
| data = { | |
| id: ahoy.visit_id, | |
| visitor_id: ahoy.visitor_id, | |
| - | }.merge(properties.to_hash) |
| + | }.merge(visit_properties.to_hash) |
| data[:user_id] = user.id if user | |
| data[:started_at] = options[:started_at] | |
ahoy/stores/mongoid_store.rb b/lib/ahoy/stores/mongoid_store.rb
+2
-2
| @@ | @@ -11,8 +11,8 @@ module Ahoy |
| v.started_at = options[:started_at] | |
| end | |
| - | properties.keys.each do |key| |
| - | visit.send(:"#{key}=", properties[key]) if visit.respond_to?(:"#{key}=") && properties[key] |
| + | visit_properties.keys.each do |key| |
| + | visit.send(:"#{key}=", visit_properties[key]) if visit.respond_to?(:"#{key}=") && visit_properties[key] |
| end | |
| yield(visit) if block_given? | |
ahoy/tracker.rb b/lib/ahoy/tracker.rb
+3
-2
| @@ | @@ -79,8 +79,9 @@ module Ahoy |
| @user ||= @store.user | |
| end | |
| - | def extractor |
| - | @extractor ||= Ahoy::Extractor.new(request, @options.slice(:api)) |
| + | # TODO rename method |
| + | def visit_properties |
| + | @visit_properties ||= Ahoy::VisitProperties.new(request, @options.slice(:api)) |
| end | |
| # for ActiveRecordLegacyStore only - do not use | |
ahoy/visit_properties.rb b/lib/ahoy/visit_properties.rb
+58
-0
| @@ | @@ -0,0 +1,58 @@ |
| + | module Ahoy |
| + | class VisitProperties |
| + | |
| + | REQUEST_KEYS = [:ip, :user_agent, :referrer, :landing_page, :platform, :app_version, :os_version] |
| + | TRAFFIC_SOURCE_KEYS = [:referring_domain, :search_keyword] |
| + | UTM_PARAMETER_KEYS = [:utm_source, :utm_medium, :utm_term, :utm_content, :utm_campaign] |
| + | TECHNOLOGY_KEYS = [:browser, :os, :device_type] |
| + | LOCATION_KEYS = [:country, :region, :city] |
| + | |
| + | KEYS = REQUEST_KEYS + TRAFFIC_SOURCE_KEYS + UTM_PARAMETER_KEYS + TECHNOLOGY_KEYS + LOCATION_KEYS |
| + | |
| + | delegate *REQUEST_KEYS, to: :request_deckhand |
| + | delegate *TRAFFIC_SOURCE_KEYS, to: :traffic_source_deckhand |
| + | delegate *(UTM_PARAMETER_KEYS + [:landing_params]), to: :utm_parameter_deckhand |
| + | delegate *TECHNOLOGY_KEYS, to: :technology_deckhand |
| + | delegate *LOCATION_KEYS, to: :location_deckhand |
| + | |
| + | def initialize(request, options = {}) |
| + | @request = request |
| + | @options = options |
| + | end |
| + | |
| + | def [](key) |
| + | send(key) |
| + | end |
| + | |
| + | def keys |
| + | KEYS |
| + | end |
| + | |
| + | def to_hash |
| + | keys.inject({}){|memo, key| memo[key] = send(key); memo } |
| + | end |
| + | |
| + | protected |
| + | |
| + | def request_deckhand |
| + | @request_deckhand ||= Deckhands::RequestDeckhand.new(@request, @options) |
| + | end |
| + | |
| + | def traffic_source_deckhand |
| + | @traffic_source_deckhand ||= Deckhands::TrafficSourceDeckhand.new(request_deckhand.referrer) |
| + | end |
| + | |
| + | def utm_parameter_deckhand |
| + | @utm_parameter_deckhand ||= Deckhands::UtmParameterDeckhand.new(request_deckhand.landing_page) |
| + | end |
| + | |
| + | def technology_deckhand |
| + | @technology_deckhand ||= Deckhands::TechnologyDeckhand.new(request_deckhand.user_agent) |
| + | end |
| + | |
| + | def location_deckhand |
| + | @location_deckhand ||= Deckhands::LocationDeckhand.new(request_deckhand.ip) |
| + | end |
| + | |
| + | end |
| + | end |