mixpanel_client 1.0.1 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -11,6 +11,7 @@ tmtags
11
11
  .\#*
12
12
 
13
13
  ## VIM
14
+ *.swo
14
15
  *.swp
15
16
 
16
17
  ## PROJECT::GENERAL
data/README.md CHANGED
@@ -7,27 +7,35 @@ Ruby access to the [Mixpanel](http://mixpanel.com/) web analytics tool.
7
7
 
8
8
  gem install mixpanel_client
9
9
 
10
-
11
10
  ## Usage
12
11
 
13
12
  require 'rubygems'
14
13
  require 'mixpanel_client'
15
14
 
16
- client = MixpanelClient.new('api_key' => 'changeme', 'api_secret' => 'changeme')
15
+ client = Mixpanel::Client.new('api_key' => 'changeme', 'api_secret' => 'changeme')
17
16
 
18
17
  data = client.request do
19
- resource 'events/retention'
18
+ resource 'events/properties'
20
19
  event '["test-event"]'
20
+ name 'hello'
21
+ values '["uno", "dos"]'
21
22
  type 'general'
22
23
  unit 'hour'
23
24
  interval 24
24
- bucket 'test'
25
+ limit 5
26
+ bucket 'kicked'
25
27
  end
26
28
 
27
29
  puts data.inspect
28
30
 
29
31
  ## Changelog
30
32
 
33
+ ### 2.0.0.beta1
34
+ * Reverted to namespacing via module name because it's a better practice.
35
+ I.e. Use `Mixpanel::Client` instead of `MixpanelClient`.
36
+ * Added 'values' as an optional parameter
37
+ * `gem install mixpanel_client --pre`
38
+
31
39
  ### 1.0.1
32
40
  * Minor housekeeping and organizing
33
41
  * Refactored specs
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby -Ku
2
+
3
+ # Mixpanel API Ruby Client Library
4
+ #
5
+ # Copyright (c) 2009+ Keolo Keagy
6
+ # See LICENSE for details.
7
+ #
8
+ # Inspired by the official mixpanel php and python libraries.
9
+ # http://mixpanel.com/api/docs/guides/api/
10
+
11
+ require 'cgi'
12
+ require 'digest/md5'
13
+ require 'open-uri'
14
+ require 'json' unless defined?(JSON)
15
+
16
+ # Ruby library for the mixpanel.com web service
17
+ module Mixpanel
18
+ class Client
19
+ BASE_URI = 'http://mixpanel.com/api'
20
+ API_VERSION = '2.0'
21
+
22
+ # The mixpanel client can be used to easily consume data through the mixpanel API
23
+ OPTIONS = [:resource, :event, :funnel, :name, :type, :unit, :interval, :limit, :format, :bucket, :values]
24
+ attr_reader :uri
25
+ attr_accessor :api_key, :api_secret
26
+
27
+ OPTIONS.each do |option|
28
+ class_eval "
29
+ def #{option}(arg=nil)
30
+ arg ? @#{option} = arg : @#{option}
31
+ end
32
+ "
33
+ end
34
+
35
+ def initialize(config)
36
+ @api_key = config['api_key']
37
+ @api_secret = config['api_secret']
38
+ end
39
+
40
+ def params
41
+ OPTIONS.inject({}) do |params, param|
42
+ option = send(param)
43
+ params.merge!(param => option) if param != :resource && !option.nil?
44
+ params
45
+ end
46
+ end
47
+
48
+ def request(&options)
49
+ reset_options
50
+ instance_eval(&options)
51
+ @uri = URI.mixpanel(resource, normalize_params(params))
52
+ response = URI.get(@uri)
53
+ to_hash(response)
54
+ end
55
+
56
+ def normalize_params(params)
57
+ params.merge!(
58
+ :api_key => @api_key,
59
+ :expire => Time.now.to_i + 600 # Grant this request 10 minutes
60
+ ).merge!(:sig => generate_signature(params))
61
+ end
62
+
63
+ def generate_signature(args)
64
+ Digest::MD5.hexdigest(args.map{|key,val| "#{key}=#{val}"}.sort.join + api_secret)
65
+ end
66
+
67
+ def to_hash(data)
68
+ if @format == 'csv'
69
+ data
70
+ else
71
+ JSON.parse(data)
72
+ end
73
+ end
74
+
75
+ def reset_options
76
+ (OPTIONS - [:resource]).each do |option|
77
+ eval "remove_instance_variable(:@#{option}) if defined?(@#{option})"
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,4 @@
1
+ # Define exceptions for this library
2
+ module Mixpanel
3
+ class URI::HTTPError < StandardError; end
4
+ end
@@ -9,12 +9,9 @@
9
9
  # http://mixpanel.com/api/docs/guides/api/
10
10
 
11
11
  # URI related helpers
12
- class MixpanelClient::URI
13
- # Create an http error class for us to use
14
- class HTTPError < StandardError; end
15
-
12
+ class Mixpanel::URI
16
13
  def self.mixpanel(resource, params)
17
- File.join([MixpanelClient::BASE_URI, MixpanelClient::API_VERSION, resource.to_s]) + "?#{self.encode(params)}"
14
+ File.join([Mixpanel::Client::BASE_URI, Mixpanel::Client::API_VERSION, resource.to_s]) + "?#{self.encode(params)}"
18
15
  end
19
16
 
20
17
  def self.encode(params)
@@ -0,0 +1,6 @@
1
+ # Set version number for mixpanel_client
2
+ module Mixpanel
3
+ class Client
4
+ VERSION = '2.0.0.beta1'
5
+ end
6
+ end
@@ -1,2 +1,3 @@
1
- require "#{File.dirname(__FILE__)}/mixpanel_client/mixpanel_client"
2
- require "#{File.dirname(__FILE__)}/mixpanel_client/uri"
1
+ require "#{File.dirname(__FILE__)}/mixpanel/client"
2
+ require "#{File.dirname(__FILE__)}/mixpanel/uri"
3
+ require "#{File.dirname(__FILE__)}/mixpanel/exceptions"
@@ -1,10 +1,10 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path('../lib', __FILE__)
3
- require 'mixpanel_client/version'
3
+ require 'mixpanel/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'mixpanel_client'
7
- s.version = MixpanelClient::VERSION
7
+ s.version = Mixpanel::Client::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ['Keolo Keagy']
10
10
  s.email = ['keolo@dreampointmedia.com']
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ['lib']
21
21
 
22
- s.add_development_dependency('rspec', '>=2.5.0')
23
- s.add_development_dependency('webmock', '>=1.6.2')
22
+ s.add_development_dependency('rspec', '>=2.5.0')
23
+ s.add_development_dependency('webmock', '>=1.6.2')
24
24
  s.add_development_dependency('metric_fu', '>=2.1.1')
25
25
  end
@@ -6,7 +6,7 @@ describe 'External calls to mixpanel' do
6
6
  before :all do
7
7
  config = YAML.load_file(File.dirname(__FILE__) + '/../../config/mixpanel.yml')
8
8
  config.should_not be_nil
9
- @client = MixpanelClient.new(config)
9
+ @client = Mixpanel::Client.new(config)
10
10
  end
11
11
 
12
12
  context 'when requesting events' do
@@ -16,7 +16,7 @@ describe 'External calls to mixpanel' do
16
16
  resource 'events'
17
17
  end
18
18
  }
