ahoy_matey 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 901b2af03cc91c3ad7ccef91dedfd1514e452357
4
- data.tar.gz: 83494b26ea230cf54836b3d67eb6efc88cbac45f
3
+ metadata.gz: aae43abe84c855bce95234160c4e8e0a2496155c
4
+ data.tar.gz: 037987022eaaf1738e0187b86683823a632639a2
5
5
  SHA512:
6
- metadata.gz: 1772c4ed5abe7395b6cf651f48ef05ec7454b3e30c80d9e54989407e8dd510fdba40f2ff827b5041dbe93fc22160eba8dc612fe780657bce4ba55bb5da6f50ce
7
- data.tar.gz: a33c3b9ea6cb8e4ae7104085b392c7d0bd49ed1121eaef0eace1c9157f11098843236f66792c0138286e2e11c3ee41bb5d2ce97676428f1ef28f3b812e9cc269
6
+ metadata.gz: 7f2eae369753dc8710a6ba8c8989b2641923b741feaff09184a5d94a76432ea568b6eeea53f0351dac79a7fe4f95bc4392f264560e6a0e693b92a974b2676d20
7
+ data.tar.gz: 4e1ff064b585b73a1de6225f5b606855f7aa13a620f187b02578775f2bb0c49f3bb1c87c8e1e88a2bf3dde71da0e92fb19ca2ee0dd5c1bd36e929602197a6524
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.3.0
2
+
3
+ - Added `current_visit_token` and `current_visitor_token` method
4
+ - Switched to UUIDs
5
+ - Quiet endpoint requests
6
+ - Skip server-side bot events
7
+ - Added `request` argument to `exclude_method`
8
+
1
9
  ## 0.2.2
2
10
 
3
11
  - Added `exclude_method` option
data/README.md CHANGED
@@ -175,6 +175,8 @@ or track all views and clicks with:
175
175
  ahoy.trackAll();
176
176
  ```
177
177
 
178
+ See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features.
179
+
178
180
  #### Ruby
179
181
 
180
182
  ```ruby
@@ -254,6 +256,12 @@ Turn off logging
254
256
  ahoy.debug(false);
255
257
  ```
256
258
 
259
+ Debug endpoint requests in Ruby [master]
260
+
261
+ ```ruby
262
+ Ahoy.quiet = false
263
+ ```
264
+
257
265
  ### More
258
266
 
259
267
  - Excludes bots
@@ -370,8 +378,8 @@ Ahoy.subscribers << Ahoy::Subscribers::ActiveRecord.new(model: Event)
370
378
  Exclude visits and events
371
379
 
372
380
  ```ruby
373
- Ahoy.exclude_method = proc do |controller|
374
- controller.request.ip == "192.168.1.1"
381
+ Ahoy.exclude_method = proc do |controller, request|
382
+ request.ip == "192.168.1.1"
375
383
  end
376
384
  ```
377
385
 
@@ -383,6 +391,12 @@ Ahoy.track_bots = true
383
391
 
384
392
  ## Upgrading
385
393
 
394
+ ### 0.3.0
395
+
396
+ Starting with `0.3.0`, visit and visitor tokens are now UUIDs.
397
+
398
+ ### 0.1.6
399
+
386
400
  In `0.1.6`, a big improvement was made to `browser` and `os`. Update existing visits with:
387
401
 
388
402
  ```ruby
@@ -2,20 +2,5 @@ module Ahoy
2
2
  class BaseController < ApplicationController
3
3
  # skip all filters
4
4
  skip_filter *_process_action_callbacks.map(&:filter)
5
-
6
- before_filter :halt_bots
7
-
8
- protected
9
-
10
- def browser
11
- @browser ||= Browser.new(ua: request.user_agent)
12
- end
13
-
14
- def halt_bots
15
- if !Ahoy.track_bots and browser.bot?
16
- render json: {}
17
- end
18
- end
19
-
20
5
  end
