redis_analytics 0.7.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/app/views/layouts/redis_analytics/application.html.erb +3 -3
  4. data/coverage/index.html +423 -381
  5. data/lib/redis_analytics/configuration.rb +73 -73
  6. data/lib/redis_analytics/engine.rb +7 -0
  7. data/lib/redis_analytics/filter.rb +22 -22
  8. data/lib/redis_analytics/helpers.rb +58 -58
  9. data/lib/redis_analytics/metrics.rb +73 -73
  10. data/lib/redis_analytics/version.rb +3 -3
  11. data/lib/redis_analytics/visit.rb +96 -96
  12. data/test/dummy/config/environments/production.rb +1 -1
  13. data/test/dummy/config/routes.rb +1 -1
  14. data/test/dummy/log/development.log +1185 -0
  15. data/test/dummy/log/production.log +5172 -0
  16. data/test/dummy/public/assets/application-c900658d554ff9f314a2e1b97cd68997.js.gz +0 -0
  17. data/test/dummy/public/assets/manifest-567012ae8b6f03148f7121062750991f.json +1 -0
  18. data/test/dummy/public/assets/redis_analytics/redis_analytics-82322234eccfd3d7c55a2034ee41ab2a.js +10785 -0
  19. data/test/dummy/public/assets/redis_analytics/redis_analytics-82322234eccfd3d7c55a2034ee41ab2a.js.gz +0 -0
  20. data/test/dummy/public/assets/redis_analytics/redis_analytics-f13abe0904b7483ea8c8c08029e97be3.css +64 -0
  21. data/test/dummy/public/assets/redis_analytics/redis_analytics-f13abe0904b7483ea8c8c08029e97be3.css.gz +0 -0
  22. data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  23. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  24. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  25. data/test/dummy/tmp/cache/assets/development/sprockets/3b2603753f496fe7b73a04ce200ea6c0 +0 -0
  26. data/test/dummy/tmp/cache/assets/development/sprockets/4b838eac074ecce8b8ae19c261677ab6 +0 -0
  27. data/test/dummy/tmp/cache/assets/development/sprockets/63afa0e9c559fa85d5c63b6f37728141 +0 -0
  28. data/test/dummy/tmp/cache/assets/development/sprockets/6d0077b1948c42a8892f40120649d217 +0 -0
  29. data/test/dummy/tmp/cache/assets/development/sprockets/a317f594a79c3dd49a6f88b49aabc1b5 +0 -0
  30. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  31. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  32. data/test/dummy/tmp/cache/assets/development/sprockets/f069f087fa68223029e7fb8547e5bc3b +0 -0
  33. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  34. data/test/dummy/tmp/cache/assets/production/sprockets/006eb7cc017cf18c3ea32cab97f0cc3c +0 -0
  35. data/test/dummy/tmp/cache/assets/production/sprockets/192691b9e0bedebfde12633bb3629d0b +0 -0
  36. data/test/dummy/tmp/cache/assets/production/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  37. data/test/dummy/tmp/cache/assets/production/sprockets/3b2603753f496fe7b73a04ce200ea6c0 +0 -0
  38. data/test/dummy/tmp/cache/assets/production/sprockets/4b838eac074ecce8b8ae19c261677ab6 +0 -0
  39. data/test/dummy/tmp/cache/assets/production/sprockets/5cf60638cb580f41112a5a83eb3b72ef +0 -0
  40. data/test/dummy/tmp/cache/assets/production/sprockets/63afa0e9c559fa85d5c63b6f37728141 +0 -0
  41. data/test/dummy/tmp/cache/assets/production/sprockets/6c2f18f7338d56feecce32780357521c +0 -0
  42. data/test/dummy/tmp/cache/assets/production/sprockets/6d0077b1948c42a8892f40120649d217 +0 -0
  43. data/test/dummy/tmp/cache/assets/production/sprockets/7751914469530dae0646d92467e9d72e +0 -0
  44. data/test/dummy/tmp/cache/assets/production/sprockets/8d62150b658b3a8b6fed7e8951f52392 +0 -0
  45. data/test/dummy/tmp/cache/assets/production/sprockets/8ea331810c31cbe1ba34b91a02f769e7 +0 -0
  46. data/test/dummy/tmp/cache/assets/production/sprockets/953bc37b1ee0915247dba29773960202 +0 -0
  47. data/test/dummy/tmp/cache/assets/production/sprockets/9b54afa4ef026f4c288feeec49f2f526 +0 -0
  48. data/test/dummy/tmp/cache/assets/production/sprockets/a29d0dc527ff5ce1252ccf6370514620 +0 -0
  49. data/test/dummy/tmp/cache/assets/production/sprockets/a317f594a79c3dd49a6f88b49aabc1b5 +0 -0
  50. data/test/dummy/tmp/cache/assets/production/sprockets/b01583a39abd5ce0a3d2b2967c6f75bd +0 -0
  51. data/test/dummy/tmp/cache/assets/production/sprockets/cfdf466647e83eb93e0d6630e4b51a25 +0 -0
  52. data/test/dummy/tmp/cache/assets/production/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  53. data/test/dummy/tmp/cache/assets/production/sprockets/d7491740e7757fe2ec57fd6d25461e5c +0 -0
  54. data/test/dummy/tmp/cache/assets/production/sprockets/df16db3bfcc56fafc73b853b7999be1f +0 -0
  55. data/test/dummy/tmp/cache/assets/production/sprockets/e7bd439b274a2155050b47e5a64ea72d +0 -0
  56. data/test/dummy/tmp/cache/assets/production/sprockets/f069f087fa68223029e7fb8547e5bc3b +0 -0
  57. data/test/dummy/tmp/cache/assets/production/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  58. data/test/dummy/tmp/cache/assets/production/sprockets/f9a412f49281cc7e6512f0787f7ba05f +0 -0
  59. data/vendor/assets/javascripts/redis_analytics/{engine.js → redis_analytics.js} +6 -1
  60. data/vendor/assets/stylesheets/redis_analytics/{engine.css → redis_analytics.css} +3 -1
  61. metadata +43 -8
  62. data/app/views/redis_analytics/application/_footer.html.erb~ +0 -3
  63. data/app/views/redis_analytics/visits/_unique_visits_line.html.erb~ +0 -26
  64. data/app/views/redis_analytics/visits/index.html.erb~ +0 -71
  65. data/test/dummy/public/assets/manifest-5bcba723c313582b1d428fc3bf592b29.json +0 -1