19
- data.should raise_error(MixpanelClient::URI::HTTPError)
19
+ data.should raise_error(Mixpanel::URI::HTTPError)
20
20
  end
21
21
 
22
22
  it 'should return events' do
@@ -1,10 +1,10 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
- describe MixpanelClient do
3
+ describe Mixpanel::Client do
4
4
  before :all do
5
5
  config = {'api_key' => 'test', 'api_secret' => 'test'}
6
- @client = MixpanelClient.new(config)
7
- @uri = Regexp.escape(MixpanelClient::BASE_URI)
6
+ @client = Mixpanel::Client.new(config)
7
+ @uri = Regexp.escape(Mixpanel::Client::BASE_URI)
8
8
  end
9
9
 
10
10
  context 'when making an invalid request' do
@@ -86,15 +86,16 @@ describe MixpanelClient do
86
86
  event '["test-event"]'
87
87
  funnel 'down-the-rabbit-hole'
88
88
  name 'ricky-bobby'
89
- type 'tall-dark-handsome'
89
+ type 'A'
90
90
  unit 'hour'
91
91
  interval 24
92
92
  limit 5
93
93
  format 'csv'
94
94
  bucket 'list'
95
+ values '["tiger", "blood"]'
95
96
  end
96
97
 
97
- MixpanelClient::OPTIONS.each do |option|
98
+ Mixpanel::Client::OPTIONS.each do |option|
98
99
  @client.send(option).should_not be_nil
99
100
  end
100
101
 
@@ -102,7 +103,7 @@ describe MixpanelClient do
102
103
  resource 'events/properties/top'
103
104
  end
104
105
 