21
6
  end
@@ -2,8 +2,8 @@ module Ahoy
2
2
  class VisitsController < BaseController
3
3
 
4
4
  def create
5
- visit_token = params[:visit_token] || generate_token
6
- visitor_token = params[:visitor_token] || generate_token
5
+ visit_token = params[:visit_token] || Ahoy.generate_id
6
+ visitor_token = params[:visitor_token] || Ahoy.generate_id
7
7
 
8
8
  visit =
9
9
  Ahoy.visit_model.new do |v|
@@ -23,11 +23,5 @@ module Ahoy
23
23
  render json: {visit_token: visit.visit_token, visitor_token: visit.visitor_token}
24
24
  end
25
25
 
26
- protected
27
-
28
- def generate_token
29
- SecureRandom.urlsafe_base64(32).gsub(/[\-_]/, "").first(32)
30
- end
31
-
32
26
  end
33
27
  end
@@ -4,20 +4,33 @@ module Ahoy
4
4
  def self.included(base)
5
5
  base.helper_method :current_visit
6
6
  base.helper_method :ahoy
7
+ base.before_filter :set_ahoy_visitor_cookie
7
8
  base.before_filter do
8
9
  RequestStore.store[:ahoy_controller] ||= self
9
10
  end
10
11
  end
11
12
 
13
+ def ahoy
14
+ @ahoy ||= Ahoy::Tracker.new(controller: self)
15
+ end
16
+
12
17
  def current_visit
13
- visit_token = cookies[:ahoy_visit] || request.headers["Ahoy-Visit"]
18
+ visit_token = current_visit_token
14
19
  if visit_token
15
20
  @current_visit ||= Ahoy.visit_model.where(visit_token: visit_token).first
16
21
  end
17
22
  end
18
23
 
19
- def ahoy
20
- @ahoy ||= Ahoy::Tracker.new(controller: self)
24
+ def current_visit_token
25
+ @current_visit_token ||= request.headers["Ahoy-Visit"] || cookies[:ahoy_visit]
26
+ end
27
+
28
+ def current_visitor_token
29
+ @current_visitor_token ||= request.headers["Ahoy-Visitor"] || cookies[:ahoy_visitor] || current_visit.try(:visitor_token) || Ahoy.generate_id
30
+ end
31
+
32
+ def set_ahoy_visitor_cookie
33
+ cookies[:ahoy_visitor] = current_visitor_token if !request.headers["Ahoy-Visitor"] && !cookies[:ahoy_visitor]
21
34
  end
22
35
 
23
36
  end
data/lib/ahoy/engine.rb CHANGED
@@ -1,4 +1,28 @@
1
1
  module Ahoy
2
2
  class Engine < ::Rails::Engine
3
+ # from https://github.com/evrone/quiet_assets/blob/master/lib/quiet_assets.rb
4
+ initializer "ahoy", after: "sprockets.environment" do |app|
5
+ next unless Ahoy.quiet
6
+
7
+ # Parse PATH_INFO by assets prefix
8
+ AHOY_PREFIX = "/ahoy/"
9
+ KEY = "ahoy.old_level"
10
+
11
+ # Just create an alias for call in middleware
12
+ Rails::Rack::Logger.class_eval do
13
+ def call_with_quiet_ahoy(env)
14
+ begin
15
+ if env["PATH_INFO"].start_with?(AHOY_PREFIX)
16
+ env[KEY] = Rails.logger.level
17
+ Rails.logger.level = Logger::ERROR
18
+ end
19
+ call_without_quiet_ahoy(env)
20
+ ensure
21
+ Rails.logger.level = env[KEY] if env[KEY]
22
+ end
23
+ end
24
+ alias_method_chain :call, :quiet_ahoy
25
+ end
26
+ end
3
27
  end
4
28
  end
data/lib/ahoy/tracker.rb CHANGED
@@ -3,10 +3,11 @@ module Ahoy
3
3
 
