mixpanel_client 3.1.4 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ad60587553d1e52a0c6d6a1ec10979df8cc8631
4
+ data.tar.gz: 7c41a327214234103fe8d4c55176f77d5f1e1263
5
+ SHA512:
6
+ metadata.gz: 276355241d2ca211363a21065ab30b30e48a2d97edbef1f13e92b797393f14c46ae276e8f8ce48706bc300beadc968c98d7cb47e19d577932c0dfc2246abda4c
7
+ data.tar.gz: 778fa6fce160a6b2092177f11165e71823cf4348c3bea51e75b6bd037f25f8ce1bc09caadca64af91deaf3a8d4080654ab5522c93e26243558eab7714132f7cb
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ # For now we're ignoring rules in the following file. We should gradually
2
+ # remove rules over time so that we don't need this file anymore.
3
+ inherit_from: rubocop-todo.yml
4
+
5
+ AllCops:
6
+ Includes:
7
+ - Rakefile
8
+ Excludes:
9
+ - bin/**
data/.rvmrc CHANGED
@@ -6,5 +6,5 @@ rvm_gemset_create_on_use_flag=1
6
6
  rvm_project_rvmrc_default=1
7
7
 
8
8
  # Use rvm with a specific version of ruby and gemset
9
- rvm use ruby-1.9.3-p392
10
- rvm gemset use mixpanel_client_1.9.3-p392
9
+ rvm use ruby-2.0.0-p195
10
+ rvm gemset use mixpanel_client_2.0.0-p195
data/Rakefile CHANGED
@@ -23,8 +23,8 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
23
23
  spec.rcov = true
24
24
  end
25
25
 
26
- task :spec
27
- task :default => :spec
26
+ task :spec
27
+ task default: :spec
28
28
 
29
29
  require 'rdoc/task'
30
30
  Rake::RDocTask.new do |rdoc|
data/changelog.md ADDED
@@ -0,0 +1,70 @@
1
+ ### v4.0.0
2
+ * Dropped support for Ruby 1.8.x
3
+ * Code cleanup via rubocop
4
+
5
+ ### v3.1.4
6
+ * Updated docs
7
+ * Updated to latest typhoeus gem
8
+
9
+ ### v3.1.3
10
+ * Added support for the import API.
11
+ * Allow setting of custom expiry.
12
+
13
+ ### v3.1.2
14
+ * Gem updates
15
+
16
+ ### v3.1.1
17
+ * Avoid overriding the arg of client.request
18
+ * Allow retrieving the request_uri of a Mixpanel request
19
+
20
+ ### v3.1.0
21
+ * Parallel requests option.
22
+
23
+ ### v3.0.0
24
+ * NOTE: This version breaks backwards compatibility.
25
+ * Use a regular ruby hash instead of metaprogramming for mixpanel options.
26
+
27
+ ### v2.2.3
28
+ * Added some more options.
29
+
30
+ ### v2.2.2
31
+ * Added some more options.
32
+
33
+ ### v2.2.1
34
+ * Added support for the raw data export API.
35
+
36
+ ### v2.2.0
37
+ * BASE_URI is now https.
38
+ * Changed funnel to funnel_id.
39
+
40
+ ### v2.1.0
41
+ * Updated json dependency to 1.6.
42
+
43
+ ### v2.0.2
44
+ * Added timezone to available options.
45
+ * All exceptions can be caught under Mixpanel::Error.
46
+
47
+ ### v2.0.1
48
+ * Added options used in segmentation resources.
49
+
50
+ ### v2.0.0
51
+ * Manually tested compatibility with Mixpanel gem.
52
+
53
+ ### v2.0.0.beta2
54
+ * Added JSON to gemspec for ruby versions less than 1.9.
55
+
56
+ ### v2.0.0.beta1
57
+ * Reverted to namespacing via module name because it's a better practice.
58
+ I.e. Use `Mixpanel::Client` instead of `MixpanelClient`.
59
+ * Added 'values' as an optional parameter
60
+ * `gem install mixpanel_client --pre`
61
+
62
+ ### v1.0.1
63
+ * Minor housekeeping and organizing
64
+ * Refactored specs
65
+
66
+ ### v1.0.0
67
+ * Changed "Mixpanel" class name to "MixpanelClient" to prevent naming collision in other
68
+ libraries. [a710a84e8ba4b6f018b7](https://github.com/keolo/mixpanel_client/commit/a710a84e8ba4b6f018b7404ab9fabc8f08b4a4f3)
69
+
70
+
@@ -44,19 +44,28 @@ module Mixpanel
44
44
  # })
45
45
  #
46
46
  # @resource [String] mixpanel api resource endpoint
47
- # @options [Hash] options variables used to make a specific request for mixpanel data
47
+ # @options [Hash] options variables used to make a specific request for
48
+ # mixpanel data
48
49
  # @return [JSON, String] mixpanel response as a JSON object or CSV string
49
50
  def request(resource, options)
50
51
  @uri = request_uri(resource, options)
51
- if @parallel
52
- parallel_request = prepare_parallel_request
53
- hydra.queue parallel_request
54
- parallel_request
55
- else
56
- response = URI.get(@uri)
57
- response = %Q|[#{response.split("\n").join(',')}]| if %w(export import).include?(resource)
58
- Utils.to_hash(response, @format)
52
+ @parallel ? make_parallel_request : make_normal_request(resource)
53
+ end
54
+
55
+ def make_parallel_request
56
+ parallel_request = prepare_parallel_request
57
+ hydra.queue parallel_request
58
+ parallel_request
59
+ end
60
+
61
+ def make_normal_request(resource)
62
+ response = URI.get(@uri)
63
+
64
+ if %w(export import).include?(resource)
65
+ response = %Q([#{response.split("\n").join(',')}])
59
66
  end
67
+
68
+ Utils.to_hash(response, @format)
60
69
  end
61
70
 
62
71
  # Return mixpanel URI to the data
@@ -74,30 +83,41 @@ module Mixpanel
74
83
  # })
75
84
  #
76
85
  # @resource [String] mixpanel api resource endpoint
77
- # @options [Hash] options variables used to make a specific request for mixpanel data
86
+ # @options [Hash] options variables used to make a specific request for
87
+ # mixpanel data
78
88
  # @return [JSON, String] mixpanel response as a JSON object or CSV string
79
89
  def request_uri(resource, options)
80
90
  @format = options[:format] || :json
81
91
  URI.mixpanel(resource, normalize_options(options))
82
92
  end
83
93
 
94
+ # rubocop:disable MethodLength
84
95
  def prepare_parallel_request
85
96
  request = ::Typhoeus::Request.new(@uri)
97
+
86
98
  request.on_complete do |response|
87
99
  if response.success?
88
100
  Utils.to_hash(response.body, @format)
89
101
  elsif response.timed_out?
90
- raise TimeoutError
102
+ fail TimeoutError
91
103
  elsif response.code == 0
92
104
  # Could not get an http response, something's wrong.
93
- raise HTTPError, response.curl_error_message
105
+ fail HTTPError, response.curl_error_message
94
106
  else
95
107
  # Received a non-successful http response.
96
- raise HTTPError, response.body.present? ? JSON.parse(response.body)['error'] : response.code.to_s
108
+ if response.body && response.body != ''
109
+ error_message = JSON.parse(response.body)['error']
110
+ else
111
+ error_message = response.code.to_s
112
+ end
113
+
114
+ fail HTTPError, error_message
97
115
  end
98
116
  end
117
+
99
118
  request
100
119
  end
120
+ # rubocop:enable MethodLength
101
121
 
102
122
  def run_parallel_requests
103
123
  hydra.run
@@ -111,14 +131,15 @@ module Mixpanel
111
131
 
112
132
  # Return a hash of options along with defaults and a generated signature
113
133
  #
114
- # @return [Hash] collection of options including defaults and generated signature
134
+ # @return [Hash] collection of options including defaults and generated
135
+ # signature
115
136
  def normalize_options(options)
116
137
  normalized_options = options.dup
117
138
  normalized_options.merge!(
118
- :format => @format,
119
- :api_key => @api_key,
120
- :expire => options[:expire] ? options[:expire].to_i : Time.now.to_i + 600
121
- ).merge!(:sig => Utils.generate_signature(normalized_options, @api_secret))
139
+ format: @format,
140
+ api_key: @api_key,
141
+ expire: options[:expire] ? options[:expire].to_i : Time.now.to_i + 600
142
+ ).merge!(sig: Utils.generate_signature(normalized_options, @api_secret))
122
143
  end
123
144
 
124
145
  def self.base_uri_for_resource(resource)
data/lib/mixpanel/uri.rb CHANGED
@@ -11,11 +11,11 @@ module Mixpanel
11
11
  class URI
12
12
  def self.mixpanel(resource, params)
13
13
  base = Mixpanel::Client.base_uri_for_resource(resource)
14
- "#{File.join([base, resource.to_s])}?#{self.encode(params)}"
14
+ "#{File.join([base, resource.to_s])}?#{encode(params)}"
15
15
  end
16
16
 
17
17
  def self.encode(params)
18
- params.map{|key,val| "#{key}=#{CGI.escape(val.to_s)}"}.sort.join('&')
18
+ params.map { |key, val| "#{key}=#{CGI.escape(val.to_s)}" }.sort.join('&')
19
19
  end
20
20
 
21
21
  def self.get(uri)
@@ -9,12 +9,24 @@
9
9
  module Mixpanel
10
10
  # Utility methods for Mixpanel::Client
11
11
  class Client
12
+ # Mixpanel API Ruby Client Library
13
+ #
14
+ # Utility helpers
15
+ #
16
+ # Copyright (c) 2009+ Keolo Keagy
17
+ # See LICENSE for details
12
18
  module Utils
13
- # Return a string composed of hashed values specified by the mixpanel data API
19
+ # Return a string composed of hashed values specified by the mixpanel
20
+ # data API
14
21
  #
15
22
  # @return [String] md5 hash signature required by mixpanel data API
16
23
  def self.generate_signature(args, api_secret)
17
- Digest::MD5.hexdigest(args.map{|key,val| "#{key}=#{val}"}.sort.join + api_secret)
24
+ Digest::MD5.hexdigest(
25
+ args.map { |key, val| "#{key}=#{val}" }
26
+ .sort
27
+ .join +
28
+ api_secret
29
+ )
18
30
  end
19
31
 
20
32
  # Return a JSON object or a string depending on a given format
@@ -10,6 +10,6 @@ module Mixpanel
10
10
  # Return metrics from Mixpanel Data API
11
11
  class Client
12
12
  # Mixpanel::Client library version
13
- VERSION = '3.1.4'
13
+ VERSION = '4.0.0'
14
14
  end
15
15
  end
File without changes
data/manual_test/basic.rb CHANGED
@@ -4,15 +4,23 @@ require 'rubygems'
4
4
  require 'mixpanel_client'
5
5
  require 'yaml'
6
6
 
7
- config = YAML.load_file(File.dirname(__FILE__) + '/../config/mixpanel.yml')['mixpanel']
7
+ config = YAML.load_file(File.join(
8
+ File.dirname(__FILE__),
9
+ '..',
10
+ 'config',
11
+ 'mixpanel.yml'
12
+ ))['mixpanel']
8
13
 
9
- client = Mixpanel::Client.new({api_key: config['api_key'], api_secret: config['api_secret']})
14
+ client = Mixpanel::Client.new(
15
+ api_key: config[:api_key],
16
+ api_secret: config[:api_secret]
17
+ )
10
18
 
11
- data = client.request('events/properties', {
12
- event: '["test-event"]',
13
- type: 'general',
14
- unit: 'hour',
15
- name: 'test'
16
- })
19
+ data = client.request('events/properties',
20
+ event: '["test-event"]',
21
+ type: 'general',
22
+ unit: 'hour',
23
+ name: 'test'
24
+ )
17
25
 
18
26
  puts data.inspect
@@ -5,21 +5,28 @@ require 'mixpanel_client'
5
5
  require 'yaml'
6
6
  require 'typhoeus'
7
7
 
8
- config = YAML.load_file(File.dirname(__FILE__) + '/../config/mixpanel.yml')['mixpanel']
9
-
10
- client = Mixpanel::Client.new({:api_key => config['api_key'], :api_secret => config['api_secret'], :parallel => true})
11
-
12
- f = client.request('events/top', {
13
- :type => 'general'
14
- })
15
-
16
-
17
- s = client.request('events/names', {
18
- :type => 'general'
19
- })
8
+ config = YAML.load_file(File.join(
9
+ File.dirname(__FILE__),
10
+ '..',
11
+ 'config',
12
+ 'mixpanel.yml'
13
+ ))['mixpanel']
14
+
15
+ client = Mixpanel::Client.new(
16
+ api_key: config[:api_key],
17
+ api_secret: config[:api_secret],
18
+ parallel: true
19
+ )
20
+
21
+ f = client.request('events/top',
22
+ type: 'general'
23
+ )
24
+
25
+ s = client.request('events/names',
26
+ type: 'general'
27
+ )
20
28
 
21
29
  client.run_parallel_requests
22
30
 
23
31
  puts f.response.handled_response.inspect
24
32
  puts s.response.handled_response.inspect
25
-
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.version = Mixpanel::Client::VERSION
9
9
  s.platform = Gem::Platform::RUBY
10
10
  s.authors = ['Keolo Keagy']
11
- s.email = ['keolo@dreampointmedia.com']
11
+ s.email = ['keolo@kea.gy']
12
12
  s.homepage = 'http://github.com/keolo/mixpanel_client'
13
13
  s.summary = %q{Ruby Mixpanel API Client Library}
14
14
  s.description = %q{Simple ruby client interface to the Mixpanel API.}
@@ -21,11 +21,13 @@ Gem::Specification.new do |s|
21
21
  s.require_paths = ['lib']
22
22
  s.add_runtime_dependency('json', '~> 1.6') if RUBY_VERSION < '1.9'
23
23
  s.add_runtime_dependency('typhoeus', '~> 0.6.7')
24
- s.add_development_dependency('bundler', '>=1.2')
25
- s.add_development_dependency('rake', '>=0.9.2.2')
26
- s.add_development_dependency('rdoc', '>=3.11')
24
+ s.add_development_dependency('bundler', '>=1.5.3')
25
+ s.add_development_dependency('rake', '>=10.1.1')
26
+ s.add_development_dependency('rdoc', '>=4.1.1')
27
27
  s.add_development_dependency('rspec', '>=2.5.0')
28
- s.add_development_dependency('webmock', '>=1.9.0')
28
+ s.add_development_dependency('webmock', '>=1.17.4')
29
29
  s.add_development_dependency('pry', '>=0.9.12.6')
30
+ s.add_development_dependency('pry-byebug', '>=1.3.2') if RUBY_VERSION >= '2.0'
31
+ s.add_development_dependency('pry-stack_explorer', '>=0.4.9')
30
32
  s.add_development_dependency('rubocop', '>=0.19.0')
31
33
  end
@@ -115,71 +115,8 @@ Create tag v2.0.2 and build and push mixpanel_client-2.0.2.gem to Rubygems
115
115
 
116
116
 
117
117
  ## Changelog
118
+ [Changelog](changelog.md)
118
119
 
119
- ### v3.1.4
120
- * Updated docs
121
- * Updated to latest typhoeus gem
122
-
123
- ### v3.1.3
124
- * Added support for the import API.
125
- * Allow setting of custom expiry.
126
-
127
- ### v3.1.2
128
- * Gem updates
129
-
130
- ### v3.1.1
131
- * Avoid overriding the arg of client.request
132
- * Allow retrieving the request_uri of a Mixpanel request
133
-
134
- ### v3.1.0
135
- * Parallel requests option.
136
-
137
- ### v3.0.0
138
- * NOTE: This version breaks backwards compatibility.
139
- * Use a regular ruby hash instead of metaprogramming for mixpanel options.
140
-
141
- ### v2.2.3
142
- * Added some more options.
143
-
144
- ### v2.2.2
145
- * Added some more options.
146
-
147
- ### v2.2.1
148
- * Added support for the raw data export API.
149
-
150
- ### v2.2.0
151
- * BASE_URI is now https.
152
- * Changed funnel to funnel_id.
153
-
154
- ### v2.1.0
155
- * Updated json dependency to 1.6.
156
-
157
- ### v2.0.2
158
- * Added timezone to available options.
159
- * All exceptions can be caught under Mixpanel::Error.
160
-
161
- ### v2.0.1
162
- * Added options used in segmentation resources.
163
-
164
- ### v2.0.0
165
- * Manually tested compatibility with Mixpanel gem.
166
-
167
- ### v2.0.0.beta2
168
- * Added JSON to gemspec for ruby versions less than 1.9.
169
-
170
- ### v2.0.0.beta1
171
- * Reverted to namespacing via module name because it's a better practice.
172
- I.e. Use `Mixpanel::Client` instead of `MixpanelClient`.
173
- * Added 'values' as an optional parameter
174
- * `gem install mixpanel_client --pre`
175
-
176
- ### v1.0.1
177
- * Minor housekeeping and organizing
178
- * Refactored specs
179
-
180
- ### v1.0.0
181
- * Changed "Mixpanel" class name to "MixpanelClient" to prevent naming collision in other
182
- libraries. [a710a84e8ba4b6f018b7](https://github.com/keolo/mixpanel_client/commit/a710a84e8ba4b6f018b7404ab9fabc8f08b4a4f3)
183
120
 
184
121
  ## Collaborators and Maintainers
185
122
  Feel free to add your name and link here.
data/rubocop-todo.yml ADDED
@@ -0,0 +1,10 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2014-03-15 09:50:10 -0700 using RuboCop version 0.19.0.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 60
9
+ #LineLength:
10
+ # Max: 262
@@ -4,89 +4,96 @@ WebMock.allow_net_connect!
4
4
 
5
5
  describe 'External calls to mixpanel' do
6
6
  before :all do
7
- config = YAML.load_file(File.dirname(__FILE__) + '/../../config/mixpanel.yml')['mixpanel']
7
+ config = YAML.load_file(File.join(
8
+ File.dirname(__FILE__),
9
+ '..',
10
+ '..',
11
+ 'config',
12
+ 'mixpanel.yml'
13
+ ))['mixpanel']
14
+
8
15
  config.should_not be_nil
9
16
  @client = Mixpanel::Client.new(config)
10
17
  end
11
18
 
12
19
  context 'when requesting events' do
13
20
  it 'should raise an error for bad requests' do
14
- data = lambda {
21
+ data = lambda do
15
22
  @client.request('events', {})
16
- }
23
+ end
17
24
  data.should raise_error(Mixpanel::HTTPError)
18
25
  end
19
26
 
20
27
  it 'should return events' do
21
- data = @client.request('events', {
22
- :event => '["test-event"]',
23
- :type => 'general',
24
- :unit => 'hour',
25
- :interval => 24
26
- })
28
+ data = @client.request('events',
29
+ event: '["test-event"]',
30
+ type: 'general',
31
+ unit: 'hour',
32
+ interval: 24
33
+ )
27
34
  data.should_not be_a Exception
28
35
  end
29
36
 
30
37
  it 'should return events in csv format' do
31
- data = @client.request('events', {
32
- :event => '["test-event"]',
33
- :type => 'general',
34
- :unit => 'hour',
35
- :interval => 24,
36
- :format => 'csv'
37
- })
38
+ data = @client.request('events',
39
+ event: '["test-event"]',
40
+ type: 'general',
41
+ unit: 'hour',
42
+ interval: 24,
43
+ format: 'csv'
44
+ )
38
45
  data.should_not be_a Exception
39
46
  end
40
47
 
41
48
  it 'should return events with optional bucket' do
42
- data = @client.request('events', {
43
- :event => '["test-event"]',
44
- :type => 'general',
45
- :unit => 'hour',
46
- :interval => 24,
47
- :bucket => 'test'
48
- })
49
+ data = @client.request('events',
50
+ event: '["test-event"]',
51
+ type: 'general',
52
+ unit: 'hour',
53
+ interval: 24,
54
+ bucket: 'test'
55
+ )
49
56
  data.should_not be_a Exception
50
57
  end
51
58
 
52
59
  it 'should return top events' do
53
- data = @client.request('events/top', {
54
- :type => 'general',
55
- :limit => 10
56
- })
60
+ data = @client.request('events/top',
61
+ type: 'general',
62
+ limit: 10
63
+ )
57
64
  data.should_not be_a Exception
58
65
  end
59
66
 
60
67
  it 'should return names' do
61
- data = @client.request('events/names', {
62
- :type => 'general',
63
- :unit => 'hour',
64
- :interval => 24,
65
- :limit => 10
66
- })
68
+ data = @client.request('events/names',
69
+ type: 'general',
70
+ unit: 'hour',
71
+ interval: 24,
72
+ limit: 10
73
+ )
67
74
  data.should_not be_a Exception
68
75
  end
69
76
 
70
77
  it 'should return retention' do
71
78
  pending 'Retention now has its own endpoint.'
72
- data = @client.request('events/retention', {
73
- :event => '["test-event"]',
74
- :type => 'general',
75
- :unit => 'hour',
76
- :interval => 24
77
- })
79
+ data = @client.request('events/retention',
80
+ event: '["test-event"]',
81
+ type: 'general',
82
+ unit: 'hour',
83
+ interval: 24
84
+ )
78
85
  data.should_not be_a Exception
79
86
  end
80
87
 
81
88
  it 'should return retention in csv format' do
82
89
  pending 'Retention now has its own endpoint.'
83
- data = @client.request('events/retention', {
84
- :event => '["test-event"]',
85
- :type => 'general',
86
- :unit => 'hour',
87
- :interval => 24,
88
- :format => 'csv'
89
- })
90
+ data = @client.request('events/retention',
91
+ event: '["test-event"]',
92
+ type: 'general',
93
+ unit: 'hour',
94
+ interval: 24,
95
+ format: 'csv'
96
+ )
90
97
  data.should_not be_a Exception
91
98
  end
92
99
  end