105
- (MixpanelClient::OPTIONS - [:resource]).each do |option|
106
+ (Mixpanel::Client::OPTIONS - [:resource]).each do |option|
106
107
  @client.send(option).should be_nil
107
108
  end
108
109
  end
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ WebMock.allow_net_connect!
4
+
5
+ describe 'External calls to mixpanel' do
6
+ before :all do
7
+ config = YAML.load_file(File.dirname(__FILE__) + '/../../config/mixpanel.yml')
8
+ config.should_not be_nil
9
+ @client = Mixpanel::Client.new(config)
10
+ end
11
+
12
+ context 'when requesting event properties' do
13
+ it 'should raise an error for bad requests' do
14
+ data = lambda {
15
+ @client.request do
16
+ resource 'properties'
17
+ end
18
+ }
19
+ data.should raise_error(Mixpanel::URI::HTTPError)
20
+ end
21
+
22
+ it 'should return events' do
23
+ data = @client.request do
24
+ resource 'events/properties'
25
+ event '["test-event"]'
26
+ name 'hello'
27
+ values '["uno", "dos"]'
28
+ type 'general'
29
+ unit 'hour'
30
+ interval 24
31
+ limit 5
32
+ bucket 'kicked'
33
+ end
34
+ data.should_not be_a Exception
35
+ end
36
+ end
37
+ end
@@ -1,29 +1,29 @@
1
1
  # coding: utf-8
2
2
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
 
4
- describe MixpanelClient::URI do
4
+ describe Mixpanel::URI do
5
5
  describe '.mixpanel' do
6
6
  it 'should return a properly formatted mixpanel uri as a string (without an endpoint)' do
7
7
  resource, params = ['events', {:c => 'see', :a => 'ey'}]
8
- MixpanelClient::URI.mixpanel(resource, params).should == 'http://mixpanel.com/api/2.0/events?a=ey&c=see'
8
+ Mixpanel::URI.mixpanel(resource, params).should == 'http://mixpanel.com/api/2.0/events?a=ey&c=see'
9
9
  end
10
10
  it 'should return a properly formatted mixpanel uri as a string (with an endpoint)' do
11
11
  resource, params = ['events/top', {:c => 'see', :a => 'ey'}]
12
- MixpanelClient::URI.mixpanel(resource, params).should == 'http://mixpanel.com/api/2.0/events/top?a=ey&c=see'
12
+ Mixpanel::URI.mixpanel(resource, params).should == 'http://mixpanel.com/api/2.0/events/top?a=ey&c=see'
13
13
  end
14
14
  end
15
15
 
16
16
  describe '.encode' do
17
17
  it 'should return a string with url encoded values.' do
18
18
  params = {:hey => '!@#$%^&*()\/"Ü', :soo => "hëllö?"}
19
- MixpanelClient::URI.encode(params).should == 'hey=%21%40%23%24%25%5E%26%2A%28%29%5C%2F%22%C3%9C&soo=h%C3%ABll%C3%B6%3F'
19
+ Mixpanel::URI.encode(params).should == 'hey=%21%40%23%24%25%5E%26%2A%28%29%5C%2F%22%C3%9C&soo=h%C3%ABll%C3%B6%3F'
20
20
  end
21
21
  end
22
22
 
23
23
  describe '.get' do
24
24
  it 'should return a string response' do
25
25
  stub_request(:get, 'http://example.com').to_return(:body => 'something')
26
- MixpanelClient::URI.get('http://example.com').should == 'something'
26
+ Mixpanel::URI.get('http://example.com').should == 'something'
27
27
  end
28
28
  end
29
29
  end
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixpanel_client
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
5
- prerelease:
4
+ hash: 62196449
5
+ prerelease: 6
6
6
  segments:
7
- - 1
7
+ - 2
8
+ - 0
8
9
  - 0
10
+ - beta
9
11
  - 1
10
- version: 1.0.1
12
+ version: 2.0.0.beta1
11
13
  platform: ruby
12
14
  authors:
13
15
  - Keolo Keagy
@@ -15,7 +17,7 @@ autorequire:
15
17
  bindir: bin
16
18
  cert_chain: []
17
19
 
18
- date: 2011-03-14 00:00:00 -07:00
20
+ date: 2011-05-18 00:00:00 -07:00
19
21
  default_executable:
20
22
  dependencies:
21
23
  - !ruby/object:Gem::Dependency
@@ -84,13 +86,15 @@ files:
84
86
  - README.md
85
87
  - Rakefile
86
88
  - config/mixpanel.template.yml
