mixpanel_client 3.1.4 → 4.0.0

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 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