@@ -1,101 +1,101 @@
1
- module RedisAnalytics
2
- module Configuration
3
- # Redis connection instance
4
- attr_accessor :redis_connection
1
+ module RedisAnalytics
2
+ module Configuration
3
+ # Redis connection instance
4
+ attr_accessor :redis_connection
5
5
 
6
- # Redis namespace for keys
7
- attr_writer :redis_namespace
6
+ # Redis namespace for keys
7
+ attr_writer :redis_namespace
8
8
 
9
- # Name of the cookie which tracks first visitors
10
- attr_writer :first_visit_cookie_name
9
+ # Name of the cookie which tracks first visitors
10
+ attr_writer :first_visit_cookie_name
11
11
 
12
- # Name of the cookie which tracks current visits
13
- attr_writer :current_visit_cookie_name
12
+ # Name of the cookie which tracks current visits
13
+ attr_writer :current_visit_cookie_name
14
14
 
15
- # Minutes the visit should timeout after (if no hit is received)
16
- attr_writer :visit_timeout
15
+ # Minutes the visit should timeout after (if no hit is received)
16
+ attr_writer :visit_timeout
17
17
 
18
- # Endpoint for dashboard
19
- attr_writer :dashboard_endpoint
18
+ # Endpoint for dashboard
19
+ attr_writer :dashboard_endpoint
20
20
 
21
- # Endpoint for api
22
- attr_writer :api_endpoint
21
+ # Endpoint for api
22
+ attr_writer :api_endpoint
23
23
 
24
- attr_writer :path_filters
24
+ attr_writer :path_filters
25
25
 
26
- attr_writer :filters
26
+ attr_writer :filters
27
27
 
