mixpanel 3.1.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -8,11 +8,11 @@
8
8
  - [Rack Middleware] (#rack-middleware)
9
9
  - [Usage] (#usage)
10
10
  - [Initialize Mixpanel] (#initialize-mixpanel)
11
- - [Track Events Directly](#track-events-directly)
12
- - [Pixel Based Event Tracking](#pixel-based-event-tracking)
13
- - [Import Events](#import-events)
14
- - [Set Person Attributes Directly](#set-person-attributes-directly)
15
- - [Increment Person Attributes Directly](#increment-person-attributes-directly)
11
+ - [Track Events Directly](#track-events-directly)
12
+ - [Pixel Based Event Tracking](#pixel-based-event-tracking)
13
+ - [Import Events](#import-events)
14
+ - [Set Person Attributes Directly](#set-person-attributes-directly)
15
+ - [Increment Person Attributes Directly](#increment-person-attributes-directly)
16
16
  - [Examples] (#examples)
17
17
  - [How to use it from Rails controllers] (#how-to-use-it-from-rails-controllers)
18
18
  - [How to track events using Resque and Rails] (#how-to-track-events-using-resque-and-rails)
@@ -59,7 +59,7 @@ Where **options** is a hash that accepts the following keys:
59
59
  By default the scripts are inserted into the head of the HTML response. If you'd prefer the scripts to run after
60
60
  all rendering has completed, set the insert_js_last flag to true and they'll be added at the end of the body tag.
61
61
  This will work whether or not you opt for the aynchronous version of the API. However, this will have no effect
62
- when inserting JS into an AJAX response.
62
+ when inserting JS into an AJAX response.
63
63
 
64
64
  * **persist** : boolean
65
65
 
@@ -74,8 +74,7 @@ Where **options** is a hash that accepts the following keys:
74
74
  This allows you to use a before_filter to set these variables, redirect, and still have them only transmitted
75
75
  once.
76
76
 
77
- *To enable persistence*, you must set the flag twice: here when instantiating Middleware and again when you initialize
78
- the Mixpanel class.
77
+ *To enable persistence*, you must set the flag twice: here when instantiating Middleware and again when you initialize the Mixpanel class.
79
78
 
80
79
  * **config** : hash
81
80
 
@@ -93,24 +92,24 @@ Where **options** is a hash that accepts the following keys:
93
92
  Where **options** is a hash that accepts the following keys:
94
93
 
95
94
  * **async** : boolean
96
-
95
+
97
96
  *Default: false*
98
97
 
99
98
  Built in async feature. Events are sent to a subprocess via a pipe and the sub process asynchronously send events to Mixpanel.
100
99
  This value can be overwritten on subsequent method calls. I.e., this setting represents the default for your Mixpanel object,
101
- but each call can overwrite this default setting.
102
-
103
- This process uses a single thread to upload events, and may start dropping events if your application generates
100
+ but each call can overwrite this default setting.
101
+
102
+ This process uses a single thread to upload events, and may start dropping events if your application generates
104
103
  them at a very high rate. While this is a simple way to have asynchronous interaction with Mixpanel, more robust solutions are
105
- available. Specifically, see the [Resque example](#how-to-track-events-using-resque-and-rails) below.
104
+ available. Specifically, see the [Resque example](#how-to-track-events-using-resque-and-rails) below.
106
105
 
107
106
  * **persist** : boolean
108
107
 
109
108
  *Default: false*
110
109
 
111
- This is used in connection with the [Rack Middleware section](#rack-middleware) above. If you are not going to use Middleware
112
- to send requests to Mixpanel through JavaScript, you don't need to worry about this option.
113
-
110
+ This is used in connection with the [Rack Middleware section](#rack-middleware) above. If you are not going to use Middleware
111
+ to send requests to Mixpanel through JavaScript, you don't need to worry about this option.
112
+
114
113
  If you would like, the Mixpanel gem may be configured to store its queue in a Rack session. This allows events
115
114
  to be stored through redirects, which can be helpful if you sign in and redirect but want to associate an event with that
116
115
  action. The Mixpanel gem will also remove duplicate events from your queue for information that should only be
@@ -121,39 +120,40 @@ Where **options** is a hash that accepts the following keys:
121
120
  once.
122
121
 
123
122
  *To enable persistence*, you must set the flag twice: here when instantiating Middleware and again when you initialize
124
- the Mixpanel class.
123
+ the Mixpanel class.
125
124
 
126
125
  * **api_key** : string
127
-
128
- *Default: nil*
129
-
130
- When using the [import functionality](#import-events), you must set an API key to go along with your token. If not set when the
131
- class is instantiated, you will be required to send the api key in the options hash of the import method.
132
-
126
+
127
+ *Default: nil*
128
+
129
+ When using the [import functionality](#import-events), you must set an API key to go along with your token. If not set when the
130
+ class is instantiated, you will be required to send the api key in the options hash of the import method.
131
+
133
132
  * **env** : hash
134
133
 
135
- *Default: {}*
136
-
137
- This is used by the gem to append information from your request environment to your Mixpanel request. If you are calling this
138
- directly from a controller, simply passing in `request.env` will be sufficient. However, as explained in the Resque example,
139
- your environment might choke if it tries to convert that hash to JSON (not to mention how large that hash can be). You can just pass
140
- in a subset of the full environment:
141
-
142
- ```ruby
143
- env = {
144
- 'REMOTE_ADDR' => request.env['REMOTE_ADDR'],
145
- 'HTTP_X_FORWARDED_FOR' => request.env['HTTP_X_FORWARDED_FOR'],
146
- 'rack.session' => request.env['rack.session'],
147
- 'mixpanel_events' => request.env['mixpanel_events']
148
- }
149
- @mixpanel = Mixpanel::Tracker.new MIXPANEL_TOKEN, { :env => env }
150
- ```
151
-
152
- Basically, this information is being used to: set the default IP address associated with the request, and grab any session variables
153
- needed to run the Middleware stuff.
154
-
155
- Additional information contained in your environment (e.g., http_referer) can simply be sent in as attributes where appropriate
156
- for your use case.
134
+ *Default: {}*
135
+
136
+ This is used by the gem to append information from your request environment to your Mixpanel request. If you are calling this
137
+ directly from a controller, simply passing in `request.env` will be sufficient. However, as explained in the Resque example,
138
+ your environment might choke if it tries to convert that hash to JSON (not to mention how large that hash can be). You can just pass
139
+ in a subset of the full environment:
140
+
141
+ ```ruby
142
+ env = {
143
+ 'REMOTE_ADDR' => request.env['REMOTE_ADDR'],
144
+ 'HTTP_X_FORWARDED_FOR' => request.env['HTTP_X_FORWARDED_FOR'],
145
+ 'rack.session' => request.env['rack.session'],
146
+ 'mixpanel_events' => request.env['mixpanel_events']
147
+ }
148
+
149
+ @mixpanel = Mixpanel::Tracker.new MIXPANEL_TOKEN, { :env => env }
150
+ ```
151
+
152
+ Basically, this information is being used to: set the default IP address associated with the request, and grab any session variables
153
+ needed to run the Middleware stuff.
154
+
155
+ Additional information contained in your environment (e.g., http_referer) can simply be sent in as attributes where appropriate
156
+ for your use case.
157
157
 
158
158
  ### Track Events Directly
159
159
 
@@ -171,18 +171,18 @@ it will automatically be converted to the correct form (e.g., `{ :os => 'Mac' }`
171
171
 
172
172
  * **async** : boolean
173
173
 
174
- *Default: the async value from when the class was instantiated*
175
-
174
+ *Default: the async value from when the class was instantiated*
175
+
176
176
  * **api_key**: string
177
177
 
178
- *Default: the api_key value from when the class was instantiated*
178
+ *Default: the api_key value from when the class was instantiated*
179
179
 
180
180
  * **url**: string
181
181
 
182
- *Default: `http://api.mixpanel.com/track/`*
183
-
184
- This can be used to proxy Mixpanel API requests.
185
-
182
+ *Default: `http://api.mixpanel.com/track/`*
183
+
184
+ This can be used to proxy Mixpanel API requests.
185
+
186
186
  Example:
187
187
 
188
188
  ```ruby
@@ -226,10 +226,13 @@ Example:
226
226
  ### Set Person Attributes Directly
227
227
 
228
228
  ```ruby
229
- @mixpanel.set distinct_id, properties, options
229
+ @mixpanel.set distinct_id_or_request_properties, properties, options
230
230
  ```
231
231
 
232
- **distinct_id** is whatever is used to identify the user to Mixpanel.
232
+ **distinct_id_or_request_properties** is whatever is used to identify the user to Mixpanel or a hash of
233
+ properties of the [engage event](https://mixpanel.com/docs/people-analytics/people-http-specification-insert-data) that exist
234
+ outside of the `$set`. Special properties will be automatically converted to the correct form (e.g., `{ :ip => '127.0.0.1' }` will be
235
+ converted to `{ :$ip => '127.0.0.1' }`
233
236
 
234
237
  **properties** is a hash of properties to be set. The keys in the properties can either be strings
235
238
  or symbols. If you send in a key that matches a [special property](https://mixpanel.com/docs/people-analytics/special-properties),
@@ -239,20 +242,26 @@ it will automatically be converted to the correct form (e.g., `{ :first_name =>
239
242
 
240
243
  * **async**: boolean
241
244
 
242
- *Default: the async value from when the class was instantiated*
245
+ *Default: the async value from when the class was instantiated*
243
246
 
244
247
  * **url**: string
245
248
 
246
- *Default: `http://api.mixpanel.com/engage/`*
247
-
248
- This can be used to proxy Mixpanel API requests
249
+ *Default: `http://api.mixpanel.com/engage/`*
249
250
 
250
- Example:
251
+ This can be used to proxy Mixpanel API requests
252
+
253
+ Example using `distinct_id` to identify the user:
251
254
 
252
255
  ```ruby
253
256
  @mixpanel.set 'john-doe', { :age => 31, :email => 'john@doe.com' }
254
257
  ```
255
258
 
259
+ Example using request properties, telling mixpanel to [ignore the time](https://groups.google.com/forum/#!msg/mp-dev/Ao4f8D0IKms/6MVhQqFDzL8J):
260
+
261
+ ```ruby
262
+ @mixpanel.set { :distinct_id => 'john-doe', :ignore_time => true }, { :age => 31, :email => 'john@doe.com' }
263
+ ```
264
+
256
265
  ### Increment Person Attributes Directly
257
266
 
258
267
  ```ruby
@@ -301,35 +310,39 @@ you identify the user, the change will not be immediately sent to Mixpanel. Mixp
301
310
  Occasionally you may need to send a request for HTML that you don't want the middleware to alter. In your AJAX request include the header "SKIP_MIXPANEL_MIDDLEWARE" to prevent the mixpanel code from being inserted.
302
311
 
303
312
  ```javascript
304
- $.ajax("/path/to/api/endpoint", {
305
- headers: {"SKIP_MIXPANEL_MIDDLEWARE": true},
306
- success: function(data) {
307
- // Process data here
308
- }
309
- });
313
+ $.ajax("/path/to/api/endpoint", {
314
+ headers: {"Skip-Mixpanel-Middleware": true}, // valid http headers don't allow underscores and get filtered by some webservers
315
+ success: function(data) {
316
+ // Process data here
317
+ }
318
+ });
310
319
  ```
311
320
 
312
321
  ## Examples
313
322
 
314
323
  ### How to use it from Rails controllers?
315
-
324
+
316
325
  In your ApplicationController class add a method to keep track of a Mixpanel instance.
317
326
 
318
327
  ```ruby
319
- protected
320
- def mixpanel
321
- @mixpanel ||= Mixpanel::Tracker.new YOUR_MIXPANEL_API_TOKEN, { :env => request.env }
322
- end
328
+ def mixpanel
329
+ @mixpanel ||= Mixpanel::Tracker.new YOUR_MIXPANEL_API_TOKEN, { :env => request.env }
330
+ end
323
331
  ```
324
332
 
325
333
  Then you can call against this method where it makes sense in your controller. For example, in the users#create method:
326
334
 
327
335
  ```ruby
328
- def create
329
- @user = User.create( :name => 'Jane Doe', :gender => 'female', :mixpanel_identifer => 'asdf' )
330
- mixpanel.track 'User Created', { :gender => @user.gender, :distinct_id => @user.mixpanel_identifier, :time => @user.created_at } # Note that passing the time key overwrites the default value of Time.now
331
- mixpanel.set @user.mixpanel_identifer, { :gender => @user.gender, :created => @user.created_at, :name => @user.name }
332
- end
336
+ def create
337
+ @user = User.create( :name => 'Jane Doe', :gender => 'female', :mixpanel_identifer => 'asdf' )
338
+ mixpanel.track 'User Created', {
339
+ :gender => @user.gender,
340
+ :distinct_id => @user.mixpanel_identifier,
341
+ :time => @user.created_at
342
+ } # Note that passing the time key overwrites the default value of Time.now
343
+
344
+ mixpanel.set @user.mixpanel_identifer, { :gender => @user.gender, :created => @user.created_at, :name => @user.name }
345
+ end
333
346
  ```
334
347
 
335
348
  ## How to track events using Resque and Rails
@@ -339,38 +352,39 @@ might be done with [Resque](https://github.com/defunkt/resque), but the same con
339
352
 
340
353
  ```ruby
341
354
  class MixpanelTrackEventJob
342
- @queue = :slow
355
+ @queue = :slow
343
356
 
344
- def self.mixpanel env
345
- Mixpanel::Tracker.new MIXPANEL_TOKEN, { :env => env }
346
- end
357
+ def self.mixpanel env
358
+ Mixpanel::Tracker.new MIXPANEL_TOKEN, { :env => env }
359
+ end
347
360
 
348
- def self.perform name, properties, env
349
- mixpanel(env).track name, params
350
- end
361
+ def self.perform name, properties, env
362
+ mixpanel(env).track name, properties
363
+ end
351
364
  end
352
365
  ```
353
366
 
354
367
  ```ruby
355
- class UsersController < ApplicationController
356
- def create
357
- @user = User.new(params[:user])
358
-
359
- if @user.save
360
- env = {
361
- 'REMOTE_ADDR' => request.env['REMOTE_ADDR'],
362
- 'HTTP_X_FORWARDED_FOR' => request.env['HTTP_X_FORWARDED_FOR'],
363
- 'rack.session' => request.env['rack.session'],
364
- 'mixpanel_events' => request.env['mixpanel_events']
365
- } # Trying to pass request.env to Resque is going to fail (it chokes when trying to conver it to JSON, but no worries...)
366
-
367
- Resque.enqueue MixpanelTrackEventJob, 'Sign up', { :invited => params[:invited] }, env
368
- redirect_to user_root_path
369
- else
370
- render :new
371
- end
372
- end
373
- end
368
+ class UsersController < ApplicationController
369
+ def create
370
+ @user = User.new(params[:user])
371
+
372
+ if @user.save
373
+ env = {
374
+ 'REMOTE_ADDR' => request.env['REMOTE_ADDR'],
375
+ 'HTTP_X_FORWARDED_FOR' => request.env['HTTP_X_FORWARDED_FOR'],
376
+ 'rack.session' => request.env['rack.session'],
377
+ 'mixpanel_events' => request.env['mixpanel_events']
378
+ } # Trying to pass request.env to Resque is going to fail (it chokes when trying to conver it to JSON, but no worries...)
379
+
380
+ Resque.enqueue MixpanelTrackEventJob, 'Sign up', { :invited => params[:invited] }, env
381
+
382
+ redirect_to user_root_path
383
+ else
384
+ render :new
385
+ end
386
+ end
387
+ end
374
388
  ```
375
389
 
376
390
  ## Supported Ruby Platforms
@@ -398,3 +412,4 @@ end
398
412
  * [Goalee](https://github.com/Goalee)
399
413
  * [Ahmed Belal](https://github.com/AhmedBelal)
400
414
  * [Esteban Pastorino](https://github.com/kitop)
415
+ * [Jeffrey Chu](https://github.com/jochu)
@@ -2,7 +2,7 @@ module Mixpanel::Event
2
2
  EVENT_PROPERTIES = %w{initial_referrer initial_referring_domain search_engine os browser referrer referring_domain}
3
3
  TRACK_URL = 'http://api.mixpanel.com/track/'
4
4
  IMPORT_URL = 'http://api.mixpanel.com/import/'
5
-
5
+
6
6
  def track(event, properties={}, options={})
7
7
  track_event event, properties, options, TRACK_URL
8
8
  end
@@ -10,33 +10,31 @@ module Mixpanel::Event
10
10
  def tracking_pixel(event, properties={}, options={})
11
11
  build_url event, properties, options.merge(:url => TRACK_URL, :img => true)
12
12
  end
13
-
13
+
14
14
  def import(event, properties={}, options={})
15
15
  track_event event, properties, options, IMPORT_URL
16
16
  end
17
-
17
+
18
18
  def append_track(event, properties={})
19
19
  append 'track', event, track_properties(properties, false)
20
20
  end
21
-
21
+
22
22
  protected
23
-
23
+
24
24
  def track_event(event, properties, options, default_url)
25
- options.reverse_merge! :url => default_url, :async => @async, :api_key => @api_key
26
- url = build_url event, properties, options
25
+ default = {:url => default_url, :async => @async, :api_key => @api_key}
26
+ url = build_url(event, properties, default.merge(options))
27
27
  parse_response request(url, options[:async])
28
28
  end
29
-
30
- def ip
31
- (@env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_ADDR'] || '').split(',').last
32
- end
33
-
29
+
34
30
  def track_properties(properties, include_token=true)
35
- properties.reverse_merge! :time => Time.now, :ip => ip
36
- properties.reverse_merge! :token => @token if include_token
37
- properties_hash properties, EVENT_PROPERTIES
31
+ default = {:time => Time.now, :ip => ip}
32
+ properties = default.merge(properties)
33
+
34
+ properties.merge!(:token => @token) if include_token
35
+ properties_hash(properties, EVENT_PROPERTIES)
38
36
  end
39
-
37
+
40
38
  def build_event(event, properties)
41
39
  { :event => event, :properties => properties_hash(properties, EVENT_PROPERTIES) }
42
40
  end
@@ -44,7 +42,7 @@ module Mixpanel::Event
44
42
  def build_url event, properties, options
45
43
  data = build_event event, track_properties(properties)
46
44
  url = "#{options[:url]}?data=#{encoded_data(data)}"
47
- url << "&api_key=#{options[:api_key]}" if options[:api_key].present?
45
+ url << "&api_key=#{options[:api_key]}" if options.fetch(:api_key, nil)
48
46
  url << "&img=1" if options[:img]
49
47
  url
50
48
  end
@@ -1,27 +1,28 @@
1
1
  module Mixpanel::Person
2
2
  PERSON_PROPERTIES = %w{email created first_name last_name name last_login username country_code}
3
+ PERSON_REQUEST_PROPERTIES = %w{token distinct_id ip ignore_time}
3
4
  PERSON_URL = 'http://api.mixpanel.com/engage/'
4
-
5
+
5
6
  def set(distinct_id, properties={}, options={})
6
7
  engage :set, distinct_id, properties, options
7
8
  end
8
-
9
+
9
10
  def increment(distinct_id, properties={}, options={})
10
11
  engage :add, distinct_id, properties, options
11
12
  end
12
-
13
+
13
14
  def append_set(properties={})
14
15
  append 'people.set', properties_hash(properties, PERSON_PROPERTIES)
15
16
  end
16
-
17
+
17
18
  def append_increment(property, increment=1)
18
19
  append 'people.increment', property, increment
19
20
  end
20
-
21
+
21
22
  def append_register(properties={})
22
23
  append 'register', properties_hash(properties, PERSON_PROPERTIES)
23
24
  end
24
-
25
+
25
26
  def append_identify(distinct_id)
26
27
  append 'identify', distinct_id
27
28
  end
@@ -29,17 +30,30 @@ module Mixpanel::Person
29
30
  def append_people_identify(distinct_id)
30
31
  append 'people.identify', distinct_id
31
32
  end
32
-
33
+
33
34
  protected
34
-
35
- def engage(action, distinct_id, properties, options)
36
- options.reverse_merge! :async => @async, :url => PERSON_URL
37
- data = build_person action, distinct_id, properties
35
+
36
+ def engage(action, request_properties_or_distinct_id, properties, options)
37
+ default = {:async => @async, :url => PERSON_URL}
38
+ options = default.merge(options)
39
+
40
+ request_properties = person_request_properties(request_properties_or_distinct_id)
41
+
42
+ data = build_person action, request_properties, properties
38
43
  url = "#{options[:url]}?data=#{encoded_data(data)}"
39
44
  parse_response request(url, options[:async])
40
45
  end
41
-
42
- def build_person(action, distinct_id, properties)
43
- { "$#{action}".to_sym => properties_hash(properties, PERSON_PROPERTIES), :$token => @token, :$distinct_id => distinct_id }
46
+
47
+ def person_request_properties(request_properties_or_distinct_id)
48
+ default = {:token => @token, :ip => ip}
49
+ if request_properties_or_distinct_id.respond_to? :to_hash
50
+ default.merge(request_properties_or_distinct_id)
51
+ else
52
+ default.merge({ :distinct_id => request_properties_or_distinct_id })
53
+ end
54
+ end
55
+
56
+ def build_person(action, request_properties, person_properties)
57
+ properties_hash(request_properties, PERSON_REQUEST_PROPERTIES).merge({ "$#{action}".to_sym => properties_hash(person_properties, PERSON_PROPERTIES) })
44
58
  end
45
- end
59
+ end
@@ -8,18 +8,18 @@ module Mixpanel
8
8
  require 'mixpanel/async'
9
9
  require 'mixpanel/event'
10
10
  require 'mixpanel/person'
11
-
11
+
12
12
  extend Mixpanel::Async
13
13
  include Mixpanel::Event
14
14
  include Mixpanel::Person
15
-
15
+
16
16
  def initialize(token, options={})
17
17
  @token = token
18
18
  @async = !!options.fetch(:async, false)
19
19
  @persist = !!options.fetch(:persist, false)
20
20
  @env = options.fetch :env, {}
21
21
  @api_key = options.fetch :api_key, nil
22
-
22
+
23
23
  # Make sure queue object is instantiated to an array. If not persisted, set queue object to empty array.
24
24
  if @persist
25
25
  @env['rack.session'] ||= {}
@@ -28,17 +28,21 @@ module Mixpanel
28
28
  @env['mixpanel_events'] = []
29
29
  end
30
30
  end
31
-
31
+
32
32
  def queue
33
33
  @persist ? @env['rack.session']['mixpanel_events'] : @env['mixpanel_events']
34
34
  end
35
-
35
+
36
36
  def append(type, *args)
37
37
  queue << [type, args.collect {|arg| arg.to_json}]
38
38
  end
39
-
39
+
40
40
  protected
41
-
41
+
42
+ def ip
43
+ (@env['HTTP_X_FORWARDED_FOR'] || @env['REMOTE_ADDR'] || '').split(',').last
44
+ end
45
+
42
46
  # Walk through each property and see if it is in the special_properties. If so, change the key to have a $ in front of it.
43
47
  def properties_hash(properties, special_properties)
44
48
  properties.inject({}) do |props, (key, value)|
@@ -47,19 +51,19 @@ module Mixpanel
47
51
  props
48
52
  end
49
53
  end
50
-
54
+
51
55
  def encoded_data(parameters)
52
56
  Base64.encode64(JSON.generate(parameters)).gsub(/\n/,'')
53
57
  end
54
-
58
+
55
59
  def request(url, async)
56
60
  async ? send_async(url) : open(url).read
57
61
  end
58
-
62
+
59
63
  def parse_response(response)
60
64
  response.to_i == 1
61
65
  end
62
-
66
+
63
67
  def send_async(url)
64
68
  w = Mixpanel::Tracker.worker
65
69
  begin
@@ -72,4 +76,4 @@ module Mixpanel
72
76
  end
73
77
  end
74
78
  end
75
- end
79
+ end
@@ -2,7 +2,7 @@ files = ['README.md', 'LICENSE', 'Rakefile', 'mixpanel.gemspec', '{spec,lib}/**/
2
2
 
3
3
  spec = Gem::Specification.new do |s|
4
4
  s.name = "mixpanel"
5
- s.version = "3.1.0"
5
+ s.version = "3.4.0"
6
6
  s.rubyforge_project = "mixpanel"
7
7
  s.description = "Simple lib to track events in Mixpanel service. It can be used in any rack based framework."
8
8
  s.author = "Alvaro Gil"
@@ -17,13 +17,9 @@ spec = Gem::Specification.new do |s|
17
17
  s.add_dependency 'json'
18
18
  s.add_dependency 'rack'
19
19
  s.add_dependency 'escape'
20
- s.add_development_dependency 'active_support'
21
20
  s.add_development_dependency 'rspec'
22
21
  s.add_development_dependency 'rack-test'
23
22
  s.add_development_dependency 'fakeweb'
24
23
  s.add_development_dependency 'nokogiri'
25
24
  s.add_development_dependency 'rake'
26
- s.add_development_dependency 'debugger' if RUBY_VERSION =~ /^1\.9\.3/
27
- s.add_development_dependency 'ruby-debug19' if RUBY_VERSION =~ /^1\.9\.2/
28
- s.add_development_dependency 'ruby-debug' if RUBY_VERSION =~ /^1\.8/
29
25
  end
@@ -8,7 +8,8 @@ def exec_default_appends_on(mixpanel)
8
8
  end
9
9
 
10
10
  def check_for_default_appends_on(txt)
11
- txt.should =~ /mixpanel\.track\("Visit",\s?\{.*"article":1[\{|,]/
11
+
12
+ txt.should =~ /mixpanel\.track\("Visit",\s?\{.*"article":1/
12
13
  txt.should =~ /mixpanel\.track\("Sign in",\s?\{.*"time":.*\}/
13
14
  txt.should =~ /mixpanel\.people\.set\(.*\);\nmixpanel.people.increment\(\"sign_in_rate\",\s?1\);/
14
15
  match = txt.match(/mixpanel\.people\.set\((.*\));/)
@@ -25,7 +25,7 @@ describe Mixpanel::Tracker do
25
25
  it "should track simple events" do
26
26
  @mixpanel.track("Sign up").should == true
27
27
  end
28
-
28
+
29
29
  it "should track events with properties" do
30
30
  @mixpanel.track('Sign up', { :likeable => true }, { :api_key => 'asdf' }).should == true
31
31
  end
@@ -40,22 +40,26 @@ describe Mixpanel::Tracker do
40
40
  @mixpanel.tracking_pixel("Sign up").should match(/&img=1/)
41
41
  end
42
42
  end
43
-
43
+
44
44
  context "Importing events" do
45
45
  it "should import simple events" do
46
46
  @mixpanel.import('Sign up').should == true
47
47
  end
48
-
48
+
49
49
  it "should import events with properties" do
50
50
  @mixpanel.import('Sign up', { :likeable => true }, { :api_key => 'asdf' }).should == true
51
51
  end
52
52
  end
53
-
53
+
54
54
  context "Engaging people" do
55
55
  it "should set attributes" do
56
56
  @mixpanel.set('person-a', { :email => 'me@domain.com', :likeable => false }).should == true
57
57
  end
58
-
58
+
59
+ it "should set attributes with request properties" do
60
+ @mixpanel.set({ :distinct_id => 'person-a', :ignore_time => true }, { :email => 'me@domain.com', :likeable => false }).should == true
61
+ end
62
+
59
63
  it "should increment attributes" do
60
64
  @mixpanel.increment('person-a', { :tokens => 3, :money => -1 }).should == true
61
65
  end
@@ -1,9 +1,7 @@
1
- require 'ruby-debug'
2
1
  require File.join(File.dirname(__FILE__), "../lib", "mixpanel")
3
2
  require 'rack/test'
4
3
  require 'fakeweb'
5
4
  require 'nokogiri'
6
- require 'active_support/core_ext/hash'
7
5
 
8
6
  Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
9
7
 
metadata CHANGED
@@ -1,172 +1,112 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mixpanel
3
- version: !ruby/object:Gem::Version
4
- hash: 3
5
- prerelease: false
6
- segments:
7
- - 3
8
- - 1
9
- - 0
10
- version: 3.1.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.4.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Alvaro Gil
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-11-13 00:00:00 -02:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-12-23 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: json
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2153080840 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: rack
37
23
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2153080840
25
+ - !ruby/object:Gem::Dependency
26
+ name: rack
27
+ requirement: &2153080400 !ruby/object:Gem::Requirement
39
28
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
47
33
  type: :runtime
48
- version_requirements: *id002
49
- - !ruby/object:Gem::Dependency
50
- name: escape
51
34
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2153080400
36
+ - !ruby/object:Gem::Dependency
37
+ name: escape
38
+ requirement: &2153079980 !ruby/object:Gem::Requirement
53
39
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
61
44
  type: :runtime
62
- version_requirements: *id003
63
- - !ruby/object:Gem::Dependency
64
- name: active_support
65
45
  prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
67
- none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
75
- type: :development
76
- version_requirements: *id004
77
- - !ruby/object:Gem::Dependency
46
+ version_requirements: *2153079980
47
+ - !ruby/object:Gem::Dependency
78
48
  name: rspec
79
- prerelease: false
80
- requirement: &id005 !ruby/object:Gem::Requirement
49
+ requirement: &2153079560 !ruby/object:Gem::Requirement
81
50
  none: false
82
- requirements:
83
- - - ">="
84
- - !ruby/object:Gem::Version
85
- hash: 3
86
- segments:
87
- - 0
88
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
89
55
  type: :development
90
- version_requirements: *id005
91
- - !ruby/object:Gem::Dependency
92
- name: rack-test
93
56
  prerelease: false
94
- requirement: &id006 !ruby/object:Gem::Requirement
57
+ version_requirements: *2153079560
58
+ - !ruby/object:Gem::Dependency
59
+ name: rack-test
60
+ requirement: &2153079140 !ruby/object:Gem::Requirement
95
61
  none: false
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- hash: 3
100
- segments:
101
- - 0
102
- version: "0"
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
103
66
  type: :development
104
- version_requirements: *id006
105
- - !ruby/object:Gem::Dependency
106
- name: fakeweb
107
67
  prerelease: false
108
- requirement: &id007 !ruby/object:Gem::Requirement
68
+ version_requirements: *2153079140
69
+ - !ruby/object:Gem::Dependency
70
+ name: fakeweb
71
+ requirement: &2153078720 !ruby/object:Gem::Requirement
109
72
  none: false
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- hash: 3
114
- segments:
115
- - 0
116
- version: "0"
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
117
77
  type: :development
118
- version_requirements: *id007
119
- - !ruby/object:Gem::Dependency
120
- name: nokogiri
121
78
  prerelease: false
122
- requirement: &id008 !ruby/object:Gem::Requirement
79
+ version_requirements: *2153078720
80
+ - !ruby/object:Gem::Dependency
81
+ name: nokogiri
82
+ requirement: &2153078300 !ruby/object:Gem::Requirement
123
83
  none: false
124
- requirements:
125
- - - ">="
126
- - !ruby/object:Gem::Version
127
- hash: 3
128
- segments:
129
- - 0
130
- version: "0"
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
131
88
  type: :development
132
- version_requirements: *id008
133
- - !ruby/object:Gem::Dependency
134
- name: rake
135
89
  prerelease: false
136
- requirement: &id009 !ruby/object:Gem::Requirement
90
+ version_requirements: *2153078300
91
+ - !ruby/object:Gem::Dependency
92
+ name: rake
93
+ requirement: &2153104240 !ruby/object:Gem::Requirement
137
94
  none: false
138
- requirements:
139
- - - ">="
140
- - !ruby/object:Gem::Version
141
- hash: 3
142
- segments:
143
- - 0
144
- version: "0"
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
145
99
  type: :development
146
- version_requirements: *id009
147
- - !ruby/object:Gem::Dependency
148
- name: ruby-debug
149
100
  prerelease: false
150
- requirement: &id010 !ruby/object:Gem::Requirement
151
- none: false
152
- requirements:
153
- - - ">="
154
- - !ruby/object:Gem::Version
155
- hash: 3
156
- segments:
157
- - 0
158
- version: "0"
159
- type: :development
160
- version_requirements: *id010
161
- description: Simple lib to track events in Mixpanel service. It can be used in any rack based framework.
101
+ version_requirements: *2153104240
102
+ description: Simple lib to track events in Mixpanel service. It can be used in any
103
+ rack based framework.
162
104
  email: zevarito@gmail.com
163
105
  executables: []
164
-
165
106
  extensions: []
166
-
167
- extra_rdoc_files:
107
+ extra_rdoc_files:
168
108
  - README.md
169
- files:
109
+ files:
170
110
  - README.md
171
111
  - LICENSE
172
112
  - Rakefile
@@ -182,39 +122,28 @@ files:
182
122
  - lib/mixpanel/subprocess.rb
183
123
  - lib/mixpanel/tracker.rb
184
124
  - lib/mixpanel.rb
185
- has_rdoc: true
186
125
  homepage: http://github.com/zevarito/mixpanel
187
126
  licenses: []
188
-
189
127
  post_install_message:
190
128
  rdoc_options: []
191
-
192
- require_paths:
129
+ require_paths:
193
130
  - lib
194
- required_ruby_version: !ruby/object:Gem::Requirement
131
+ required_ruby_version: !ruby/object:Gem::Requirement
195
132
  none: false
196
- requirements:
197
- - - ">="
198
- - !ruby/object:Gem::Version
199
- hash: 3
200
- segments:
201
- - 0
202
- version: "0"
203
- required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ! '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
138
  none: false
205
- requirements:
206
- - - ">="
207
- - !ruby/object:Gem::Version
208
- hash: 3
209
- segments:
210
- - 0
211
- version: "0"
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
212
143
  requirements: []
213
-
214
144
  rubyforge_project: mixpanel
215
- rubygems_version: 1.3.7
145
+ rubygems_version: 1.8.15
216
146
  signing_key:
217
147
  specification_version: 3
218
148
  summary: Supports direct request api and javascript requests through a middleware.
219
149
  test_files: []
220
-