mixpanel 2.2.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +233 -105
- data/lib/mixpanel/async.rb +31 -0
- data/lib/mixpanel/event.rb +41 -0
- data/lib/mixpanel/middleware.rb +142 -0
- data/lib/mixpanel/person.rb +41 -0
- data/lib/mixpanel/subprocess.rb +27 -0
- data/lib/mixpanel/tracker.rb +54 -151
- data/lib/mixpanel.rb +1 -0
- data/mixpanel.gemspec +2 -1
- data/spec/mixpanel/{tracker/middleware_spec.rb → middleware_spec.rb} +10 -10
- data/spec/mixpanel/tracker_spec.rb +33 -90
- data/spec/spec_helper.rb +13 -3
- data/spec/support/rack_apps.rb +1 -1
- metadata +37 -24
- data/lib/mixpanel/tracker/middleware.rb +0 -144
- data/lib/mixpanel/tracker/subprocess.rb +0 -29
- data/spec/mixpanel/mixpanel_spec.rb +0 -11
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixpanel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-12 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement: &
|
16
|
+
requirement: &2158058640 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2158058640
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rack
|
27
|
-
requirement: &
|
27
|
+
requirement: &2158058200 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2158058200
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: escape
|
38
|
-
requirement: &
|
38
|
+
requirement: &2158057780 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,21 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2158057780
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: active_support
|
49
|
+
requirement: &2158057360 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2158057360
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: rspec
|
49
|
-
requirement: &
|
60
|
+
requirement: &2158056940 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,10 +65,10 @@ dependencies:
|
|
54
65
|
version: '0'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *2158056940
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: rack-test
|
60
|
-
requirement: &
|
71
|
+
requirement: &2158056520 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,10 +76,10 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *2158056520
|
69
80
|
- !ruby/object:Gem::Dependency
|
70
81
|
name: fakeweb
|
71
|
-
requirement: &
|
82
|
+
requirement: &2158056100 !ruby/object:Gem::Requirement
|
72
83
|
none: false
|
73
84
|
requirements:
|
74
85
|
- - ! '>='
|
@@ -76,10 +87,10 @@ dependencies:
|
|
76
87
|
version: '0'
|
77
88
|
type: :development
|
78
89
|
prerelease: false
|
79
|
-
version_requirements: *
|
90
|
+
version_requirements: *2158056100
|
80
91
|
- !ruby/object:Gem::Dependency
|
81
92
|
name: nokogiri
|
82
|
-
requirement: &
|
93
|
+
requirement: &2158055680 !ruby/object:Gem::Requirement
|
83
94
|
none: false
|
84
95
|
requirements:
|
85
96
|
- - ! '>='
|
@@ -87,10 +98,10 @@ dependencies:
|
|
87
98
|
version: '0'
|
88
99
|
type: :development
|
89
100
|
prerelease: false
|
90
|
-
version_requirements: *
|
101
|
+
version_requirements: *2158055680
|
91
102
|
- !ruby/object:Gem::Dependency
|
92
103
|
name: rake
|
93
|
-
requirement: &
|
104
|
+
requirement: &2158055260 !ruby/object:Gem::Requirement
|
94
105
|
none: false
|
95
106
|
requirements:
|
96
107
|
- - ! '>='
|
@@ -98,10 +109,10 @@ dependencies:
|
|
98
109
|
version: '0'
|
99
110
|
type: :development
|
100
111
|
prerelease: false
|
101
|
-
version_requirements: *
|
112
|
+
version_requirements: *2158055260
|
102
113
|
- !ruby/object:Gem::Dependency
|
103
114
|
name: ruby-debug19
|
104
|
-
requirement: &
|
115
|
+
requirement: &2158054800 !ruby/object:Gem::Requirement
|
105
116
|
none: false
|
106
117
|
requirements:
|
107
118
|
- - ! '>='
|
@@ -109,7 +120,7 @@ dependencies:
|
|
109
120
|
version: '0'
|
110
121
|
type: :development
|
111
122
|
prerelease: false
|
112
|
-
version_requirements: *
|
123
|
+
version_requirements: *2158054800
|
113
124
|
description: Simple lib to track events in Mixpanel service. It can be used in any
|
114
125
|
rack based framework.
|
115
126
|
email: zevarito@gmail.com
|
@@ -122,13 +133,15 @@ files:
|
|
122
133
|
- LICENSE
|
123
134
|
- Rakefile
|
124
135
|
- mixpanel.gemspec
|
125
|
-
- spec/mixpanel/
|
126
|
-
- spec/mixpanel/tracker/middleware_spec.rb
|
136
|
+
- spec/mixpanel/middleware_spec.rb
|
127
137
|
- spec/mixpanel/tracker_spec.rb
|
128
138
|
- spec/spec_helper.rb
|
129
139
|
- spec/support/rack_apps.rb
|
130
|
-
- lib/mixpanel/
|
131
|
-
- lib/mixpanel/
|
140
|
+
- lib/mixpanel/async.rb
|
141
|
+
- lib/mixpanel/event.rb
|
142
|
+
- lib/mixpanel/middleware.rb
|
143
|
+
- lib/mixpanel/person.rb
|
144
|
+
- lib/mixpanel/subprocess.rb
|
132
145
|
- lib/mixpanel/tracker.rb
|
133
146
|
- lib/mixpanel.rb
|
134
147
|
homepage: http://github.com/zevarito/mixpanel
|
@@ -1,144 +0,0 @@
|
|
1
|
-
require 'rack'
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module Mixpanel
|
5
|
-
class Tracker
|
6
|
-
class Middleware
|
7
|
-
def initialize(app, mixpanel_token, options={})
|
8
|
-
@app = app
|
9
|
-
@token = mixpanel_token
|
10
|
-
@options = {
|
11
|
-
:insert_js_last => false,
|
12
|
-
:persist => false,
|
13
|
-
:config => {}
|
14
|
-
}.merge(options)
|
15
|
-
end
|
16
|
-
|
17
|
-
def call(env)
|
18
|
-
@env = env
|
19
|
-
|
20
|
-
@status, @headers, @response = @app.call(env)
|
21
|
-
|
22
|
-
if is_trackable_response?
|
23
|
-
merge_queue! if @options[:persist]
|
24
|
-
update_response!
|
25
|
-
update_content_length!
|
26
|
-
delete_event_queue!
|
27
|
-
end
|
28
|
-
|
29
|
-
[@status, @headers, @response]
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def update_response!
|
35
|
-
@response.each do |part|
|
36
|
-
if is_regular_request? && is_html_response?
|
37
|
-
insert_at = part.index(@options[:insert_js_last] ? '</body' : '</head')
|
38
|
-
unless insert_at.nil?
|
39
|
-
part.insert(insert_at, render_event_tracking_scripts) unless queue.empty?
|
40
|
-
part.insert(insert_at, render_mixpanel_scripts) #This will insert the mixpanel initialization code before the queue of tracking events.
|
41
|
-
end
|
42
|
-
elsif is_ajax_request? && is_html_response?
|
43
|
-
part.insert(0, render_event_tracking_scripts) unless queue.empty?
|
44
|
-
elsif is_ajax_request? && is_javascript_response?
|
45
|
-
part.insert(0, render_event_tracking_scripts(false)) unless queue.empty?
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def update_content_length!
|
51
|
-
new_size = 0
|
52
|
-
@response.each{|part| new_size += part.bytesize}
|
53
|
-
@headers.merge!("Content-Length" => new_size.to_s)
|
54
|
-
end
|
55
|
-
|
56
|
-
def is_regular_request?
|
57
|
-
!is_ajax_request?
|
58
|
-
end
|
59
|
-
|
60
|
-
def is_ajax_request?
|
61
|
-
@env.has_key?("HTTP_X_REQUESTED_WITH") && @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
|
62
|
-
end
|
63
|
-
|
64
|
-
def is_html_response?
|
65
|
-
@headers["Content-Type"].include?("text/html") if @headers.has_key?("Content-Type")
|
66
|
-
end
|
67
|
-
|
68
|
-
def is_javascript_response?
|
69
|
-
@headers["Content-Type"].include?("text/javascript") if @headers.has_key?("Content-Type")
|
70
|
-
end
|
71
|
-
|
72
|
-
def is_trackable_response?
|
73
|
-
return false if @status == 302
|
74
|
-
return false if @env.has_key?("HTTP_SKIP_MIXPANEL_MIDDLEWARE")
|
75
|
-
is_html_response? || is_javascript_response?
|
76
|
-
end
|
77
|
-
|
78
|
-
def render_mixpanel_scripts
|
79
|
-
<<-EOT
|
80
|
-
<!-- start Mixpanel -->
|
81
|
-
<script type="text/javascript">
|
82
|
-
(function(c,a){window.mixpanel=a;var b,d,h,e;b=c.createElement("script");
|
83
|
-
b.type="text/javascript";b.async=!0;b.src=("https:"===c.location.protocol?"https:":"http:")+
|
84
|
-
'//cdn.mxpnl.com/libs/mixpanel-2.1.min.js';d=c.getElementsByTagName("script")[0];
|
85
|
-
d.parentNode.insertBefore(b,d);a._i=[];a.init=function(b,c,f){function d(a,b){
|
86
|
-
var c=b.split(".");2==c.length&&(a=a[c[0]],b=c[1]);a[b]=function(){a.push([b].concat(
|
87
|
-
Array.prototype.slice.call(arguments,0)))}}var g=a;"undefined"!==typeof f?g=a[f]=[]:
|
88
|
-
f="mixpanel";g.people=g.people||[];h=['disable','track','track_pageview','track_links',
|
89
|
-
'track_forms','register','register_once','unregister','identify','name_tag',
|
90
|
-
'set_config','people.identify','people.set','people.increment'];for(e=0;e<h.length;e++)d(g,h[e]);
|
91
|
-
a._i.push([b,c,f])};a.__SV=1.1;})(document,window.mixpanel||[]);
|
92
|
-
|
93
|
-
mixpanel.init("#{@token}");
|
94
|
-
mixpanel.set_config(#{@options[:config].to_json});
|
95
|
-
</script>
|
96
|
-
<!-- end Mixpanel -->
|
97
|
-
EOT
|
98
|
-
end
|
99
|
-
|
100
|
-
def delete_event_queue!
|
101
|
-
if @options[:persist]
|
102
|
-
(@env['rack.session']).delete('mixpanel_events')
|
103
|
-
else
|
104
|
-
@env.delete('mixpanel_events')
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def queue
|
109
|
-
if @options[:persist]
|
110
|
-
return [] if !(@env['rack.session']).has_key?('mixpanel_events') || @env['rack.session']['mixpanel_events'].empty?
|
111
|
-
@env['rack.session']['mixpanel_events']
|
112
|
-
else
|
113
|
-
return [] if !@env.has_key?('mixpanel_events') || @env['mixpanel_events'].empty?
|
114
|
-
@env['mixpanel_events']
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def merge_queue!
|
119
|
-
present_hash = {}
|
120
|
-
special_events = ['identify', 'name_tag', 'people.set', 'register']
|
121
|
-
queue.uniq!
|
122
|
-
|
123
|
-
queue.reverse_each do |item|
|
124
|
-
is_special = special_events.include?(item[0])
|
125
|
-
if present_hash[item[0]] and is_special
|
126
|
-
queue.delete(item)
|
127
|
-
else
|
128
|
-
present_hash[item[0]] = true if is_special
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def render_event_tracking_scripts(include_script_tag=true)
|
134
|
-
return "" if queue.empty?
|
135
|
-
|
136
|
-
output = queue.map {|type, arguments| %(mixpanel.#{type}(#{arguments.join(', ')});) }.join("\n")
|
137
|
-
output = "try {#{output}} catch(err) {}"
|
138
|
-
|
139
|
-
include_script_tag ? "<script type='text/javascript'>#{output}</script>" : output
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'thread'
|
3
|
-
|
4
|
-
module Mixpanel
|
5
|
-
class Tracker
|
6
|
-
class Subprocess
|
7
|
-
Q = Queue.new
|
8
|
-
ENDMARKER = Object.new
|
9
|
-
|
10
|
-
Thread.abort_on_exception = true
|
11
|
-
producer = Thread.new do
|
12
|
-
STDIN.each_line() do |url|
|
13
|
-
STDERR.puts("Dropped: #{url}") && next if Q.length > 10000
|
14
|
-
Q << url
|
15
|
-
end
|
16
|
-
Q << ENDMARKER
|
17
|
-
end
|
18
|
-
|
19
|
-
loop do
|
20
|
-
url = Q.pop
|
21
|
-
break if(url == ENDMARKER)
|
22
|
-
url.chomp!
|
23
|
-
next if(url.empty?) #for testing
|
24
|
-
open(url).read
|
25
|
-
end
|
26
|
-
producer.join
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Mixpanel do
|
4
|
-
context "Deprecated initialization mode" do
|
5
|
-
it "should not allow to initialize the class as the old way" do
|
6
|
-
lambda do
|
7
|
-
mixpanel = Mixpanel.new(MIX_PANEL_TOKEN, @env = {"REMOTE_ADDR" => "127.0.0.1"})
|
8
|
-
end.should raise_error(NoMethodError)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|