mixpanel_client 0.4.1 → 0.5.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.
- data/.gitignore +1 -0
- data/README.md +45 -4
- data/Rakefile +8 -0
- data/VERSION +1 -1
- data/config/mixpanel.template.yml +3 -0
- data/lib/mixpanel_client.rb +55 -14
- data/mixpanel_client.gemspec +11 -4
- data/spec/events_externalspec.rb +101 -0
- data/spec/mixpanel_client_spec.rb +91 -12
- data/spec/spec_helper.rb +2 -1
- data/test/manual.rb +58 -7
- data/test/test.rb +36 -0
- metadata +22 -4
data/.gitignore
CHANGED
data/README.md
CHANGED
|
@@ -1,27 +1,68 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Mixpanel API Client (for API version 2.0)
|
|
2
2
|
|
|
3
3
|
Ruby access to the [Mixpanel](http://mixpanel.com/) web analytics tool.
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
## Installation
|
|
7
|
+
|
|
6
8
|
gem install mixpanel_client
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
## New Usage
|
|
12
|
+
|
|
13
|
+
require 'rubygems'
|
|
14
|
+
require 'mixpanel_client'
|
|
15
|
+
|
|
16
|
+
config = {'api_key' => 'changeme', 'api_secret' => 'changeme'}
|
|
17
|
+
|
|
18
|
+
client = Mixpanel::Client.new(config)
|
|
19
|
+
|
|
20
|
+
# Get all results for 'test-event' in the last 24 hours from the test bucket
|
|
21
|
+
data = client.request do
|
|
22
|
+
resource 'events'
|
|
23
|
+
event '["test-event"]'
|
|
24
|
+
type 'general'
|
|
25
|
+
unit 'hour'
|
|
26
|
+
interval 24
|
|
27
|
+
bucket 'test'
|
|
28
|
+
end
|
|
29
|
+
puts data.inspect
|
|
30
|
+
|
|
31
|
+
# Get the top property names for 'test-event'
|
|
32
|
+
data = client.request do
|
|
33
|
+
resource 'events/properties/top'
|
|
34
|
+
event '["test-event"]'
|
|
35
|
+
type 'general'
|
|
36
|
+
end
|
|
37
|
+
puts data.inspect
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Old Usage (versions prior to 0.5.0)
|
|
41
|
+
|
|
42
|
+
__NOTE: This old usage is deprecated and will be removed in future versions.__
|
|
43
|
+
|
|
9
44
|
require 'rubygems'
|
|
10
|
-
require 'json'
|
|
11
45
|
require 'mixpanel_client'
|
|
12
46
|
|
|
13
47
|
config = {:api_key => 'changeme', :api_secret => 'changeme'}
|
|
14
48
|
|
|
15
49
|
api = Mixpanel::Client.new(config)
|
|
16
50
|
|
|
17
|
-
|
|
51
|
+
# Example without an endpoint
|
|
52
|
+
data = api.request(nil, :events, {
|
|
18
53
|
:event => '["test-event"]',
|
|
19
54
|
:unit => 'hour',
|
|
20
55
|
:interval => 24
|
|
21
56
|
})
|
|
57
|
+
puts data.inspect
|
|
22
58
|
|
|
59
|
+
# Example with an endpoint and method
|
|
60
|
+
data = api.request(:events, :top, {
|
|
61
|
+
:type => 'general'
|
|
62
|
+
})
|
|
23
63
|
puts data.inspect
|
|
24
64
|
|
|
65
|
+
|
|
25
66
|
## Copyright
|
|
26
67
|
|
|
27
68
|
Copyright (c) 2009+ Keolo Keagy. See LICENSE for details.
|
data/Rakefile
CHANGED
|
@@ -13,6 +13,7 @@ begin
|
|
|
13
13
|
gem.authors = ['Keolo Keagy']
|
|
14
14
|
gem.add_development_dependency 'rspec', '>= 1.2.9'
|
|
15
15
|
gem.add_development_dependency 'cucumber', '>= 0'
|
|
16
|
+
gem.add_development_dependency 'webmock', '>= 1.3.5'
|
|
16
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
|
17
18
|
end
|
|
18
19
|
Jeweler::GemcutterTasks.new
|
|
@@ -26,6 +27,13 @@ Spec::Rake::SpecTask.new(:spec) do |spec|
|
|
|
26
27
|
spec.spec_files = FileList['spec/**/*_spec.rb']
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
namespace :spec do
|
|
31
|
+
desc 'Run all tests that depend on external dependencies'
|
|
32
|
+
Spec::Rake::SpecTask.new(:externals) do |t|
|
|
33
|
+
t.spec_files = FileList['spec/**/*_externalspec.rb']
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
29
37
|
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
|
30
38
|
spec.libs << 'lib' << 'spec'
|
|
31
39
|
spec.pattern = 'spec/**/*_spec.rb'
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.5.0
|
data/lib/mixpanel_client.rb
CHANGED
|
@@ -11,34 +11,58 @@
|
|
|
11
11
|
require 'cgi'
|
|
12
12
|
require 'digest/md5'
|
|
13
13
|
require 'open-uri'
|
|
14
|
+
require 'json' unless defined?(JSON)
|
|
14
15
|
|
|
15
16
|
# Ruby library for the mixpanel.com web service
|
|
16
17
|
module Mixpanel
|
|
17
18
|
BASE_URI = 'http://mixpanel.com/api'
|
|
18
19
|
VERSION = '2.0'
|
|
19
20
|
|
|
20
|
-
# The mixpanel client can be used to easily consume data through the
|
|
21
|
-
# mixpanel API.
|
|
21
|
+
# The mixpanel client can be used to easily consume data through the mixpanel API
|
|
22
22
|
class Client
|
|
23
|
+
OPTIONS = [:resource, :event, :funnel, :name, :type, :unit, :interval, :limit, :format, :bucket]
|
|
23
24
|
attr_reader :uri
|
|
24
25
|
attr_accessor :api_key, :api_secret
|
|
25
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
|
+
|
|
26
35
|
def initialize(config)
|
|
27
|
-
@api_key = config[
|
|
28
|
-
@api_secret = config[
|
|
36
|
+
@api_key = config['api_key']
|
|
37
|
+
@api_secret = config['api_secret']
|
|
29
38
|
end
|
|
30
39
|
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
def params
|
|
41
|
+
OPTIONS.inject({}) do |params, param|
|
|
42
|
+
params.merge!(param => send(param)) if param != :resource && !send(param).nil?
|
|
43
|
+
params
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def request(deprecated_endpoint=nil, deprecated_meth=nil, deprecated_params=nil, &options)
|
|
48
|
+
reset_options
|
|
49
|
+
if block_given?
|
|
50
|
+
instance_eval &options
|
|
51
|
+
@uri = URI.mixpanel(resource, normalize_params(params))
|
|
52
|
+
response = URI.get(@uri)
|
|
53
|
+
to_hash(response)
|
|
54
|
+
else
|
|
55
|
+
warn 'This usage is deprecated. Please use the new block form (see README).'
|
|
56
|
+
@uri = URI.deprecated_mixpanel(deprecated_endpoint, deprecated_meth, normalize_params(deprecated_params))
|
|
57
|
+
response = URI.get(@uri)
|
|
58
|
+
to_hash(response)
|
|
59
|
+
end
|
|
35
60
|
end
|
|
36
61
|
|
|
37
62
|
def normalize_params(params)
|
|
38
63
|
params.merge!(
|
|
39
|
-
:api_key => api_key,
|
|
40
|
-
:expire => Time.now.to_i + 600
|
|
41
|
-
:format => :json
|
|
64
|
+
:api_key => @api_key,
|
|
65
|
+
:expire => Time.now.to_i + 600 # Grant this request 10 minutes
|
|
42
66
|
).merge!(:sig => hash_args(params))
|
|
43
67
|
end
|
|
44
68
|
|
|
@@ -47,23 +71,40 @@ module Mixpanel
|
|
|
47
71
|
end
|
|
48
72
|
|
|
49
73
|
def to_hash(data)
|
|
50
|
-
|
|
51
|
-
|
|
74
|
+
if @format == 'csv'
|
|
75
|
+
data
|
|
76
|
+
else
|
|
77
|
+
JSON.parse(data)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def reset_options
|
|
82
|
+
(OPTIONS - [:resource]).each do |option|
|
|
83
|
+
eval "remove_instance_variable(:@#{option}) if defined?(@#{option})"
|
|
84
|
+
end
|
|
52
85
|
end
|
|
53
86
|
end
|
|
54
87
|
|
|
55
88
|
# URI related helpers
|
|
56
89
|
class URI
|
|
57
|
-
|
|
90
|
+
class HTTPError < StandardError; end
|
|
91
|
+
|
|
92
|
+
def self.deprecated_mixpanel(endpoint, meth, params)
|
|
58
93
|
File.join([BASE_URI, VERSION, endpoint.to_s, meth.to_s].reject(&:empty?)) + "?#{self.encode(params)}"
|
|
59
94
|
end
|
|
60
95
|
|
|
96
|
+
def self.mixpanel(resource, params)
|
|
97
|
+
File.join([BASE_URI, VERSION, resource.to_s]) + "?#{self.encode(params)}"
|
|
98
|
+
end
|
|
99
|
+
|
|
61
100
|
def self.encode(params)
|
|
62
101
|
params.map{|key,val| "#{key}=#{CGI.escape(val.to_s)}"}.sort.join('&')
|
|
63
102
|
end
|
|
64
103
|
|
|
65
104
|
def self.get(uri)
|
|
66
105
|
::URI.parse(uri).read
|
|
106
|
+
rescue OpenURI::HTTPError => error
|
|
107
|
+
raise HTTPError, JSON.parse(error.io.read)['error']
|
|
67
108
|
end
|
|
68
109
|
end
|
|
69
110
|
end
|
data/mixpanel_client.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{mixpanel_client}
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.5.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Keolo Keagy"]
|
|
12
|
-
s.date = %q{2010-
|
|
12
|
+
s.date = %q{2010-10-14}
|
|
13
13
|
s.description = %q{Simple ruby client interface to the Mixpanel API.}
|
|
14
14
|
s.email = %q{keolo@dreampointmedia.com}
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -23,11 +23,13 @@ Gem::Specification.new do |s|
|
|
|
23
23
|
"README.md",
|
|
24
24
|
"Rakefile",
|
|
25
25
|
"VERSION",
|
|
26
|
+
"config/mixpanel.template.yml",
|
|
26
27
|
"features/mixpanel_client.feature",
|
|
27
28
|
"features/step_definitions/mixpanel_client_steps.rb",
|
|
28
29
|
"features/support/env.rb",
|
|
29
30
|
"lib/mixpanel_client.rb",
|
|
30
31
|
"mixpanel_client.gemspec",
|
|
32
|
+
"spec/events_externalspec.rb",
|
|
31
33
|
"spec/mixpanel_client_spec.rb",
|
|
32
34
|
"spec/spec.opts",
|
|
33
35
|
"spec/spec_helper.rb"
|
|
@@ -38,9 +40,11 @@ Gem::Specification.new do |s|
|
|
|
38
40
|
s.rubygems_version = %q{1.3.6}
|
|
39
41
|
s.summary = %q{Ruby Mixpanel API Client Library}
|
|
40
42
|
s.test_files = [
|
|
41
|
-
"spec/
|
|
43
|
+
"spec/events_externalspec.rb",
|
|
44
|
+
"spec/mixpanel_client_spec.rb",
|
|
42
45
|
"spec/spec_helper.rb",
|
|
43
|
-
"test/manual.rb"
|
|
46
|
+
"test/manual.rb",
|
|
47
|
+
"test/test.rb"
|
|
44
48
|
]
|
|
45
49
|
|
|
46
50
|
if s.respond_to? :specification_version then
|
|
@@ -50,13 +54,16 @@ Gem::Specification.new do |s|
|
|
|
50
54
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
51
55
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
|
52
56
|
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
|
57
|
+
s.add_development_dependency(%q<webmock>, [">= 1.3.5"])
|
|
53
58
|
else
|
|
54
59
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
|
55
60
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
|
61
|
+
s.add_dependency(%q<webmock>, [">= 1.3.5"])
|
|
56
62
|
end
|
|
57
63
|
else
|
|
58
64
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
|
59
65
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
|
66
|
+
s.add_dependency(%q<webmock>, [">= 1.3.5"])
|
|
60
67
|
end
|
|
61
68
|
end
|
|
62
69
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
|
+
|
|
4
|
+
WebMock.allow_net_connect!
|
|
5
|
+
|
|
6
|
+
describe 'External calls to mixpanel' do
|
|
7
|
+
before :all do
|
|
8
|
+
config = YAML.load_file(File.dirname(__FILE__) + '/../config/mixpanel.yml')
|
|
9
|
+
config.should_not be_nil
|
|
10
|
+
@client = Mixpanel::Client.new(config)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe 'Events' do
|
|
14
|
+
it 'should raise an error for bad requests' do
|
|
15
|
+
data = lambda {
|
|
16
|
+
@client.request do
|
|
17
|
+
resource 'events'
|
|
18
|
+
end
|
|
19
|
+
}
|
|
20
|
+
data.should raise_error(Mixpanel::URI::HTTPError)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should return events' do
|
|
24
|
+
data = @client.request do
|
|
25
|
+
resource 'events'
|
|
26
|
+
event '["test-event"]'
|
|
27
|
+
type 'general'
|
|
28
|
+
unit 'hour'
|
|
29
|
+
interval 24
|
|
30
|
+
end
|
|
31
|
+
data.should_not be_a Exception
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should return events in csv format' do
|
|
35
|
+
data = @client.request do
|
|
36
|
+
resource 'events'
|
|
37
|
+
event '["test-event"]'
|
|
38
|
+
type 'general'
|
|
39
|
+
unit 'hour'
|
|
40
|
+
interval 24
|
|
41
|
+
format 'csv'
|
|
42
|
+
end
|
|
43
|
+
data.should_not be_a Exception
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'should return events with optional bucket' do
|
|
47
|
+
data = @client.request do
|
|
48
|
+
resource 'events'
|
|
49
|
+
event '["test-event"]'
|
|
50
|
+
type 'general'
|
|
51
|
+
unit 'hour'
|
|
52
|
+
interval 24
|
|
53
|
+
bucket 'test'
|
|
54
|
+
end
|
|
55
|
+
data.should_not be_a Exception
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'should return top events' do
|
|
59
|
+
data = @client.request do
|
|
60
|
+
resource 'events/top'
|
|
61
|
+
type 'general'
|
|
62
|
+
limit 10
|
|
63
|
+
end
|
|
64
|
+
data.should_not be_a Exception
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'should return names' do
|
|
68
|
+
data = @client.request do
|
|
69
|
+
resource 'events/names'
|
|
70
|
+
type 'general'
|
|
71
|
+
unit 'hour'
|
|
72
|
+
interval 24
|
|
73
|
+
limit 10
|
|
74
|
+
end
|
|
75
|
+
data.should_not be_a Exception
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'should return retention' do
|
|
79
|
+
data = @client.request do
|
|
80
|
+
resource 'events/retention'
|
|
81
|
+
event '["test-event"]'
|
|
82
|
+
type 'general'
|
|
83
|
+
unit 'hour'
|
|
84
|
+
interval 24
|
|
85
|
+
end
|
|
86
|
+
data.should_not be_a Exception
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'should return retention in csv format' do
|
|
90
|
+
data = @client.request do
|
|
91
|
+
resource 'events/retention'
|
|
92
|
+
event '["test-event"]'
|
|
93
|
+
type 'general'
|
|
94
|
+
unit 'hour'
|
|
95
|
+
interval 24
|
|
96
|
+
format 'csv'
|
|
97
|
+
end
|
|
98
|
+
data.should_not be_a Exception
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -1,24 +1,53 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
|
-
|
|
3
2
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
4
3
|
|
|
5
4
|
describe Mixpanel::Client do
|
|
6
5
|
before :all do
|
|
7
|
-
config = {
|
|
8
|
-
@
|
|
6
|
+
config = {'api_key' => 'test', 'api_secret' => 'test'}
|
|
7
|
+
@client = Mixpanel::Client.new(config)
|
|
8
|
+
@uri = Regexp.escape(Mixpanel::BASE_URI)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe '#request' do
|
|
12
12
|
it 'should return json and convert to a ruby hash' do
|
|
13
|
-
# Stub Mixpanel
|
|
14
|
-
|
|
13
|
+
# Stub Mixpanel request
|
|
14
|
+
stub_request(:get, /^#{@uri}.*/).to_return(:body => '{"legend_size": 0, "data": {"series": [], "values": {}}}')
|
|
15
15
|
|
|
16
|
-
data = @
|
|
16
|
+
data = @client.request(nil, :events, {
|
|
17
17
|
:event => '["test-event"]',
|
|
18
18
|
:unit => 'hour',
|
|
19
19
|
:interval => 24
|
|
20
20
|
})
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
data.should == {"data"=>{"series"=>[], "values"=>{}}, "legend_size"=>0}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'block form' do
|
|
27
|
+
it 'should work without an endpoint' do
|
|
28
|
+
# Stub Mixpanel request
|
|
29
|
+
stub_request(:get, /^#{@uri}.*/).to_return(:body => '{"legend_size": 0, "data": {"series": [], "values": {}}}')
|
|
30
|
+
|
|
31
|
+
# No endpoint
|
|
32
|
+
data = @client.request do
|
|
33
|
+
resource 'events'
|
|
34
|
+
event '["test-event"]'
|
|
35
|
+
unit 'hour'
|
|
36
|
+
interval 24
|
|
37
|
+
end
|
|
38
|
+
data.should == {"data"=>{"series"=>[], "values"=>{}}, "legend_size"=>0}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'should work with an endpoint, method, and type' do
|
|
42
|
+
# Stub Mixpanel request
|
|
43
|
+
stub_request(:get, /^#{@uri}.*/).to_return(:body => '{"events": [], "type": "general"}')
|
|
44
|
+
|
|
45
|
+
# With endpoint
|
|
46
|
+
data = @client.request do
|
|
47
|
+
resource 'events/top'
|
|
48
|
+
type 'general'
|
|
49
|
+
end
|
|
50
|
+
data.should == {"events"=>[], "type"=>"general"}
|
|
22
51
|
end
|
|
23
52
|
end
|
|
24
53
|
|
|
@@ -26,26 +55,69 @@ describe Mixpanel::Client do
|
|
|
26
55
|
it 'should return a hashed string alpha sorted by key names.' do
|
|
27
56
|
args = {:c => 'see', :a => 'aye', :d => 'dee', :b => 'bee'}
|
|
28
57
|
args_alpha_sorted = {:a => 'aye', :b => 'bee', :c => 'see', :d => 'dee'}
|
|
29
|
-
@
|
|
58
|
+
@client.hash_args(args).should == @client.hash_args(args_alpha_sorted)
|
|
30
59
|
end
|
|
31
60
|
end
|
|
32
61
|
|
|
33
62
|
describe '#to_hash' do
|
|
34
63
|
it 'should return a ruby hash given json as a string' do
|
|
35
|
-
@
|
|
64
|
+
@client.to_hash('{"a" : "aye", "b" : "bee"}').should == {'a' => 'aye', 'b' => 'bee'}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe 'resetting options' do
|
|
69
|
+
it 'options should be reset before each request' do
|
|
70
|
+
# Stub Mixpanel request
|
|
71
|
+
stub_request(:get, /^#{@uri}.*/).to_return(:body => '{"events": [], "type": "general"}')
|
|
72
|
+
|
|
73
|
+
@client.request do
|
|
74
|
+
resource 'events'
|
|
75
|
+
event '["test-event"]'
|
|
76
|
+
funnel 'down-the-rabbit-hole'
|
|
77
|
+
name 'ricky-bobby'
|
|
78
|
+
type 'tall-dark-handsome'
|
|
79
|
+
unit 'hour'
|
|
80
|
+
interval 24
|
|
81
|
+
limit 5
|
|
82
|
+
format 'csv'
|
|
83
|
+
bucket 'list'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
Mixpanel::Client::OPTIONS.each do |option|
|
|
87
|
+
@client.send(option).should_not be_nil
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
@client.request do
|
|
91
|
+
resource 'events/properties/top'
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
(Mixpanel::Client::OPTIONS - [:resource]).each do |option|
|
|
95
|
+
@client.send(option).should be_nil
|
|
96
|
+
end
|
|
36
97
|
end
|
|
37
98
|
end
|
|
38
99
|
end
|
|
39
100
|
|
|
40
101
|
describe Mixpanel::URI do
|
|
41
|
-
describe '.
|
|
102
|
+
describe '.deprecated_mixpanel' do
|
|
42
103
|
it 'should return a properly formatted mixpanel uri as a string (without an endpoint)' do
|
|
43
104
|
endpoint, meth, params = [:events, nil, {:c => 'see', :a => 'aye'}]
|
|
44
|
-
Mixpanel::URI.
|
|
105
|
+
Mixpanel::URI.deprecated_mixpanel(endpoint, meth, params).should == 'http://mixpanel.com/api/2.0/events?a=aye&c=see'
|
|
45
106
|
end
|
|
46
107
|
it 'should return a properly formatted mixpanel uri as a string (with an endpoint)' do
|
|
47
108
|
endpoint, meth, params = [:events, :top, {:c => 'see', :a => 'aye'}]
|
|
48
|
-
Mixpanel::URI.
|
|
109
|
+
Mixpanel::URI.deprecated_mixpanel(endpoint, meth, params).should == 'http://mixpanel.com/api/2.0/events/top?a=aye&c=see'
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe '.mixpanel' do
|
|
114
|
+
it 'should return a properly formatted mixpanel uri as a string (without an endpoint)' do
|
|
115
|
+
resource, params = ['events', {:c => 'see', :a => 'aye'}]
|
|
116
|
+
Mixpanel::URI.mixpanel(resource, params).should == 'http://mixpanel.com/api/2.0/events?a=aye&c=see'
|
|
117
|
+
end
|
|
118
|
+
it 'should return a properly formatted mixpanel uri as a string (with an endpoint)' do
|
|
119
|
+
resource, params = ['events/top', {:c => 'see', :a => 'aye'}]
|
|
120
|
+
Mixpanel::URI.mixpanel(resource, params).should == 'http://mixpanel.com/api/2.0/events/top?a=aye&c=see'
|
|
49
121
|
end
|
|
50
122
|
end
|
|
51
123
|
|
|
@@ -55,4 +127,11 @@ describe Mixpanel::URI do
|
|
|
55
127
|
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'
|
|
56
128
|
end
|
|
57
129
|
end
|
|
130
|
+
|
|
131
|
+
describe '.get' do
|
|
132
|
+
it 'should return a string response' do
|
|
133
|
+
stub_request(:get, 'http://example.com').to_return(:body => 'something')
|
|
134
|
+
Mixpanel::URI.get('http://example.com').should == 'something'
|
|
135
|
+
end
|
|
136
|
+
end
|
|
58
137
|
end
|
data/spec/spec_helper.rb
CHANGED
data/test/manual.rb
CHANGED
|
@@ -3,29 +3,80 @@
|
|
|
3
3
|
# Notes:
|
|
4
4
|
# Test URI.mixpanel in browser to see response and error codes.
|
|
5
5
|
#
|
|
6
|
+
# Pushing to rubygems.org
|
|
7
|
+
# rake version:bump:patch
|
|
8
|
+
# git commit ...
|
|
9
|
+
# git push
|
|
10
|
+
# rake release
|
|
6
11
|
|
|
7
12
|
require 'rubygems'
|
|
8
13
|
require "#{File.dirname(__FILE__)}/../lib/mixpanel_client"
|
|
9
14
|
#require 'mixpanel_client'
|
|
10
|
-
require 'json'
|
|
11
15
|
|
|
12
|
-
config = {
|
|
16
|
+
config = {'api_key' => 'e81de686c96261747fdc443d4809c297', 'api_secret' => '201ff82db5f1e8766b0004f0acf8d82e'}
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
client = Mixpanel::Client.new(config)
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
# Block form
|
|
21
|
+
data = client.request do
|
|
22
|
+
resource 'events'
|
|
23
|
+
event '["test-event"]'
|
|
24
|
+
unit 'hour'
|
|
25
|
+
interval 24
|
|
26
|
+
format 'csv'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
puts
|
|
30
|
+
puts client.inspect
|
|
31
|
+
puts data.inspect
|
|
32
|
+
puts
|
|
33
|
+
|
|
34
|
+
# Argument form
|
|
35
|
+
data = client.request(nil, :events, {
|
|
17
36
|
:event => '["test-event"]',
|
|
18
37
|
:unit => 'hour',
|
|
19
38
|
:interval => 24,
|
|
20
39
|
})
|
|
21
40
|
|
|
22
|
-
puts
|
|
41
|
+
puts
|
|
42
|
+
puts client.inspect
|
|
23
43
|
puts data.inspect
|
|
44
|
+
puts
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
# Block form
|
|
47
|
+
data = client.request do
|
|
48
|
+
resource 'events/properties/top'
|
|
49
|
+
type 'general'
|
|
50
|
+
event '["test-event"]'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
puts
|
|
54
|
+
puts client.inspect
|
|
55
|
+
puts data.inspect
|
|
56
|
+
puts
|
|
57
|
+
|
|
58
|
+
# Argument form
|
|
59
|
+
data = client.request(:events, :top, {
|
|
26
60
|
:type => 'general',
|
|
27
61
|
#:format => :csv
|
|
28
62
|
})
|
|
29
63
|
|
|
30
|
-
puts
|
|
64
|
+
puts
|
|
65
|
+
puts client.inspect
|
|
66
|
+
puts data.inspect
|
|
67
|
+
puts
|
|
68
|
+
|
|
69
|
+
# Bucket
|
|
70
|
+
data = client.request do
|
|
71
|
+
resource 'events'
|
|
72
|
+
event '["test-event"]'
|
|
73
|
+
type 'general'
|
|
74
|
+
unit 'hour'
|
|
75
|
+
interval 24
|
|
76
|
+
bucket 'test'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
puts
|
|
80
|
+
puts client.inspect
|
|
31
81
|
puts data.inspect
|
|
82
|
+
puts
|
data/test/test.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# Notes:
|
|
4
|
+
# Test URI.mixpanel in browser to see response and error codes.
|
|
5
|
+
#
|
|
6
|
+
# Pushing to rubygems.org
|
|
7
|
+
# rake version:bump:patch
|
|
8
|
+
# git commit ...
|
|
9
|
+
# git push
|
|
10
|
+
# rake release
|
|
11
|
+
|
|
12
|
+
require 'rubygems'
|
|
13
|
+
require "#{File.dirname(__FILE__)}/../lib/mixpanel_client"
|
|
14
|
+
|
|
15
|
+
config = YAML.load_file "#{File.dirname(__FILE__)}/../config/mixpanel.yml"
|
|
16
|
+
client = Mixpanel::Client.new(config)
|
|
17
|
+
|
|
18
|
+
data = client.request do
|
|
19
|
+
resource 'events'
|
|
20
|
+
event '["test-event"]'
|
|
21
|
+
unit 'hour'
|
|
22
|
+
interval 24
|
|
23
|
+
format 'csv'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
puts client.inspect
|
|
27
|
+
puts data.inspect
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
data = client.request do
|
|
31
|
+
resource 'events/top'
|
|
32
|
+
type 'general'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
puts client.inspect
|
|
36
|
+
puts data.inspect
|
metadata
CHANGED
|
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
|
4
4
|
prerelease: false
|
|
5
5
|
segments:
|
|
6
6
|
- 0
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
version: 0.
|
|
7
|
+
- 5
|
|
8
|
+
- 0
|
|
9
|
+
version: 0.5.0
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Keolo Keagy
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2010-
|
|
17
|
+
date: 2010-10-14 00:00:00 -07:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
@@ -43,6 +43,20 @@ dependencies:
|
|
|
43
43
|
version: "0"
|
|
44
44
|
type: :development
|
|
45
45
|
version_requirements: *id002
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: webmock
|
|
48
|
+
prerelease: false
|
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
segments:
|
|
54
|
+
- 1
|
|
55
|
+
- 3
|
|
56
|
+
- 5
|
|
57
|
+
version: 1.3.5
|
|
58
|
+
type: :development
|
|
59
|
+
version_requirements: *id003
|
|
46
60
|
description: Simple ruby client interface to the Mixpanel API.
|
|
47
61
|
email: keolo@dreampointmedia.com
|
|
48
62
|
executables: []
|
|
@@ -59,11 +73,13 @@ files:
|
|
|
59
73
|
- README.md
|
|
60
74
|
- Rakefile
|
|
61
75
|
- VERSION
|
|
76
|
+
- config/mixpanel.template.yml
|
|
62
77
|
- features/mixpanel_client.feature
|
|
63
78
|
- features/step_definitions/mixpanel_client_steps.rb
|
|
64
79
|
- features/support/env.rb
|
|
65
80
|
- lib/mixpanel_client.rb
|
|
66
81
|
- mixpanel_client.gemspec
|
|
82
|
+
- spec/events_externalspec.rb
|
|
67
83
|
- spec/mixpanel_client_spec.rb
|
|
68
84
|
- spec/spec.opts
|
|
69
85
|
- spec/spec_helper.rb
|
|
@@ -98,6 +114,8 @@ signing_key:
|
|
|
98
114
|
specification_version: 3
|
|
99
115
|
summary: Ruby Mixpanel API Client Library
|
|
100
116
|
test_files:
|
|
117
|
+
- spec/events_externalspec.rb
|
|
101
118
|
- spec/mixpanel_client_spec.rb
|
|
102
119
|
- spec/spec_helper.rb
|
|
103
120
|
- test/manual.rb
|
|
121
|
+
- test/test.rb
|