28
- # Path to the Geo IP Database file
29
- attr_writer :geo_ip_data_path
28
+ # Path to the Geo IP Database file
29
+ attr_writer :geo_ip_data_path
30
30
 
31
- # Redis namespace for keys
32
- def redis_namespace
33
- @redis_namespace ||= 'ra'
34
- end
35
-
36
- # Minutes the visit should timeout after (if no hit is received)
37
- def visit_timeout
38
- @visit_timeout ||= 30 # minutes
39
- end
31
+ # Redis namespace for keys
32
+ def redis_namespace
33
+ @redis_namespace ||= 'ra'
34
+ end
40
35
 
41
- # Name of the cookie which tracks first visitors (unknown visitors)
42
- def first_visit_cookie_name
43
- @first_visit_cookie_name ||= '_rucn'
44
- end
36
+ # Minutes the visit should timeout after (if no hit is received)
37
+ def visit_timeout
38
+ @visit_timeout ||= 30 # minutes
39
+ end
45
40
 
46
- # Name of the cookie which tracks visits
47
- def current_visit_cookie_name
48
- @current_visit_cookie_name ||= '_vcn'
49
- end
41
+ # Name of the cookie which tracks first visitors (unknown visitors)
42
+ def first_visit_cookie_name
43
+ @first_visit_cookie_name ||= '_rucn'
44
+ end
50
45
 
51
- def filters
52
- @filters ||= []
53
- end
46
+ # Name of the cookie which tracks visits
47
+ def current_visit_cookie_name
48
+ @current_visit_cookie_name ||= '_vcn'
49
+ end
54
50
 
55
- def path_filters
56
- @path_filters ||= []
57
- end
51
+ def filters
52
+ @filters ||= []
53
+ end
58
54
 
59
- def add_filter(&proc)
60
- filters << RedisAnalytics::Filter.new(proc)
61
- end
55
+ def path_filters
56
+ @path_filters ||= []
57
+ end
62
58
 
63
- def add_path_filter(path)
64
- path_filters << RedisAnalytics::PathFilter.new(path)
65
- end
59
+ def add_filter(&proc)
60
+ filters << RedisAnalytics::Filter.new(proc)
61
+ end
66
62
 
67
- def geo_ip_data_path
68
- @geo_ip_data_path = ::File.expand_path(::File.join(::File.dirname(__FILE__),'..','..')) + "/bin/GeoIP.dat"
69
- end
63
+ def add_path_filter(path)
64
+ path_filters << RedisAnalytics::PathFilter.new(path)
65
+ end
70
66
 
71
- def visitor_recency_slices
72
- @visitor_recency_slices ||= [1, 7, 30]
73
- end
67
+ def geo_ip_data_path
68
+ @geo_ip_data_path = ::File.expand_path(::File.join(::File.dirname(__FILE__),'..','..')) + "/bin/GeoIP.dat"
69
+ end
74
70
 
75
- def default_range
76
- @default_range = :day
77
- end
71
+ def visitor_recency_slices
72
+ @visitor_recency_slices ||= [1, 7, 30]
73
+ end
78
74
 
79
- def redis_key_timestamps # [format, expire in seconds or nil]
80
- ['%Y', '%Y_%m', '%Y_%m_%d', '%Y_%m_%d_%H', '%Y_%m_%d_%H_%M']
81
- end
75
+ def default_range
76
+ @default_range = :day
77
+ end
82
78
 
83
- def time_range_formats
84
- [[:year, :month, "%b"], [:week, :day, "%a"], [:day, :hour, "%l%P"]]
85
- end
79
+ def redis_key_timestamps # [format, expire in seconds or nil]
80
+ ['%Y', '%Y_%m', '%Y_%m_%d', '%Y_%m_%d_%H', '%Y_%m_%d_%H_%M']
81
+ end
86
82
 
87
- def configure
88
- yield self
89
- end
83
+ def time_range_formats
84
+ [[:year, :month, "%b"], [:week, :day, "%a"], [:day, :hour, "%l%P"]]
85
+ end
90
86
 
91
- def api_endpoint
92
- @api_endpoint || dashboard_endpoint + '/api'
93
- end
87
+ def configure
88
+ yield self
89
+ end
94
90
 