4
4
  def initialize(options = {})
5
5
  @controller = options[:controller]
6
+ @request = options[:request] || @controller.try(:request)
6
7
  end
7
8
 
8
9
  def track(name, properties = {}, options = {})
9
- if !(@controller and Ahoy.exclude_method and Ahoy.exclude_method.call(@controller))
10
+ if (Ahoy.track_bots or !bot?) and !exclude?
10
11
  # publish to each subscriber
11
12
  options = options.dup
12
13
  if @controller
@@ -15,8 +16,15 @@ module Ahoy
15
16
  if @controller.respond_to?(:current_visit)
16
17
  options[:visit] ||= @controller.current_visit
17
18
  end
19
+ if @controller.respond_to?(:current_visit_token)
20
+ options[:visit_token] = @controller.current_visit_token
21
+ end
22
+ if @controller.respond_to?(:current_visitor_token)
23
+ options[:visitor_token] = @controller.current_visitor_token
24
+ end
18
25
  end
19
26
  options[:time] ||= Time.zone.now
27
+ options[:id] ||= Ahoy.generate_id
20
28
 
21
29
  subscribers = Ahoy.subscribers
22
30
  if subscribers.any?
@@ -31,5 +39,23 @@ module Ahoy
31
39
  true
32
40
  end
33
41
 
42
+ protected
43
+
44
+ def bot?
45
+ @bot ||= Browser.new(ua: @request.user_agent).bot?
46
+ end
47
+
48
+ def exclude?
49
+ if Ahoy.exclude_method
50
+ if Ahoy.exclude_method.arity == 1
51
+ Ahoy.exclude_method.call(@controller)
52
+ else
53
+ Ahoy.exclude_method.call(@controller, @request)
54
+ end
55
+ else
56
+ false
57
+ end
58
+ end
59
+
34
60
  end
35
61
  end
data/lib/ahoy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ahoy
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/ahoy/warden.rb CHANGED
@@ -9,6 +9,6 @@ Warden::Manager.after_set_user except: :fetch do |user, auth, opts|
9
9
  visit.save!
10
10
  end
11
11
  end
12
- ahoy = Ahoy::Tracker.new
12
+ ahoy = Ahoy::Tracker.new(request: request)
13
13
  ahoy.track "$authenticate", {}, user: user, visit: visit
14
14
  end
