keen 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/README.md +8 -0
- data/lib/keen.rb +1 -1
- data/lib/keen/client.rb +15 -0
- data/lib/keen/client/querying_methods.rb +40 -2
- data/lib/keen/version.rb +1 -1
- data/spec/integration/api_spec.rb +27 -0
- data/spec/keen/client/querying_methods_spec.rb +24 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be248e41731a4f4e86d99397bc780980e468e643
|
4
|
+
data.tar.gz: 5f673b82043892b20214caa66c872266916a6df9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebe7cd7ba80d155daf102d4e77ec18b595cec2640d58c87aa94b05f7c2fe566bd62e61b391a4a8beffb259f5b8fa3b1bab84de0aa4080ccbf38da4afebd21573
|
7
|
+
data.tar.gz: 5ae089f9bc5ac3993962398c0e31f0e715f00c418f313af7990e614d8bcff61da5230f2c544997d56914af3ede4cc4c155a1e8e94c2493221a894f4fd273a316
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -83,6 +83,8 @@ Next, run an instance of EventMachine. If you're using an EventMachine-based web
|
|
83
83
|
thin or goliath you're already doing this. Otherwise, you'll need to start an EventMachine loop manually as follows:
|
84
84
|
|
85
85
|
```ruby
|
86
|
+
require 'em-http-request'
|
87
|
+
|
86
88
|
Thread.new { EventMachine.run }
|
87
89
|
```
|
88
90
|
|
@@ -116,6 +118,8 @@ Keen.sum("purchases", :target_property => "price") # => 10000
|
|
116
118
|
Keen.minimum("purchases", :target_property => "price") # => 20
|
117
119
|
Keen.maximum("purchases", :target_property => "price") # => 100
|
118
120
|
Keen.average("purchases", :target_property => "price") # => 60
|
121
|
+
Keen.median("purchases", :target_property => "price") # => 60
|
122
|
+
Keen.percentile("purchases", :target_property => "price", :percentile => 90) # => 100
|
119
123
|
|
120
124
|
Keen.sum("purchases", :target_property => "price", :group_by => "item.id") # => [{ "item.id": 123, "result": 240 }, { ... }]
|
121
125
|
|
@@ -283,6 +287,10 @@ EventMachine itself won't do this because it runs in a different thread. Here's
|
|
283
287
|
|
284
288
|
### Changelog
|
285
289
|
|
290
|
+
##### 0.8.2
|
291
|
+
+ Add support for `median` and `percentile` analysis
|
292
|
+
+ Support arrays for extraction `property_names` option
|
293
|
+
|
286
294
|
##### 0.8.1
|
287
295
|
+ Add support for asynchronous batch publishing
|
288
296
|
|
data/lib/keen.rb
CHANGED
data/lib/keen/client.rb
CHANGED
@@ -101,6 +101,8 @@ module Keen
|
|
101
101
|
preprocess_encodables(params)
|
102
102
|
preprocess_timeframe(params)
|
103
103
|
preprocess_group_by(params)
|
104
|
+
preprocess_percentile(params)
|
105
|
+
preprocess_property_names(params)
|
104
106
|
|
105
107
|
query_params = ""
|
106
108
|
params.each do |param, value|
|
@@ -133,6 +135,19 @@ module Keen
|
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
138
|
+
def preprocess_percentile(params)
|
139
|
+
if params.key?(:percentile)
|
140
|
+
params[:percentile] = params[:percentile].to_s
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def preprocess_property_names(params)
|
145
|
+
property_names = params[:property_names]
|
146
|
+
if property_names.is_a?(Array)
|
147
|
+
params[:property_names] = MultiJson.encode(property_names)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
136
151
|
def method_missing(_method, *args, &block)
|
137
152
|
if config = CONFIG[_method.to_sym]
|
138
153
|
if config.is_a?(Proc)
|
@@ -97,6 +97,39 @@ module Keen
|
|
97
97
|
query(__method__, event_collection, params)
|
98
98
|
end
|
99
99
|
|
100
|
+
# Runs a median query.
|
101
|
+
# See detailed documentation here:
|
102
|
+
# https://keen.io/docs/api/reference/#median-resource
|
103
|
+
#
|
104
|
+
# @param event_collection
|
105
|
+
# @param params [Hash] (optional)
|
106
|
+
# target_property (required)
|
107
|
+
# group_by (optional)
|
108
|
+
# timeframe (optional)
|
109
|
+
# interval (optional)
|
110
|
+
# filters (optional) [Array]
|
111
|
+
# timezone (optional)
|
112
|
+
def median(event_collection, params)
|
113
|
+
query(__method__, event_collection, params)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Runs a percentile query.
|
117
|
+
# See detailed documentation here:
|
118
|
+
# https://keen.io/docs/api/reference/#percentile-resource
|
119
|
+
#
|
120
|
+
# @param event_collection
|
121
|
+
# @param params [Hash] (optional)
|
122
|
+
# target_property (required)
|
123
|
+
# percentile (required)
|
124
|
+
# group_by (optional)
|
125
|
+
# timeframe (optional)
|
126
|
+
# interval (optional)
|
127
|
+
# filters (optional) [Array]
|
128
|
+
# timezone (optional)
|
129
|
+
def percentile(event_collection, params)
|
130
|
+
query(__method__, event_collection, params)
|
131
|
+
end
|
132
|
+
|
100
133
|
# Runs a select_unique query.
|
101
134
|
# See detailed documentation here:
|
102
135
|
# https://keen.io/docs/api/reference/#select-unique-resource
|
@@ -161,14 +194,15 @@ module Keen
|
|
161
194
|
private
|
162
195
|
|
163
196
|
def query(query_name, event_collection, params)
|
197
|
+
query_params = clone_params(params)
|
164
198
|
ensure_project_id!
|
165
199
|
ensure_read_key!
|
166
200
|
|
167
201
|
if event_collection
|
168
|
-
|
202
|
+
query_params[:event_collection] = event_collection.to_s
|
169
203
|
end
|
170
204
|
|
171
|
-
query_params = preprocess_params(
|
205
|
+
query_params = preprocess_params(query_params)
|
172
206
|
|
173
207
|
begin
|
174
208
|
response = Keen::HTTP::Sync.new(self.api_url, self.proxy_url).get(
|
@@ -182,6 +216,10 @@ module Keen
|
|
182
216
|
process_response(response.code, response_body)["result"]
|
183
217
|
end
|
184
218
|
|
219
|
+
def clone_params(params)
|
220
|
+
params.dup
|
221
|
+
end
|
222
|
+
|
185
223
|
def api_query_resource_path(analysis_type)
|
186
224
|
"/#{self.api_version}/projects/#{self.project_id}/queries/#{analysis_type}"
|
187
225
|
end
|
data/lib/keen/version.rb
CHANGED
@@ -188,6 +188,15 @@ describe "Keen IO API" do
|
|
188
188
|
Keen.average(event_collection, :target_property => "price").should == 15
|
189
189
|
end
|
190
190
|
|
191
|
+
it "should return a valid median" do
|
192
|
+
Keen.median(event_collection, :target_property => "price").should == 10
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should return a valid percentile" do
|
196
|
+
Keen.percentile(event_collection, :target_property => "price", :percentile => 50).should == 10
|
197
|
+
Keen.percentile(event_collection, :target_property => "price", :percentile => 100).should == 20
|
198
|
+
end
|
199
|
+
|
191
200
|
it "should return a valid select_unique" do
|
192
201
|
results = Keen.select_unique(event_collection, :target_property => "price")
|
193
202
|
results.sort.should == [10, 20].sort
|
@@ -197,6 +206,24 @@ describe "Keen IO API" do
|
|
197
206
|
results = Keen.extraction(event_collection)
|
198
207
|
results.length.should == 2
|
199
208
|
results.all? { |result| result["keen"] }.should be_true
|
209
|
+
results.map { |result| result["price"] }.sort.should == [10, 20]
|
210
|
+
results.map { |result| result["username"] }.sort.should == ["bob", "ted"]
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should return a valid extraction of one property name" do
|
214
|
+
results = Keen.extraction(event_collection, :property_names => "price")
|
215
|
+
results.length.should == 2
|
216
|
+
results.any? { |result| result["keen"] }.should be_false
|
217
|
+
results.map { |result| result["price"] }.sort.should == [10, 20]
|
218
|
+
results.map { |result| result["username"] }.sort.should == [nil, nil]
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should return a valid extraction of more than one property name" do
|
222
|
+
results = Keen.extraction(event_collection, :property_names => ["price", "username"])
|
223
|
+
results.length.should == 2
|
224
|
+
results.any? { |result| result["keen"] }.should be_false
|
225
|
+
results.map { |result| result["price"] }.sort.should == [10, 20]
|
226
|
+
results.map { |result| result["username"] }.sort.should == ["bob", "ted"]
|
200
227
|
end
|
201
228
|
|
202
229
|
it "should return a valid funnel" do
|
@@ -17,7 +17,7 @@ describe Keen::Client do
|
|
17
17
|
describe "querying names" do
|
18
18
|
let(:params) { { :event_collection => "signups" } }
|
19
19
|
|
20
|
-
["minimum", "maximum", "sum", "average", "count", "count_unique", "select_unique", "extraction", "multi_analysis"].each do |query_name|
|
20
|
+
["minimum", "maximum", "sum", "average", "count", "count_unique", "select_unique", "extraction", "multi_analysis", "median", "percentile"].each do |query_name|
|
21
21
|
it "should call keen query passing the query name" do
|
22
22
|
client.should_receive(:query).with(query_name.to_sym, event_collection, params)
|
23
23
|
client.send(query_name, event_collection, params)
|
@@ -75,17 +75,27 @@ describe Keen::Client do
|
|
75
75
|
filter_str = CGI.escape(MultiJson.encode(filters))
|
76
76
|
test_query("&filters=#{filter_str}", :filters => filters)
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
it "should encode a single group by property" do
|
80
80
|
test_query("&group_by=one%20foo", :group_by => "one foo")
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
it "should encode multi-group by properly" do
|
84
84
|
group_by = ["one", "two"]
|
85
85
|
group_by_str = CGI.escape(MultiJson.encode(group_by))
|
86
86
|
test_query("&group_by=#{group_by_str}", :group_by => group_by)
|
87
87
|
end
|
88
88
|
|
89
|
+
it "should encode an array of property names property" do
|
90
|
+
property_names = ["one", "two"]
|
91
|
+
property_names_str = CGI.escape(MultiJson.encode(property_names))
|
92
|
+
test_query("&property_names=#{property_names_str}", :property_names => property_names)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should encode a percentile decimal properly" do
|
96
|
+
test_query("&percentile=99.99", :percentile => 99.99)
|
97
|
+
end
|
98
|
+
|
89
99
|
it "should encode absolute timeframes properly" do
|
90
100
|
timeframe = {
|
91
101
|
:start => "2012-08-13T19:00Z+00:00",
|
@@ -119,6 +129,17 @@ describe Keen::Client do
|
|
119
129
|
}.to raise_error(Keen::AuthenticationError)
|
120
130
|
expect_keen_get(url, "sync", read_key)
|
121
131
|
end
|
132
|
+
|
133
|
+
it "should not change the extra params" do
|
134
|
+
timeframe = {
|
135
|
+
:start => "2012-08-13T19:00Z+00:00",
|
136
|
+
:end => "2012-08-13T19:00Z+00:00",
|
137
|
+
}
|
138
|
+
timeframe_str = CGI.escape(MultiJson.encode(timeframe))
|
139
|
+
|
140
|
+
test_query("&timeframe=#{timeframe_str}", options = {:timeframe => timeframe})
|
141
|
+
options.should eq({:timeframe => timeframe})
|
142
|
+
end
|
122
143
|
end
|
123
144
|
end
|
124
145
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Wild
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-05-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: multi_json
|