95
- def dashboard_endpoint
96
- @dashboard_endpoint || '/redis_analytics'
97
- end
91
+ def api_endpoint
92
+ @api_endpoint || dashboard_endpoint + '/api'
93
+ end
98
94
 
95
+ def dashboard_endpoint
96
+ @dashboard_endpoint || '/redis_analytics'
99
97
  end
98
+
100
99
  end
100
+ end
101
101
 
@@ -13,6 +13,13 @@ module RedisAnalytics
13
13
  initializer "redis_analytics.view_helpers" do |app|
14
14
  ActionController::Base.send :include, RedisAnalytics::Helpers
15
15
  end
16
+
17
+ initializer "redis_analytics.precompile.hook", group: :all do |app|
18
+ app.config.assets.precompile += %w[
19
+ redis_analytics/redis_analytics.js
20
+ redis_analytics/redis_analytics.css
21
+ ]
22
+ end
16
23
  end
17
24
  end
18
25
  end
@@ -1,32 +1,32 @@
1
- module RedisAnalytics
2
- class Filter
3
- attr_reader :filter_proc
1
+ module RedisAnalytics
2
+ class Filter
3
+ attr_reader :filter_proc
4
4
 
5
- def initialize(filter_proc)
6
- @filter_proc = filter_proc
7
- end
8
-
9
- def matches?(request, response)
10
- filter_proc.call(request, response)
11
- end
5
+ def initialize(filter_proc)
6
+ @filter_proc = filter_proc
7
+ end
12
8
 
9
+ def matches?(request, response)
10
+ filter_proc.call(request, response)
13
11
  end
14
12
 
15
- class PathFilter
16
- attr_reader :filter_path
13
+ end
14
+
15
+ class PathFilter
16
+ attr_reader :filter_path
17
17
 
18
- def initialize(filter_path)
19
- @filter_path = filter_path
20
- end
18
+ def initialize(filter_path)
19
+ @filter_path = filter_path
20
+ end
21
21
 
22
- def matches?(request_path)
23
- if filter_path.is_a?(String)
24
- request_path == filter_path
25
- elsif filter_path.is_a?(Regexp)
26
- request_path =~ filter_path
27
- end
22
+ def matches?(request_path)
23
+ if filter_path.is_a?(String)
24
+ request_path == filter_path
25
+ elsif filter_path.is_a?(Regexp)
26
+ request_path =~ filter_path
28
27
  end
29
28
  end
30
-
31
29
  end
32
30
 
31
+ end
32
+
@@ -1,74 +1,74 @@
1
- module RedisAnalytics
2
- module Helpers
1
+ module RedisAnalytics
2
+ module Helpers
3
3
 
4
- FORMAT_SPECIFIER = [['%Y', 365], ['%m', 30], ['%d', 24], ['%H', 60], ['%M', 60]]
4
+ FORMAT_SPECIFIER = [['%Y', 365], ['%m', 30], ['%d', 24], ['%H', 60], ['%M', 60]]
5
5
 
6
- GRANULARITY = ['yearly', 'monthly', 'dayly', 'hourly', 'minutely']
6
+ GRANULARITY = ['yearly', 'monthly', 'dayly', 'hourly', 'minutely']
7
7
 
8
- private
9
- def method_missing(meth, *args, &block)
10
- if meth.to_s =~ /^(minute|hour|dai|day|month|year)ly_([a-z_0-9]+)$/
11
- granularity = ($1 == 'dai' ? 'day' : $1) + 'ly'
12
- metric_name = $2
13
- data(granularity, metric_name, *args)
14
- else
15
- super
16
- end
8
+ private
9
+ def method_missing(meth, *args, &block)
10
+ if meth.to_s =~ /^(minute|hour|dai|day|month|year)ly_([a-z_0-9]+)$/
11
+ granularity = ($1 == 'dai' ? 'day' : $1) + 'ly'
12
+ metric_name = $2
13
+ data(granularity, metric_name, *args)
14
+ else
15
+ super
17
16
  end
17
+ end
18
18
 