data/lib/ahoy.rb ADDED
@@ -0,0 +1,66 @@
1
+ require "addressable/uri"
2
+ require "browser"
3
+ require "geocoder"
4
+ require "referer-parser"
5
+ require "user_agent_parser"
6
+ require "request_store"
7
+ require "ahoy/version"
8
+ require "ahoy/tracker"
9
+ require "ahoy/controller"
10
+ require "ahoy/model"
11
+ require "ahoy/subscribers/active_record"
12
+ require "ahoy/engine"
13
+ require "ahoy/warden" if defined?(Warden)
14
+
15
+ module Ahoy
16
+
17
+ def self.generate_id
18
+ SecureRandom.uuid
19
+ end
20
+
21
+ def self.visit_model
22
+ @visit_model || ::Visit
23
+ end
24
+
25
+ def self.visit_model=(visit_model)
26
+ @visit_model = visit_model
27
+ end
28
+
29
+ # TODO private
30
+ # performance hack for referer-parser
31
+ def self.referrer_parser
32
+ @referrer_parser ||= RefererParser::Referer.new("https://github.com/ankane/ahoy")
33
+ end
34
+
35
+ # performance
36
+ def self.user_agent_parser
37
+ @user_agent_parser ||= UserAgentParser::Parser.new
38
+ end
39
+
40
+ def self.fetch_user(controller)
41
+ if user_method.respond_to?(:call)
42
+ user_method.call(controller)
43
+ else
44
+ controller.send(user_method)
45
+ end
46
+ end
47
+
48
+ mattr_accessor :user_method
49
+ self.user_method = proc do |controller|
50
+ (controller.respond_to?(:current_user) && controller.current_user) || (controller.respond_to?(:current_resource_owner, true) && controller.send(:current_resource_owner)) || nil
51
+ end
52
+
53
+ mattr_accessor :exclude_method
54
+
55
+ mattr_accessor :subscribers
56
+ self.subscribers = []
57
+
58
+ mattr_accessor :track_bots
59
+ self.track_bots = false
60
+
61
+ mattr_accessor :quiet
62
+ self.quiet = true
63
+ end
64
+
65
+ ActionController::Base.send :include, Ahoy::Controller
66
+ ActiveRecord::Base.send(:extend, Ahoy::Model) if defined?(ActiveRecord)
data/lib/ahoy_matey.rb CHANGED
@@ -1,59 +1 @@
1
- require "addressable/uri"
2
- require "browser"
3
- require "geocoder"
4
- require "referer-parser"
5
- require "user_agent_parser"
6
- require "request_store"
7
- require "ahoy/version"
8
- require "ahoy/tracker"
9
- require "ahoy/controller"
10
- require "ahoy/model"
11
- require "ahoy/subscribers/active_record"
12
- require "ahoy/engine"
13
- require "ahoy/warden" if defined?(Warden)
14
-
15
- module Ahoy
16
-
17
- def self.visit_model
18
- @visit_model || ::Visit
19
- end
20
-
21
- def self.visit_model=(visit_model)
22
- @visit_model = visit_model
23
- end
24
-
25
- # TODO private
26
- # performance hack for referer-parser
27
- def self.referrer_parser
28
- @referrer_parser ||= RefererParser::Referer.new("https://github.com/ankane/ahoy")
29
- end
30
-
31
- # performance
32
- def self.user_agent_parser
33
- @user_agent_parser ||= UserAgentParser::Parser.new
34
- end
35
-
36
- def self.fetch_user(controller)
37
- if user_method.respond_to?(:call)
38
- user_method.call(controller)
39
- else
40
- controller.send(user_method)
41
- end
42
- end
43
-
44
- mattr_accessor :user_method
45
- self.user_method = proc do |controller|
46
- (controller.respond_to?(:current_user) && controller.current_user) || (controller.respond_to?(:current_resource_owner, true) && controller.send(:current_resource_owner)) || nil
47
- end
48
-
49
- mattr_accessor :exclude_method
50
-
51
- mattr_accessor :subscribers
52
- self.subscribers = []
53
-
54
- mattr_accessor :track_bots
55
- self.track_bots = false
56
- end
57
-
58
- ActionController::Base.send :include, Ahoy::Controller
59
- ActiveRecord::Base.send(:extend, Ahoy::Model) if defined?(ActiveRecord)
1
+ require "ahoy"
@@ -1,3 +1,11 @@
1
+ /*
2
+ * Ahoy.js
3
+ * Simple, powerful JavaScript analytics
4
+ * https://github.com/ankane/ahoy.js
5
+ * v0.1.0
6
+ * MIT License
7
+ */
8
+
1
9
  /*jslint browser: true, indent: 2, plusplus: true, vars: true */
2
10
 
3
11
  (function (window) {
@@ -5,13 +13,14 @@
5
13
 
6
14
  var ahoy = window.ahoy || window.Ahoy || {};
7
15
  var $ = window.jQuery || window.Zepto || window.$;
8
- var visitToken, visitorToken;
16
+ var visitId, visitorId;
9
17
  var visitTtl = 4 * 60; // 4 hours
10
18
  var visitorTtl = 2 * 365 * 24 * 60; // 2 years
11
19
  var isReady = false;
12
20
  var queue = [];
13
21
  var canStringify = typeof(JSON) !== "undefined" && typeof(JSON.stringify) !== "undefined";
14
22
  var eventQueue = [];
23
+ var page = ahoy.page || window.location.pathname;
15
24
 
16
25
  // cookies
17
26
 
@@ -72,18 +81,12 @@
72
81
  }
73
82
  }