89
+ - lib/mixpanel/client.rb
90
+ - lib/mixpanel/exceptions.rb
91
+ - lib/mixpanel/uri.rb
92
+ - lib/mixpanel/version.rb
87
93
  - lib/mixpanel_client.rb
88
- - lib/mixpanel_client/mixpanel_client.rb
89
- - lib/mixpanel_client/uri.rb
90
- - lib/mixpanel_client/version.rb
91
94
  - mixpanel_client.gemspec
92
95
  - spec/mixpanel_client/events_externalspec.rb
93
96
  - spec/mixpanel_client/mixpanel_client_spec.rb
97
+ - spec/mixpanel_client/properties_externalspec.rb
94
98
  - spec/mixpanel_client/uri_spec.rb
95
99
  - spec/spec_helper.rb
96
100
  has_rdoc: true
@@ -114,12 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
118
  required_rubygems_version: !ruby/object:Gem::Requirement
115
119
  none: false
116
120
  requirements:
117
- - - ">="
121
+ - - ">"
118
122
  - !ruby/object:Gem::Version
119
- hash: 3
123
+ hash: 25
120
124
  segments:
121
- - 0
122
- version: "0"
125
+ - 1
126
+ - 3
127
+ - 1
128
+ version: 1.3.1
123
129
  requirements: []
124
130
 
125
131
  rubyforge_project: mixpanel_client
@@ -130,5 +136,6 @@ summary: Ruby Mixpanel API Client Library
130
136
  test_files:
131
137
  - spec/mixpanel_client/events_externalspec.rb
132
138
  - spec/mixpanel_client/mixpanel_client_spec.rb
139
+ - spec/mixpanel_client/properties_externalspec.rb
133
140
  - spec/mixpanel_client/uri_spec.rb
134
141
  - spec/spec_helper.rb
@@ -1,79 +0,0 @@
1
- #!/usr/bin/env ruby -Ku
2
-
3
- # Mixpanel API Ruby Client Library
4
- #
5
- # Copyright (c) 2009+ Keolo Keagy
6
- # See LICENSE for details.
7
- #
8
- # Inspired by the official mixpanel php and python libraries.
9
- # http://mixpanel.com/api/docs/guides/api/
10
-
11
- require 'cgi'
12
- require 'digest/md5'
13
- require 'open-uri'
14
- require 'json' unless defined?(JSON)
15
-
16
- # Ruby library for the mixpanel.com web service
17
- class MixpanelClient
18
- BASE_URI = 'http://mixpanel.com/api'
19
- API_VERSION = '2.0'
20
-
21
- # The mixpanel client can be used to easily consume data through the mixpanel API
22
- OPTIONS = [:resource, :event, :funnel, :name, :type, :unit, :interval, :limit, :format, :bucket]
23
- attr_reader :uri
24
- attr_accessor :api_key, :api_secret
25
-
26
- OPTIONS.each do |option|
27
- class_eval "
28
- def #{option}(arg=nil)
29
- arg ? @#{option} = arg : @#{option}
30
- end
31
- "
32
- end
33
-
34
- def initialize(config)
35
- @api_key = config['api_key']
36
- @api_secret = config['api_secret']
37
- end
38
-
39
- def params
40
- OPTIONS.inject({}) do |params, param|
41
- option = send(param)
42
- params.merge!(param => option) if param != :resource && !option.nil?
43
- params
44
- end
45
- end
46
-
47
- def request(&options)
48
- reset_options
49
- instance_eval(&options)
50
- @uri = URI.mixpanel(resource, normalize_params(params))
51
- response = URI.get(@uri)
52
- to_hash(response)
53
- end
54
-
55
- def normalize_params(params)
56
- params.merge!(
57
- :api_key => @api_key,
58
- :expire => Time.now.to_i + 600 # Grant this request 10 minutes
59
- ).merge!(:sig => generate_signature(params))
60
- end
61
-
62
- def generate_signature(args)
63
- Digest::MD5.hexdigest(args.map{|key,val| "#{key}=#{val}"}.sort.join + api_secret)
64
- end
65
-
66
- def to_hash(data)
67
- if @format == 'csv'
68
- data
69
- else
70
- JSON.parse(data)
71
- end
72
- end
73
-
74
- def reset_options
75
- (OPTIONS - [:resource]).each do |option|
76
- eval "remove_instance_variable(:@#{option}) if defined?(@#{option})"
77
- end
78
- end
79
- end
@@ -1,3 +0,0 @@
1
- class MixpanelClient
2
- VERSION = '1.0.1'
3
- end