19
- def metric_type(metric_name)
20
- RedisAnalytics.redis_connection.hget("#{RedisAnalytics.redis_namespace}:#METRICS", metric_name)
21
- end
19
+ def metric_type(metric_name)
20
+ RedisAnalytics.redis_connection.hget("#{RedisAnalytics.redis_namespace}:#METRICS", metric_name)
21
+ end
22
22
 
23
- def data(granularity, metric_name, from_date, options = {})
24
- aggregate = options[:aggregate] || false
25
- x = granularity[0..-3]
23
+ def data(granularity, metric_name, from_date, options = {})
24
+ aggregate = options[:aggregate] || false
25
+ x = granularity[0..-3]
26
26
 
27
- to_date = (options[:to_date] || Time.now).send("end_of_#{x}")
28
- i = from_date.send("beginning_of_#{x}")
27
+ to_date = (options[:to_date] || Time.now).send("end_of_#{x}")
28
+ i = from_date.send("beginning_of_#{x}")
29
29
 
30
- union = []
31
- time = []
32
- begin
33
- slice_key = i.strftime(FORMAT_SPECIFIER[0..GRANULARITY.index(granularity)].map{|x| x[0]}.join('_'))
34
- union << "#{RedisAnalytics.redis_namespace}:#{metric_name}:#{slice_key}"
35
- time << slice_key.split('_')
36
- i += 1.send(x)
37
- end while i <= to_date
38
- seq = get_next_seq
39
- if metric_type(metric_name) == 'String'
40
- if aggregate
41
- union_key = "#{RedisAnalytics.redis_namespace}:#{seq}"
42
- RedisAnalytics.redis_connection.zunionstore(union_key, union)
43
- RedisAnalytics.redis_connection.expire(union_key, 100)
44
- return Hash[RedisAnalytics.redis_connection.zrange(union_key, 0, -1, :with_scores => true)]
45
- else
46
- return time.zip(union.map{|x| Hash[RedisAnalytics.redis_connection.zrange(x, 0, -1, :with_scores => true)]})
47
- end
48
- elsif metric_type(metric_name) == 'Fixnum'
49
- if aggregate
50
- return RedisAnalytics.redis_connection.mget(*union).map(&:to_i).inject(:+)
51
- else
52
- return time.zip(RedisAnalytics.redis_connection.mget(*union).map(&:to_i))
53
- end
30
+ union = []
31
+ time = []
32
+ begin
33
+ slice_key = i.strftime(FORMAT_SPECIFIER[0..GRANULARITY.index(granularity)].map{|x| x[0]}.join('_'))
34
+ union << "#{RedisAnalytics.redis_namespace}:#{metric_name}:#{slice_key}"
35
+ time << slice_key.split('_')
36
+ i += 1.send(x)
37
+ end while i <= to_date
38
+ seq = get_next_seq
39
+ if metric_type(metric_name) == 'String'
40
+ if aggregate
41
+ union_key = "#{RedisAnalytics.redis_namespace}:#{seq}"
42
+ RedisAnalytics.redis_connection.zunionstore(union_key, union)
43
+ RedisAnalytics.redis_connection.expire(union_key, 100)
44
+ return Hash[RedisAnalytics.redis_connection.zrange(union_key, 0, -1, :with_scores => true)]
45
+ else
46
+ return time.zip(union.map{|x| Hash[RedisAnalytics.redis_connection.zrange(x, 0, -1, :with_scores => true)]})
47
+ end
48
+ elsif metric_type(metric_name) == 'Fixnum'
49
+ if aggregate
50
+ return RedisAnalytics.redis_connection.mget(*union).map(&:to_i).inject(:+)
54
51
  else
