mixpanel 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,6 +28,12 @@ If you want to use the asynchronous version of Mixpanel's javascript API
28
28
 
29
29
  config.middleware.use "Mixpanel::Tracker::Middleware", "YOUR_MIXPANEL_API_TOKEN", :async => true
30
30
 
31
+ By default the scripts are inserted into the head of the html response. If you'd prefer the scripts to run after all rendering has completed you can set the insert_js_last flag and they'll be added at the end of the body tag. This will work whether or not you opt for the aynchronous version of the API. However, when inserting js into an ajax response it will have no effect:
32
+
33
+ Rails::Initializer.run do |config|
34
+
35
+ config.middleware.use "Mixpanel::Tracker::Middleware", "YOUR_MIXPANEL_API_TOKEN", :async => true, :insert_js_last => true
36
+
31
37
  In your application_controller class add a method to instance mixpanel.
32
38
 
33
39
  before_filter :initialize_mixpanel
@@ -51,6 +57,36 @@ To execute any javascript API call
51
57
  @mixpanel.append_api("register", {:some => "property"})
52
58
  @mixpanel.append_api("identify", "Unique Identifier")
53
59
 
60
+ == Resque and Rails example
61
+
62
+ If you don't want to use the built in Mixpanel Gem async feature bellow there is an example about how to make async calls using Resque.
63
+
64
+ {Resque is a Redis-backed Ruby library for creating background jobs}[https://github.com/defunkt/resque]
65
+
66
+ class MixpanelTrackEventJob
67
+ @queue = :slow
68
+
69
+ def mixpanel(request_env)
70
+ Mixpanel.new(MIXPANEL_TOKEN, request_env)
71
+ end
72
+
73
+ def perform(name, params, request_env)
74
+ mixpanel(request_env).track_event(name, params)
75
+ end
76
+ end
77
+
78
+ class UsersController < ApplicationController
79
+ def create
80
+ @user = User.new(params[:user])
81
+
82
+ if @user.save
83
+ MixpanelTrackEventJob.enqueue("Sign up", {:invited => params[:invited]}, request.env)
84
+ redirect_to user_root_path
85
+ else
86
+ render :new
87
+ end
88
+ end
89
+ end
54
90
 
55
91
  == Notes
56
92
 
@@ -64,10 +100,15 @@ For a short term this method will be accepted but it will be deprecated soon.
64
100
 
65
101
  Mixpanel.new
66
102
 
103
+ == Collaborations
104
+
105
+ All collaborations are welcome to this project, please fork and make a pull request.
106
+
67
107
  == Collaborators and Maintainers
68
108
 
69
109
  * {Alvaro Gil}[https://github.com/zevarito] (Author)
70
110
  * {Nathan Baxter}[https://github.com/LogicWolfe]
71
111
  * {Jake Mallory}[https://github.com/tinomen]
72
112
  * {Logan Bowers}[https://github.com/loganb]
73
- * {jakemack} [https://github.com/jakemack]
113
+ * {jakemack}[https://github.com/jakemack]
114
+ * {James Ferguson}[https://github.com/JamesFerguson]
data/Rakefile CHANGED
@@ -1,9 +1,10 @@
1
- require 'spec/rake/spectask'
1
+ require 'rubygems'
2
+ require 'rspec/core/rake_task'
2
3
 
3
4
  task :default => :spec
4
5
 
5
6
  desc "Run all examples"
6
- Spec::Rake::SpecTask.new('spec') do |t|
7
- t.spec_opts = ["-u -c -fs"]
8
- t.spec_files = FileList['spec/**/*_spec.rb']
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.rspec_opts = ["-c -fs"]
9
+ t.pattern = 'spec/**/*_spec.rb'
9
10
  end
@@ -7,7 +7,8 @@ module Mixpanel
7
7
  @app = app
8
8
  @token = mixpanel_token
9
9
  @options = {
10
- :async => false
10
+ :async => false,
11
+ :insert_js_last => false
11
12
  }.merge(options)
12
13
  end
13
14
 
@@ -16,9 +17,11 @@ module Mixpanel
16
17
 
17
18
  @status, @headers, @response = @app.call(env)
18
19
 
19
- update_response!
20
- update_content_length!
21
- delete_event_queue!
20
+ if is_trackable_response?
21
+ update_response!
22
+ update_content_length!
23
+ delete_event_queue!
24
+ end
22
25
 
23
26
  [@status, @headers, @response]
24
27
  end
@@ -28,7 +31,7 @@ module Mixpanel
28
31
  def update_response!
29
32
  @response.each do |part|
30
33
  if is_regular_request? && is_html_response?
31
- insert_at = part.index('</head')
34
+ insert_at = part.index(@options[:insert_js_last] ? '</body' : '</head')
32
35
  unless insert_at.nil?
33
36
  part.insert(insert_at, render_event_tracking_scripts) unless queue.empty?
34
37
  part.insert(insert_at, render_mixpanel_scripts) #This will insert the mixpanel initialization code before the queue of tracking events.
@@ -63,6 +66,10 @@ module Mixpanel
63
66
  @headers["Content-Type"].include?("text/javascript") if @headers.has_key?("Content-Type")
64
67
  end
65
68
 
69
+ def is_trackable_response?
70
+ is_html_response? || is_javascript_response?
71
+ end
72
+
66
73
  def render_mixpanel_scripts
67
74
  if @options[:async]
68
75
  <<-EOT
@@ -2,12 +2,12 @@ files = ['README.rdoc', 'LICENSE', 'Rakefile', 'mixpanel.gemspec', '{spec,lib}/*
2
2
 
3
3
  spec = Gem::Specification.new do |s|
4
4
  s.name = "mixpanel"
5
- s.version = "1.0.0"
5
+ s.version = "1.1.1"
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"
9
9
  s.email = "zevarito@gmail.com"
10
- s.homepage = "http://cuboxsa.com"
10
+ s.homepage = "http://github.com/zevarito/mixpanel"
11
11
  s.platform = Gem::Platform::RUBY
12
12
  s.summary = "Supports direct request api and javascript requests through a middleware."
13
13
  s.files = files
@@ -21,4 +21,7 @@ spec = Gem::Specification.new do |s|
21
21
  s.add_development_dependency 'rack-test'
22
22
  s.add_development_dependency 'fakeweb'
23
23
  s.add_development_dependency 'nokogiri'
24
+ s.add_development_dependency 'rake'
25
+ s.add_development_dependency 'ruby-debug19' if RUBY_VERSION =~ /^1\.9/
26
+ s.add_development_dependency 'ruby-debug' if RUBY_VERSION =~ /^1\.8/
24
27
  end
@@ -29,13 +29,13 @@ describe Mixpanel::Tracker::Middleware do
29
29
  last_response.headers["Content-Length"].should == html_document.length.to_s
30
30
  end
31
31
  end
32
-
32
+
33
33
  describe "With large ajax response" do
34
34
  before do
35
35
  setup_rack_application(DummyApp, {:body => large_script, :headers => {"Content-Type" => "text/html"}}, {:async => true})
36
36
  get "/", {}, {"HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"}
37
37
  end
38
-
38
+
39
39
  it "should not append mixpanel scripts to head element" do
40
40
  last_response.body.index('var mp_protocol').should be_nil
41
41
  end
@@ -44,32 +44,46 @@ describe Mixpanel::Tracker::Middleware do
44
44
  last_response.body.should == large_script
45
45
  end
46
46
  end
47
-
47
+
48
48
  describe "With regular requests" do
49
- before do
50
- setup_rack_application(DummyApp, {:body => html_document, :headers => {"Content-Type" => "text/html"}}, {:async => true})
51
- get "/"
52
- end
49
+ describe "With js in head" do
50
+ before do
51
+ setup_rack_application(DummyApp, {:body => html_document, :headers => {"Content-Type" => "text/html"}}, {:async => true, :insert_js_last => false})
52
+ get "/"
53
+ end
53
54
 
54
- it "should append mixpanel scripts to head element" do
55
- Nokogiri::HTML(last_response.body).search('head script').should_not be_empty
56
- Nokogiri::HTML(last_response.body).search('body script').should be_empty
57
- end
55
+ it "should append mixpanel scripts to head element" do
56
+ Nokogiri::HTML(last_response.body).search('head script').should_not be_empty
57
+ Nokogiri::HTML(last_response.body).search('body script').should be_empty
58
+ end
58
59
 
59
- it "should have 1 included script" do
60
- Nokogiri::HTML(last_response.body).search('script').size.should == 1
61
- end
60
+ it "should have 1 included script" do
61
+ Nokogiri::HTML(last_response.body).search('script').size.should == 1
62
+ end
62
63
 
63
- it "should use the specified token instantiating mixpanel lib" do
64
- last_response.should =~ /mpq.push\(\["init", "#{MIX_PANEL_TOKEN}"\]\)/
65
- end
64
+ it "should use the specified token instantiating mixpanel lib" do
65
+ last_response.should =~ /mpq.push\(\["init", "#{MIX_PANEL_TOKEN}"\]\)/
66
+ end
67
+
68
+ it "should define Content-Length if not exist" do
69
+ last_response.headers.has_key?("Content-Length").should == true
70
+ end
66
71
 
67
- it "should define Content-Length if not exist" do
68
- last_response.headers.has_key?("Content-Length").should == true
72
+ it "should update Content-Length in headers" do
73
+ last_response.headers["Content-Length"].should_not == html_document.length.to_s
74
+ end
69
75
  end
70
76
 
71
- it "should update Content-Length in headers" do
72
- last_response.headers["Content-Length"].should_not == html_document.length.to_s
77
+ describe "With js last" do
78
+ before do
79
+ setup_rack_application(DummyApp, {:body => html_document, :headers => {"Content-Type" => "text/html"}}, {:async => true, :insert_js_last => true})
80
+ get "/"
81
+ end
82
+
83
+ it "should append mixpanel scripts to end of body element" do
84
+ Nokogiri::HTML(last_response.body).search('head script').should be_empty
85
+ Nokogiri::HTML(last_response.body).search('body script').should_not be_empty
86
+ end
73
87
  end
74
88
  end
75
89
  end
@@ -89,13 +103,13 @@ describe Mixpanel::Tracker::Middleware do
89
103
  last_response.headers["Content-Length"].should == html_document.length.to_s
90
104
  end
91
105
  end
92
-
106
+
93
107
  describe "With large ajax response" do
94
108
  before do
95
109
  setup_rack_application(DummyApp, :body => large_script, :headers => {"Content-Type" => "text/html"})
96
110
  get "/", {}, {"HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"}
97
111
  end
98
-
112
+
99
113
  it "should not append mixpanel scripts to head element" do
100
114
  last_response.body.index('var mp_protocol').should be_nil
101
115
  end
@@ -104,32 +118,46 @@ describe Mixpanel::Tracker::Middleware do
104
118
  last_response.body.should == large_script
105
119
  end
106
120
  end
107
-
108
- describe "With regular requests" do
109
- before do
110
- setup_rack_application(DummyApp, :body => html_document, :headers => {"Content-Type" => "text/html"})
111
- get "/"
112
- end
113
-
114
- it "should append mixpanel scripts to head element" do
115
- Nokogiri::HTML(last_response.body).search('head script').should_not be_empty
116
- Nokogiri::HTML(last_response.body).search('body script').should be_empty
117
- end
118
-
119
- it "should have 2 included scripts" do
120
- Nokogiri::HTML(last_response.body).search('script').size.should == 2
121
- end
122
-
123
- it "should use the specified token instantiating mixpanel lib" do
124
- last_response.should =~ /new MixpanelLib\('#{MIX_PANEL_TOKEN}'\)/
125
- end
126
121
 
127
- it "should define Content-Length if not exist" do
128
- last_response.headers.has_key?("Content-Length").should == true
129
- end
130
-
131
- it "should update Content-Length in headers" do
132
- last_response.headers["Content-Length"].should_not == html_document.length.to_s
122
+ describe "With regular requests" do
123
+ describe "With js in head" do
124
+ before do
125
+ setup_rack_application(DummyApp, {:body => html_document, :headers => {"Content-Type" => "text/html"}}, {:insert_js_last => false})
126
+ get "/"
127
+ end
128
+
129
+ it "should append mixpanel scripts to head element" do
130
+ Nokogiri::HTML(last_response.body).search('head script').should_not be_empty
131
+ Nokogiri::HTML(last_response.body).search('body script').should be_empty
132
+ end
133
+
134
+ it "should have 2 included scripts" do
135
+ Nokogiri::HTML(last_response.body).search('script').size.should == 2
136
+ end
137
+
138
+ it "should use the specified token instantiating mixpanel lib" do
139
+ last_response.should =~ /new MixpanelLib\('#{MIX_PANEL_TOKEN}'\)/
140
+ end
141
+
142
+ it "should define Content-Length if not exist" do
143
+ last_response.headers.has_key?("Content-Length").should == true
144
+ end
145
+
146
+ it "should update Content-Length in headers" do
147
+ last_response.headers["Content-Length"].should_not == html_document.length.to_s
148
+ end
149
+ end
150
+
151
+ describe "With js last" do
152
+ before do
153
+ setup_rack_application(DummyApp, {:body => html_document, :headers => {"Content-Type" => "text/html"}}, {:insert_js_last => true})
154
+ get "/"
155
+ end
156
+
157
+ it "should append mixpanel scripts to end of body element" do
158
+ Nokogiri::HTML(last_response.body).search('head script').should be_empty
159
+ Nokogiri::HTML(last_response.body).search('body script').should_not be_empty
160
+ end
133
161
  end
134
162
  end
135
163
  end
@@ -7,7 +7,7 @@ describe Mixpanel::Tracker do
7
7
 
8
8
  context "Initializing object" do
9
9
  it "should have an instance variable for token and events" do
10
- @mixpanel.instance_variables.should include("@token", "@env")
10
+ @mixpanel.instance_variables.map(&:to_s).should include("@token", "@env")
11
11
  end
12
12
  end
13
13
 
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixpanel
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
4
  prerelease: false
6
5
  segments:
7
6
  - 1
8
- - 0
9
- - 0
10
- version: 1.0.0
7
+ - 1
8
+ - 1
9
+ version: 1.1.1
11
10
  platform: ruby
12
11
  authors:
13
12
  - Alvaro Gil
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2011-09-28 00:00:00 -03:00
17
+ date: 2011-11-23 00:00:00 -02:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -26,7 +25,6 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 3
30
28
  segments:
31
29
  - 0
32
30
  version: "0"
@@ -40,7 +38,6 @@ dependencies:
40
38
  requirements:
41
39
  - - ">="
42
40
  - !ruby/object:Gem::Version
43
- hash: 3
44
41
  segments:
45
42
  - 0
46
43
  version: "0"
@@ -54,7 +51,6 @@ dependencies:
54
51
  requirements:
55
52
  - - ">="
56
53
  - !ruby/object:Gem::Version
57
- hash: 3
58
54
  segments:
59
55
  - 0
60
56
  version: "0"
@@ -68,7 +64,6 @@ dependencies:
68
64
  requirements:
69
65
  - - ">="
70
66
  - !ruby/object:Gem::Version
71
- hash: 3
72
67
  segments:
73
68
  - 0
74
69
  version: "0"
@@ -82,7 +77,6 @@ dependencies:
82
77
  requirements:
83
78
  - - ">="
84
79
  - !ruby/object:Gem::Version
85
- hash: 3
86
80
  segments:
87
81
  - 0
88
82
  version: "0"
@@ -96,7 +90,6 @@ dependencies:
96
90
  requirements:
97
91
  - - ">="
98
92
  - !ruby/object:Gem::Version
99
- hash: 3
100
93
  segments:
101
94
  - 0
102
95
  version: "0"
@@ -110,12 +103,37 @@ dependencies:
110
103
  requirements:
111
104
  - - ">="
112
105
  - !ruby/object:Gem::Version
113
- hash: 3
114
106
  segments:
115
107
  - 0
116
108
  version: "0"
117
109
  type: :development
118
110
  version_requirements: *id007
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ prerelease: false
114
+ requirement: &id008 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ type: :development
123
+ version_requirements: *id008
124
+ - !ruby/object:Gem::Dependency
125
+ name: ruby-debug19
126
+ prerelease: false
127
+ requirement: &id009 !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ segments:
133
+ - 0
134
+ version: "0"
135
+ type: :development
136
+ version_requirements: *id009
119
137
  description: Simple lib to track events in Mixpanel service. It can be used in any rack based framework.
120
138
  email: zevarito@gmail.com
121
139
  executables: []
@@ -139,7 +157,7 @@ files:
139
157
  - lib/mixpanel/tracker.rb
140
158
  - lib/mixpanel.rb
141
159
  has_rdoc: true
142
- homepage: http://cuboxsa.com
160
+ homepage: http://github.com/zevarito/mixpanel
143
161
  licenses: []
144
162
 
145
163
  post_install_message:
@@ -152,7 +170,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
170
  requirements:
153
171
  - - ">="
154
172
  - !ruby/object:Gem::Version
155
- hash: 3
156
173
  segments:
157
174
  - 0
158
175
  version: "0"
@@ -161,7 +178,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
178
  requirements:
162
179
  - - ">="
163
180
  - !ruby/object:Gem::Version
164
- hash: 3
165
181
  segments:
166
182
  - 0
167
183
  version: "0"