mixpanel_client 4.1.4 → 4.1.5
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/changelog.md +4 -0
- data/config/mixpanel.template.yml +2 -2
- data/lib/mixpanel/client.rb +7 -11
- data/lib/mixpanel/uri.rb +2 -2
- data/lib/mixpanel/version.rb +1 -1
- data/manual_test/basic.rb +5 -5
- data/manual_test/parallel.rb +6 -5
- data/readme.md +1 -0
- data/spec/mixpanel_client/events_externalspec.rb +21 -21
- data/spec/mixpanel_client/mixpanel_client_spec.rb +19 -19
- data/spec/mixpanel_client/properties_externalspec.rb +6 -6
- data/spec/mixpanel_client/uri_spec.rb +11 -9
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 276a112f1f0c83a360953fb404392ba687bbaa5d
|
4
|
+
data.tar.gz: 1c0a5f3b4d551b3529282a449ffff42f52d1fc0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6416ca4b99f358b9eeeecdeee63932299e83251b68e38b80d5e50196cdd3809c627d525515b483b2d0267d3694961a6539ba76ad3de8714c5b944e5878bfef9
|
7
|
+
data.tar.gz: b241d59a34c755e505fb28cb63501f8da0414fa66fcfe2be27d14be536b7b17f359a62ad880da8a4b7936ec893b08196f9fed441f057fc2c51aaa4c9263bf73d
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/changelog.md
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
mixpanel:
|
2
|
-
api_key: 'changeme'
|
3
|
-
api_secret: 'changeme'
|
2
|
+
:api_key: 'changeme'
|
3
|
+
:api_secret: 'changeme'
|
data/lib/mixpanel/client.rb
CHANGED
@@ -13,7 +13,7 @@ module Mixpanel
|
|
13
13
|
DATA_URI = 'https://data.mixpanel.com/api/2.0'
|
14
14
|
IMPORT_URI = 'https://api.mixpanel.com'
|
15
15
|
|
16
|
-
attr_reader
|
16
|
+
attr_reader :uri
|
17
17
|
attr_accessor :api_key, :api_secret, :parallel, :timeout
|
18
18
|
|
19
19
|
# Configure the client
|
@@ -26,8 +26,8 @@ module Mixpanel
|
|
26
26
|
def initialize(config)
|
27
27
|
@api_key = config[:api_key]
|
28
28
|
@api_secret = config[:api_secret]
|
29
|
-
@parallel = config[:parallel]
|
30
|
-
@timeout = config[:timeout]
|
29
|
+
@parallel = config[:parallel] || false
|
30
|
+
@timeout = config[:timeout] || nil
|
31
31
|
|
32
32
|
fail ConfigurationError if @api_key.nil? || @api_secret.nil?
|
33
33
|
end
|
@@ -64,10 +64,10 @@ module Mixpanel
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def make_normal_request(resource)
|
67
|
-
response = URI.get(@uri, @timeout)
|
67
|
+
response = URI.get(@uri, @timeout, @api_secret)
|
68
68
|
|
69
69
|
if %w(export import).include?(resource) && @format != 'raw'
|
70
|
-
response = %
|
70
|
+
response = %([#{response.split("\n").join(',')}])
|
71
71
|
end
|
72
72
|
|
73
73
|
Utils.to_hash(response, @format)
|
@@ -92,14 +92,14 @@ module Mixpanel
|
|
92
92
|
# @options [Hash] options variables used to make a specific request for
|
93
93
|
# mixpanel data
|
94
94
|
# @return [JSON, String] mixpanel response as a JSON object or CSV string
|
95
|
-
def request_uri(resource, options = {}
|
95
|
+
def request_uri(resource, options = {})
|
96
96
|
@format = options[:format] || :json
|
97
97
|
URI.mixpanel(resource, normalize_options(options))
|
98
98
|
end
|
99
99
|
|
100
100
|
# rubocop:disable MethodLength
|
101
101
|
def prepare_parallel_request
|
102
|
-
request = ::Typhoeus::Request.new(@uri)
|
102
|
+
request = ::Typhoeus::Request.new(@uri, userpwd: "#{@api_secret}:")
|
103
103
|
|
104
104
|
request.on_complete do |response|
|
105
105
|
if response.success?
|
@@ -145,12 +145,8 @@ module Mixpanel
|
|
145
145
|
normalized_options
|
146
146
|
.merge!(
|
147
147
|
format: @format,
|
148
|
-
api_key: @api_key,
|
149
148
|
expire: request_expires_at(normalized_options)
|
150
149
|
)
|
151
|
-
.merge!(
|
152
|
-
sig: Utils.generate_signature(normalized_options, @api_secret)
|
153
|
-
)
|
154
150
|
end
|
155
151
|
|
156
152
|
def request_expires_at(options)
|
data/lib/mixpanel/uri.rb
CHANGED
@@ -18,8 +18,8 @@ module Mixpanel
|
|
18
18
|
params.map { |key, val| "#{key}=#{CGI.escape(val.to_s)}" }.sort.join('&')
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.get(uri, timeout)
|
22
|
-
::URI.parse(uri).read(read_timeout: timeout)
|
21
|
+
def self.get(uri, timeout, secret)
|
22
|
+
::URI.parse(uri).read(read_timeout: timeout, http_basic_authentication: [secret, nil])
|
23
23
|
rescue OpenURI::HTTPError => error
|
24
24
|
raise HTTPError, JSON.parse(error.io.read)['error']
|
25
25
|
end
|
data/lib/mixpanel/version.rb
CHANGED
data/manual_test/basic.rb
CHANGED
@@ -5,10 +5,10 @@ require 'mixpanel_client'
|
|
5
5
|
require 'yaml'
|
6
6
|
|
7
7
|
config = YAML.load_file(File.join(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
File.dirname(__FILE__),
|
9
|
+
'..',
|
10
|
+
'config',
|
11
|
+
'mixpanel.yml'
|
12
12
|
))['mixpanel']
|
13
13
|
|
14
14
|
client = Mixpanel::Client.new(
|
@@ -21,6 +21,6 @@ data = client.request('events/properties',
|
|
21
21
|
type: 'general',
|
22
22
|
unit: 'hour',
|
23
23
|
name: 'test'
|
24
|
-
)
|
24
|
+
)
|
25
25
|
|
26
26
|
puts data.inspect
|
data/manual_test/parallel.rb
CHANGED
@@ -5,11 +5,12 @@ require 'mixpanel_client'
|
|
5
5
|
require 'yaml'
|
6
6
|
require 'typhoeus'
|
7
7
|
|
8
|
-
config = YAML.load_file(
|
9
|
-
File.
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
config = YAML.load_file(
|
9
|
+
File.join(
|
10
|
+
File.dirname(__FILE__),
|
11
|
+
'..',
|
12
|
+
'config',
|
13
|
+
'mixpanel.yml'
|
13
14
|
))['mixpanel']
|
14
15
|
|
15
16
|
client = Mixpanel::Client.new(
|
data/readme.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/mixpanel_client)
|
4
4
|
[](https://codeclimate.com/github/keolo/mixpanel_client)
|
5
|
+
[ ](https://codeship.com/projects/159479)
|
5
6
|
|
6
7
|
Ruby access to the [Mixpanel](http://mixpanel.com/) web analytics tool.
|
7
8
|
|
@@ -5,14 +5,14 @@ WebMock.allow_net_connect!
|
|
5
5
|
describe 'External calls to mixpanel' do
|
6
6
|
before :all do
|
7
7
|
config = YAML.load_file(File.join(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
File.dirname(__FILE__),
|
9
|
+
'..',
|
10
|
+
'..',
|
11
|
+
'config',
|
12
|
+
'mixpanel.yml'
|
13
13
|
))['mixpanel']
|
14
14
|
|
15
|
-
config.
|
15
|
+
expect(config).to_not be_nil
|
16
16
|
@client = Mixpanel::Client.new(config)
|
17
17
|
end
|
18
18
|
|
@@ -21,7 +21,7 @@ describe 'External calls to mixpanel' do
|
|
21
21
|
data = lambda do
|
22
22
|
@client.request('events', {})
|
23
23
|
end
|
24
|
-
data.
|
24
|
+
expect(data).to raise_error(Mixpanel::HTTPError)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should return events' do
|
@@ -30,8 +30,8 @@ describe 'External calls to mixpanel' do
|
|
30
30
|
type: 'general',
|
31
31
|
unit: 'hour',
|
32
32
|
interval: 24
|
33
|
-
|
34
|
-
data.
|
33
|
+
)
|
34
|
+
expect(data).to_not be_a Exception
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'should return events in csv format' do
|
@@ -41,8 +41,8 @@ describe 'External calls to mixpanel' do
|
|
41
41
|
unit: 'hour',
|
42
42
|
interval: 24,
|
43
43
|
format: 'csv'
|
44
|
-
|
45
|
-
data.
|
44
|
+
)
|
45
|
+
expect(data).to_not be_a Exception
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'should return events with optional bucket' do
|
@@ -52,16 +52,16 @@ describe 'External calls to mixpanel' do
|
|
52
52
|
unit: 'hour',
|
53
53
|
interval: 24,
|
54
54
|
bucket: 'test'
|
55
|
-
|
56
|
-
data.
|
55
|
+
)
|
56
|
+
expect(data).to_not be_a Exception
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'should return top events' do
|
60
60
|
data = @client.request('events/top',
|
61
61
|
type: 'general',
|
62
62
|
limit: 10
|
63
|
-
|
64
|
-
data.
|
63
|
+
)
|
64
|
+
expect(data).to_not be_a Exception
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'should return names' do
|
@@ -70,8 +70,8 @@ describe 'External calls to mixpanel' do
|
|
70
70
|
unit: 'hour',
|
71
71
|
interval: 24,
|
72
72
|
limit: 10
|
73
|
-
|
74
|
-
data.
|
73
|
+
)
|
74
|
+
expect(data).to_not be_a Exception
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'should return retention' do
|
@@ -81,8 +81,8 @@ describe 'External calls to mixpanel' do
|
|
81
81
|
type: 'general',
|
82
82
|
unit: 'hour',
|
83
83
|
interval: 24
|
84
|
-
|
85
|
-
data.
|
84
|
+
)
|
85
|
+
expect(data).to_not be_a Exception
|
86
86
|
end
|
87
87
|
|
88
88
|
it 'should return retention in csv format' do
|
@@ -93,8 +93,8 @@ describe 'External calls to mixpanel' do
|
|
93
93
|
unit: 'hour',
|
94
94
|
interval: 24,
|
95
95
|
format: 'csv'
|
96
|
-
|
97
|
-
data.
|
96
|
+
)
|
97
|
+
expect(data).to_not be_a Exception
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
@@ -12,33 +12,33 @@ describe Mixpanel::Client do
|
|
12
12
|
|
13
13
|
context 'when initializing a new Mixpanel::Client' do
|
14
14
|
it 'should set a parallel option as false by default' do
|
15
|
-
Mixpanel::Client.new(
|
15
|
+
expect(Mixpanel::Client.new(
|
16
16
|
api_key: 'test_key',
|
17
17
|
api_secret: 'test_secret'
|
18
|
-
).parallel.
|
18
|
+
).parallel).to eq(false)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'should be able to set a parallel option when passed' do
|
22
|
-
Mixpanel::Client.new(
|
22
|
+
expect(Mixpanel::Client.new(
|
23
23
|
api_key: 'test_key',
|
24
24
|
api_secret: 'test_secret',
|
25
25
|
parallel: true
|
26
|
-
).parallel.
|
26
|
+
).parallel).to eq(true)
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'should set a timeout option as nil by default' do
|
30
|
-
Mixpanel::Client.new(
|
30
|
+
expect(Mixpanel::Client.new(
|
31
31
|
api_key: 'test_key',
|
32
32
|
api_secret: 'test_secret'
|
33
|
-
).timeout.
|
33
|
+
).timeout).to be_nil
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should be able to set a timeout option when passed' do
|
37
|
-
Mixpanel::Client.new(
|
37
|
+
expect(Mixpanel::Client.new(
|
38
38
|
api_key: 'test_key',
|
39
39
|
api_secret: 'test_secret',
|
40
40
|
timeout: 3
|
41
|
-
).timeout.
|
41
|
+
).timeout).to eql(3)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -79,7 +79,7 @@ describe Mixpanel::Client do
|
|
79
79
|
)
|
80
80
|
end
|
81
81
|
|
82
|
-
data.
|
82
|
+
expect(data).to raise_error(ArgumentError)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -99,7 +99,7 @@ describe Mixpanel::Client do
|
|
99
99
|
interval: 24
|
100
100
|
)
|
101
101
|
|
102
|
-
data.
|
102
|
+
expect(data).to eq(
|
103
103
|
'data' => {
|
104
104
|
'series' => [],
|
105
105
|
'values' => {}
|
@@ -119,7 +119,7 @@ describe Mixpanel::Client do
|
|
119
119
|
api_key: 'test_key'
|
120
120
|
)
|
121
121
|
|
122
|
-
data.
|
122
|
+
expect(data).to eq([1])
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'should work with an endpoint, method, and type' do
|
@@ -135,7 +135,7 @@ describe Mixpanel::Client do
|
|
135
135
|
type: 'general'
|
136
136
|
)
|
137
137
|
|
138
|
-
data.
|
138
|
+
expect(data).to eq(
|
139
139
|
'events' => [],
|
140
140
|
'type' => 'general'
|
141
141
|
)
|
@@ -183,7 +183,7 @@ describe Mixpanel::Client do
|
|
183
183
|
|
184
184
|
specify 'Mixpanel::URI instance should receive the custom expiry time in
|
185
185
|
the options[:expiry] instead of 600s' do
|
186
|
-
Mixpanel::URI.
|
186
|
+
expect(Mixpanel::URI).to receive(:mixpanel) do |*args|
|
187
187
|
args.pop[:expire].should eq expiry.to_i
|
188
188
|
true
|
189
189
|
end.and_return(fake_url)
|
@@ -220,7 +220,7 @@ describe Mixpanel::Client do
|
|
220
220
|
interval: 24
|
221
221
|
)
|
222
222
|
|
223
|
-
data.
|
223
|
+
expect(data).to be_a Typhoeus::Request
|
224
224
|
end
|
225
225
|
|
226
226
|
describe '#hydra' do
|
@@ -331,9 +331,9 @@ describe Mixpanel::Client do
|
|
331
331
|
)
|
332
332
|
|
333
333
|
sorted_signature = Mixpanel::Client::Utils.generate_signature(
|
334
|
-
|
335
|
-
|
336
|
-
|
334
|
+
args_alpha_sorted,
|
335
|
+
@client.api_secret
|
336
|
+
)
|
337
337
|
|
338
338
|
unsorted_signature.should eq sorted_signature
|
339
339
|
end
|
@@ -341,10 +341,10 @@ describe Mixpanel::Client do
|
|
341
341
|
|
342
342
|
describe '#to_hash' do
|
343
343
|
it 'should return a ruby hash given json as a string' do
|
344
|
-
Mixpanel::Client::Utils.to_hash(
|
344
|
+
expect(Mixpanel::Client::Utils.to_hash(
|
345
345
|
'{"a" : "ey", "b" : "bee"}',
|
346
346
|
:json
|
347
|
-
).
|
347
|
+
)).to eq(
|
348
348
|
'a' => 'ey',
|
349
349
|
'b' => 'bee'
|
350
350
|
)
|
@@ -5,11 +5,11 @@ WebMock.allow_net_connect!
|
|
5
5
|
describe 'External calls to mixpanel' do
|
6
6
|
before :all do
|
7
7
|
config = YAML.load_file(File.join(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
File.dirname(__FILE__),
|
9
|
+
'..',
|
10
|
+
'..',
|
11
|
+
'config',
|
12
|
+
'mixpanel.yml'
|
13
13
|
))['mixpanel']
|
14
14
|
|
15
15
|
config.should_not be_nil
|
@@ -34,7 +34,7 @@ describe 'External calls to mixpanel' do
|
|
34
34
|
interval: 24,
|
35
35
|
limit: 5,
|
36
36
|
bucket: 'kicked'
|
37
|
-
|
37
|
+
)
|
38
38
|
data.should_not be_a Exception
|
39
39
|
end
|
40
40
|
end
|
@@ -5,7 +5,8 @@ describe Mixpanel::URI do
|
|
5
5
|
describe '.mixpanel' do
|
6
6
|
it 'should return a properly formatted mixpanel uri as a string (without an
|
7
7
|
endpoint)' do
|
8
|
-
resource
|
8
|
+
resource = 'events'
|
9
|
+
params = { c: 'see', a: 'ey' }
|
9
10
|
|
10
11
|
Mixpanel::URI.mixpanel(resource, params).should eq(
|
11
12
|
"#{Mixpanel::Client::BASE_URI}/events?a=ey&c=see"
|
@@ -14,7 +15,8 @@ describe Mixpanel::URI do
|
|
14
15
|
|
15
16
|
it 'should return a properly formatted mixpanel uri as a string (with an
|
16
17
|
endpoint)' do
|
17
|
-
resource
|
18
|
+
resource = 'events/top'
|
19
|
+
params = { c: 'see', a: 'ey' }
|
18
20
|
|
19
21
|
Mixpanel::URI.mixpanel(resource, params).should eq(
|
20
22
|
"#{Mixpanel::Client::BASE_URI}/events/top?a=ey&c=see"
|
@@ -23,7 +25,8 @@ describe Mixpanel::URI do
|
|
23
25
|
|
24
26
|
it 'should return a uri with a different endpoint when doing a raw data
|
25
27
|
export' do
|
26
|
-
resource
|
28
|
+
resource = 'export'
|
29
|
+
params = { c: 'see', a: 'ey' }
|
27
30
|
|
28
31
|
Mixpanel::URI.mixpanel(resource, params).should eq(
|
29
32
|
"#{Mixpanel::Client::DATA_URI}/export?a=ey&c=see"
|
@@ -32,7 +35,8 @@ describe Mixpanel::URI do
|
|
32
35
|
|
33
36
|
it 'should return a uri with a the correct endpoint when doing an
|
34
37
|
import' do
|
35
|
-
resource
|
38
|
+
resource = 'import'
|
39
|
+
params = { c: 'see', a: 'ey' }
|
36
40
|
Mixpanel::URI.mixpanel(resource, params).should eq(
|
37
41
|
"#{Mixpanel::Client::IMPORT_URI}/import?a=ey&c=see"
|
38
42
|
)
|
@@ -53,17 +57,16 @@ describe Mixpanel::URI do
|
|
53
57
|
it 'should return a string response' do
|
54
58
|
stub_request(:get, 'http://example.com').to_return(body: 'something')
|
55
59
|
|
56
|
-
Mixpanel::URI.get('http://example.com', nil).should eq 'something'
|
60
|
+
Mixpanel::URI.get('http://example.com', nil, 'secret').should eq 'something'
|
57
61
|
end
|
58
62
|
|
59
63
|
context 'when timeout is not nil' do
|
60
|
-
|
61
64
|
context 'when the request times out' do
|
62
65
|
it 'should return a timeout error' do
|
63
66
|
stub_request(:get, 'http://example.com').to_timeout
|
64
67
|
|
65
68
|
expect do
|
66
|
-
Mixpanel::URI.get('http://example.com', 3)
|
69
|
+
Mixpanel::URI.get('http://example.com', 3, 'secret')
|
67
70
|
end.to raise_error Timeout::Error
|
68
71
|
end
|
69
72
|
end
|
@@ -72,10 +75,9 @@ describe Mixpanel::URI do
|
|
72
75
|
it 'should return a string response' do
|
73
76
|
stub_request(:get, 'http://example.com').to_return(body: 'something')
|
74
77
|
|
75
|
-
Mixpanel::URI.get('http://example.com', 3).should eq 'something'
|
78
|
+
Mixpanel::URI.get('http://example.com', 3, 'secret').should eq 'something'
|
76
79
|
end
|
77
80
|
end
|
78
|
-
|
79
81
|
end
|
80
82
|
end
|
81
83
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixpanel_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keolo Keagy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: typhoeus
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- ".document"
|
161
161
|
- ".gitignore"
|
162
162
|
- ".rubocop.yml"
|
163
|
+
- ".ruby-version"
|
163
164
|
- ".rvmrc"
|
164
165
|
- Gemfile
|
165
166
|
- Rakefile
|