55
- if Metrics.public_instance_methods.any?{|m| m.to_s =~ /^#{metric_name}_ratio_per_(hit|visit)$/}
56
- aggregate ? {} : time.zip([{}] * time.length)
57
- elsif Metrics.public_instance_methods.any?{|m| m.to_s =~ /^#{metric_name}_count_per_(hit|visit)$/}
58
- aggregate ? 0 : time.zip([0] * time.length)
59
- else
60
- aggregate ? 0 : time.zip([0] * time.length)
61
- end
52
+ return time.zip(RedisAnalytics.redis_connection.mget(*union).map(&:to_i))
53
+ end
54
+ else
55
+ if Metrics.public_instance_methods.any?{|m| m.to_s =~ /^#{metric_name}_ratio_per_(hit|visit)$/}
56
+ aggregate ? {} : time.zip([{}] * time.length)
57
+ elsif Metrics.public_instance_methods.any?{|m| m.to_s =~ /^#{metric_name}_count_per_(hit|visit)$/}
58
+ aggregate ? 0 : time.zip([0] * time.length)
59
+ else
60
+ aggregate ? 0 : time.zip([0] * time.length)
62
61
  end
63
62
  end
63
+ end
64
64
 
65
- def get_next_seq
66
- seq = RedisAnalytics.redis_connection.incr("#{RedisAnalytics.redis_namespace}:#SEQUENCER")
67
- end
65
+ def get_next_seq
66
+ seq = RedisAnalytics.redis_connection.incr("#{RedisAnalytics.redis_namespace}:#SEQUENCER")
67
+ end
68
68
 
69
- def time_range
70
- (request.cookies["_rarng"] || RedisAnalytics.default_range).to_sym
71
- end
69
+ def time_range
70
+ (request.cookies["_rarng"] || RedisAnalytics.default_range).to_sym
72
71
  end
73
72
  end
73
+ end
74
74
 
@@ -1,95 +1,95 @@
1
- module RedisAnalytics
2
- module Metrics
1
+ module RedisAnalytics
2
+ module Metrics
3
3
 
4
- attr_reader :visit_time_count_per_visit
5
- attr_reader :visits_count_per_visit, :first_visits_count_per_visit, :repeat_visits_count_per_visit
6
- attr_reader :unique_visits_ratio_per_visit
7
- attr_reader :page_views_count_per_hit, :second_page_views_count_per_hit
4
+ attr_reader :visit_time_count_per_visit
5
+ attr_reader :visits_count_per_visit, :first_visits_count_per_visit, :repeat_visits_count_per_visit
6
+ attr_reader :unique_visits_ratio_per_visit
7
+ attr_reader :page_views_count_per_hit, :second_page_views_count_per_hit
8
8
 
9
- # Developers can override or define new public methods here
10
- # Methods should start with track and end with count or types
11
- # Return types should be Fixnum or String resp.
12
- # If you return nil or an error nothing will be tracked
9
+ # Developers can override or define new public methods here
10
+ # Methods should start with track and end with count or types
11
+ # Return types should be Fixnum or String resp.
12
+ # If you return nil or an error nothing will be tracked
13
13
 
14
- def browser_ratio_per_visit
15
- user_agent.name.to_s
16
- end
14
+ def browser_ratio_per_visit
15
+ user_agent.name.to_s
16
+ end
17
17
 
18
- def platform_ratio_per_visit
19
- user_agent.platform.to_s
20
- end
18
+ def platform_ratio_per_visit
19
+ user_agent.platform.to_s
20
+ end
21
21
 
22
- def country_ratio_per_visit
23
- if defined?(GeoIP)
24
- begin
25
- g = GeoIP.new(RedisAnalytics.geo_ip_data_path)
26
- geo_country_code = g.country(@rack_request.ip).to_hash[:country_code2]
27
- if geo_country_code and geo_country_code =~ /^[A-Z]{2}$/
28
- return geo_country_code
29
- end
30
- rescue Exception => e
31
- warn "Unable to fetch country info #{e}"
22
+ def country_ratio_per_visit
23
+ if defined?(GeoIP)
24
+ begin
25
+ g = GeoIP.new(RedisAnalytics.geo_ip_data_path)
26
+ geo_country_code = g.country(@rack_request.ip).to_hash[:country_code2]
27
+ if geo_country_code and geo_country_code =~ /^[A-Z]{2}$/
28
+ return geo_country_code
32
29
  end
30
+ rescue Exception => e
31
+ warn "Unable to fetch country info #{e}"
33
32
  end
34
33
  end
34
+ end
35
35
 
36
- def recency_ratio_per_visit
37
- # tracking for visitor recency
38
- if @last_visit_time # from first_visit_cookie
39
- days_since_last_visit = ((@t.to_i - @last_visit_time.to_i)/(24*3600)).round
40
- if days_since_last_visit <= 1
41
- return 'd'
42
- elsif days_since_last_visit <= 7
43
- return 'w'
44
- elsif days_since_last_visit <= 30
45
- return 'm'
46
- else
47
- return 'o'
48
- end
36
+ def recency_ratio_per_visit
37
+ # tracking for visitor recency
38
+ if @last_visit_time # from first_visit_cookie
39
+ days_since_last_visit = ((@t.to_i - @last_visit_time.to_i)/(24*3600)).round
40
+ if days_since_last_visit <= 1
41
+ return 'd'
42
+ elsif days_since_last_visit <= 7
43
+ return 'w'
44
+ elsif days_since_last_visit <= 30
45
+ return 'm'
46
+ else
47
+ return 'o'
49
48
  end
50
49
  end
50
+ end
51
51
 
52
- def device_ratio_per_visit
53
- return ((user_agent.mobile? or user_agent.tablet?) ? 'mobile' : 'desktop')
54
- end
52
+ def device_ratio_per_visit
53
+ return ((user_agent.mobile? or user_agent.tablet?) ? 'mobile' : 'desktop')
54
+ end
55
55
 
56
- def referrer_ratio_per_visit
57
- if @rack_request.referrer
58
- ['google', 'bing', 'yahoo', 'cleartrip', 'github'].each do |referrer|
59
- # this will track x.google.mysite.com as google so its buggy, fix the regex
60
- if m = @rack_request.referrer.match(/^(https?:\/\/)?([a-zA-Z0-9\.\-]+\.)?(#{referrer})\.([a-zA-Z\.]+)(:[0-9]+)?(\/.*)?$/)
61
- "REFERRER => #{m.to_a[3]}"
62
- referrer = m.to_a[3]
63
- else
64
- referrer = 'other'
65
- end
56
+ def referrer_ratio_per_visit
57
+ if @rack_request.referrer
58
+ ['google', 'bing', 'yahoo', 'cleartrip', 'github'].each do |referrer|
59
+ # this will track x.google.mysite.com as google so its buggy, fix the regex
60
+ if m = @rack_request.referrer.match(/^(https?:\/\/)?([a-zA-Z0-9\.\-]+\.)?(#{referrer})\.([a-zA-Z\.]+)(:[0-9]+)?(\/.*)?$/)
61
+ "REFERRER => #{m.to_a[3]}"
62
+ referrer = m.to_a[3]
63
+ else
64
+ referrer = 'other'
66
65
  end
67
- else
68
- referrer = 'organic'
69
66
  end
70
- return referrer
71
- end
72
-
73
- # track the ratio of URL's visits
74
- def url_ratio_per_hit
75
- return @rack_request.path
76
- end
77
-
78
- # track the landing pages ratio
79
- def landing_page_ratio_per_hit
80
- return @rack_request.path if @page_view_seq_no.to_i == 0
67
+ else
68
+ referrer = 'organic'
81
69
  end
70
+ return referrer
71
+ end
82
72
 
83
- # track the landing pages ratio
84
- def http_response_ratio_per_hit
85
- return @rack_response.status.to_s
86
- end
73
+ # track the ratio of URL's visits
74
+ def url_ratio_per_hit
75
+ return @rack_request.path
76
+ end
77
+
78
+ # track the landing pages ratio
79
+ def landing_page_ratio_per_hit
80
+ return @rack_request.path if @page_view_seq_no.to_i == 0
81
+ end
87
82
 
88
- private
89
- def user_agent
90
- Browser.new(:ua => @rack_request.user_agent, :accept_language => 'en-us')
91
- end
83
+ # track the landing pages ratio
84
+ def http_response_ratio_per_hit
85
+ return @rack_response.status.to_s
86
+ end
92
87
 
88
+ private
89
+ def user_agent
90
+ Browser.new(:ua => @rack_request.user_agent, :accept_language => 'en-us')
93
91
  end
92
+
94
93
  end
94
+ end
95
95