74
83
 
75
- // https://github.com/klughammer/node-randomstring
84
+ // http://stackoverflow.com/a/2117523/1177228
76
85
  function generateId() {
77
- var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz';
78
- var length = 32;
79
- var string = '';
80
-
81
- for (var i = 0; i < length; i++) {
82
- var randomNumber = Math.floor(Math.random() * chars.length);
83
- string += chars.substring(randomNumber, randomNumber + 1);
84
- }
85
-
86
- return string;
86
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
87
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
88
+ return v.toString(16);
89
+ });
87
90
  }
88
91
 
89
92
  function saveEventQueue() {
@@ -123,35 +126,37 @@
123
126
  return {
124
127
  tag: $target.get(0).tagName.toLowerCase(),
125
128
  id: $target.attr("id"),
126
- "class": $target.attr("class")
129
+ "class": $target.attr("class"),
130
+ page: page,
131
+ section: $target.closest("*[data-section]").data("section")
127
132
  };
128
133
  }
129
134
 
130
135
  // main
131
136
 
132
- visitToken = getCookie("ahoy_visit");
133
- visitorToken = getCookie("ahoy_visitor");
137
+ visitId = getCookie("ahoy_visit");
138
+ visitorId = getCookie("ahoy_visitor");
134
139
 
135
- if (visitToken && visitorToken) {
140
+ if (visitId && visitorId) {
136
141
  // TODO keep visit alive?
137
142
  log("Active visit");
138
143
  setReady();
139
144
  } else {
140
- visitToken = generateId();
141
- setCookie("ahoy_visit", visitToken, visitTtl);
145
+ visitId = generateId();
146
+ setCookie("ahoy_visit", visitId, visitTtl);
142
147
 
143
148
  // make sure cookies are enabled
144
149
  if (getCookie("ahoy_visit")) {
145
150
  log("Visit started");
146
151
 
147
- if (!visitorToken) {
148
- visitorToken = generateId();
149
- setCookie("ahoy_visitor", visitorToken, visitorTtl);
152
+ if (!visitorId) {
153
+ visitorId = generateId();
154
+ setCookie("ahoy_visitor", visitorId, visitorTtl);
150
155
  }
151
156
 
152
157
  var data = {
153
- visit_token: visitToken,
154
- visitor_token: visitorToken,
158
+ visit_token: visitId,
159
+ visitor_token: visitorId,
155
160
  platform: ahoy.platform || "Web",
156
161
  landing_page: window.location.href,
157
162
  screen_width: window.screen.width,
@@ -172,6 +177,14 @@
172
177
  }
173
178
  }
174
179
 
180
+ ahoy.getVisitToken = function () {
181
+ return visitId;
182
+ };
183
+
184
+ ahoy.getVisitorToken = function () {
185
+ return visitorId;
186
+ };
187
+
175
188
  ahoy.reset = function () {
176
189
  destroyCookie("ahoy_visit");
177
190
  destroyCookie("ahoy_visitor");
@@ -209,7 +222,8 @@
209
222
  ahoy.trackView = function () {
210
223
  var properties = {
211
224
  url: window.location.href,
212
- title: document.title
225
+ title: document.title,
226
+ page: page
213
227
  };
214
228
  ahoy.track("$view", properties);
215
229
  };
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_matey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-27 00:00:00.000000000 Z
11
+ date: 2014-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -141,6 +141,7 @@ files:
141
141
  - app/controllers/ahoy/visits_controller.rb
142
142
  - app/models/ahoy/event.rb
143
143
  - config/routes.rb
144
+ - lib/ahoy.rb
144
145
  - lib/ahoy/controller.rb
145
146
  - lib/ahoy/engine.rb
146
147
  - lib/ahoy/model.rb