rest-more 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +1 -4
- data/CHANGES.md +12 -0
- data/Gemfile +0 -1
- data/README.md +0 -1
- data/Rakefile +7 -2
- data/example/rails2/app/controllers/application_controller.rb +5 -1
- data/example/rails2/app/views/application/helper.html.erb +0 -1
- data/example/rails2/config/rest-core.yaml +0 -4
- data/example/rails2/test/functional/application_controller_test.rb +16 -2
- data/example/rails3/Gemfile +1 -1
- data/example/rails3/app/controllers/application_controller.rb +5 -1
- data/example/rails3/app/views/application/helper.html.erb +0 -1
- data/example/rails3/config/rest-core.yaml +0 -4
- data/example/rails3/test/functional/application_controller_test.rb +16 -2
- data/lib/rest-core/client/bing.rb +1 -1
- data/lib/rest-core/client/dropbox.rb +1 -1
- data/lib/rest-core/client/facebook.rb +1 -1
- data/lib/rest-core/client/facebook/rails_util.rb +9 -2
- data/lib/rest-core/client/github.rb +1 -1
- data/lib/rest-core/client/linkedin.rb +1 -1
- data/lib/rest-core/client/mixi.rb +1 -1
- data/lib/rest-core/client/twitter.rb +1 -1
- data/lib/rest-core/client/twitter/rails_util.rb +1 -1
- data/lib/rest-more.rb +0 -1
- data/lib/rest-more/version.rb +1 -1
- data/rest-more.gemspec +2 -8
- data/test/facebook/test_handler.rb +1 -1
- data/test/facebook/test_misc.rb +13 -7
- metadata +2 -8
- data/lib/rest-core/client/flurry.rb +0 -137
- data/lib/rest-core/client/flurry/rails_util.rb +0 -13
- data/task/.gitignore +0 -1
- data/task/gemgem.rb +0 -265
- data/test/flurry/test_metrics.rb +0 -93
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
before_install: 'git submodule update --init'
|
2
|
-
script: '
|
2
|
+
script: 'ruby -r bundler/setup -S rake test:travis'
|
3
3
|
|
4
4
|
env:
|
5
5
|
- 'RESTMORE=rest-more'
|
@@ -7,10 +7,7 @@ env:
|
|
7
7
|
- 'RESTMORE=rails3'
|
8
8
|
|
9
9
|
rvm:
|
10
|
-
- 1.8.7
|
11
10
|
- 1.9.2
|
12
11
|
- 1.9.3
|
13
|
-
- rbx-18mode
|
14
12
|
- rbx-19mode
|
15
|
-
- jruby-18mode
|
16
13
|
- jruby-19mode
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## rest-more 1.0.2 -- 2012-07-13
|
4
|
+
|
5
|
+
* [Facebook::RailsUtil] Change the redirect log level from WARN to INFO.
|
6
|
+
* [Facebook::RailsUtil] Since Facebook would return correct URL now,
|
7
|
+
we don't have to try to use `URI.encode` anymore. Actually, that
|
8
|
+
causes bugs.
|
9
|
+
|
10
|
+
* [Twitter::RailsUtil] Change the redirect log level from WARN to INFO.
|
11
|
+
|
12
|
+
* [Flurry] Has been removed because it's too hard to maintain and
|
13
|
+
make it right.
|
14
|
+
|
3
15
|
## rest-more 1.0.1 -- 2012-05-14
|
4
16
|
|
5
17
|
* [RailsUtilUtil] Fix for DalliStore
|
data/Gemfile
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
begin
|
4
|
+
require "#{dir = File.dirname(__FILE__)}/task/gemgem"
|
5
|
+
rescue LoadError
|
6
|
+
sh "git submodule update --init"
|
7
|
+
exec Gem.ruby, "-S", "rake", *ARGV
|
8
|
+
end
|
5
9
|
|
10
|
+
Gemgem.dir = dir
|
6
11
|
($LOAD_PATH << File.expand_path("#{Gemgem.dir}/lib" ) <<
|
7
12
|
File.expand_path("#{Gemgem.dir}/rest-core/lib")).uniq!
|
8
13
|
|
@@ -3,7 +3,6 @@ class ApplicationController < ActionController::Base
|
|
3
3
|
protect_from_forgery
|
4
4
|
|
5
5
|
include RestCore::Facebook::RailsUtil
|
6
|
-
include RestCore::Flurry::RailsUtil
|
7
6
|
|
8
7
|
before_filter :filter_common , :only => [:index]
|
9
8
|
before_filter :filter_canvas , :only => [:canvas]
|
@@ -72,6 +71,11 @@ class ApplicationController < ActionController::Base
|
|
72
71
|
render :text => Timeout::Error.name
|
73
72
|
end
|
74
73
|
|
74
|
+
def redirect_uri
|
75
|
+
rc_facebook_setup(:canvas => '')
|
76
|
+
render :text => rc_facebook_normalized_request_uri
|
77
|
+
end
|
78
|
+
|
75
79
|
private
|
76
80
|
def filter_common
|
77
81
|
rc_facebook_setup(:auto_authorize => true, :canvas => '')
|
@@ -207,8 +207,7 @@ class ApplicationControllerTest < ActionController::TestCase
|
|
207
207
|
def test_helper
|
208
208
|
get(:helper)
|
209
209
|
assert_response :success
|
210
|
-
assert_equal "#{RestCore::Facebook.default_app_id}
|
211
|
-
"#{RestCore::Flurry .default_apiKey}",
|
210
|
+
assert_equal "#{RestCore::Facebook.default_app_id}",
|
212
211
|
@response.body.strip
|
213
212
|
end
|
214
213
|
|
@@ -242,4 +241,19 @@ class ApplicationControllerTest < ActionController::TestCase
|
|
242
241
|
assert_response :success
|
243
242
|
assert_equal 'Timeout::Error', @response.body.strip
|
244
243
|
end
|
244
|
+
|
245
|
+
def test_facebook_redirect_uri
|
246
|
+
get(:redirect_uri, :query => '/')
|
247
|
+
assert_response :success
|
248
|
+
assert_equal 'http://test.host/redirect_uri?query=%2F',
|
249
|
+
@response.body.strip
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_facebook_redirect_uri_with_spaces
|
253
|
+
get(:redirect_uri, :query => 'The user denied your request.')
|
254
|
+
assert_response :success
|
255
|
+
assert_equal \
|
256
|
+
'http://test.host/redirect_uri?query=The+user+denied+your+request.',
|
257
|
+
@response.body.strip
|
258
|
+
end
|
245
259
|
end
|
data/example/rails3/Gemfile
CHANGED
@@ -3,7 +3,6 @@ class ApplicationController < ActionController::Base
|
|
3
3
|
protect_from_forgery
|
4
4
|
|
5
5
|
include RestCore::Facebook::RailsUtil
|
6
|
-
include RestCore::Flurry::RailsUtil
|
7
6
|
|
8
7
|
before_filter :filter_common , :only => [:index]
|
9
8
|
before_filter :filter_canvas , :only => [:canvas]
|
@@ -72,6 +71,11 @@ class ApplicationController < ActionController::Base
|
|
72
71
|
render :text => Timeout::Error.name
|
73
72
|
end
|
74
73
|
|
74
|
+
def redirect_uri
|
75
|
+
rc_facebook_setup(:canvas => '')
|
76
|
+
render :text => rc_facebook_normalized_request_uri
|
77
|
+
end
|
78
|
+
|
75
79
|
private
|
76
80
|
def filter_common
|
77
81
|
rc_facebook_setup(:auto_authorize => true, :canvas => '')
|
@@ -207,8 +207,7 @@ class ApplicationControllerTest < ActionController::TestCase
|
|
207
207
|
def test_helper
|
208
208
|
get(:helper)
|
209
209
|
assert_response :success
|
210
|
-
assert_equal "#{RestCore::Facebook.default_app_id}
|
211
|
-
"#{RestCore::Flurry .default_apiKey}",
|
210
|
+
assert_equal "#{RestCore::Facebook.default_app_id}",
|
212
211
|
@response.body.strip
|
213
212
|
end
|
214
213
|
|
@@ -242,4 +241,19 @@ class ApplicationControllerTest < ActionController::TestCase
|
|
242
241
|
assert_response :success
|
243
242
|
assert_equal 'Timeout::Error', @response.body.strip
|
244
243
|
end
|
244
|
+
|
245
|
+
def test_facebook_redirect_uri
|
246
|
+
get(:redirect_uri, :query => '/')
|
247
|
+
assert_response :success
|
248
|
+
assert_equal 'http://test.host/redirect_uri?query=%2F',
|
249
|
+
@response.body.strip
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_facebook_redirect_uri_with_spaces
|
253
|
+
get(:redirect_uri, :query => 'The user denied your request.')
|
254
|
+
assert_response :success
|
255
|
+
assert_equal \
|
256
|
+
'http://test.host/redirect_uri?query=The+user+denied+your+request.',
|
257
|
+
@response.body.strip
|
258
|
+
end
|
245
259
|
end
|
@@ -3,7 +3,7 @@ require 'rest-core'
|
|
3
3
|
|
4
4
|
# http://msdn.microsoft.com/en-us/library/dd250846.aspx
|
5
5
|
RestCore::Bing = RestCore::Builder.client(:AppId) do
|
6
|
-
s =
|
6
|
+
s = RestCore
|
7
7
|
use s::Timeout , 10
|
8
8
|
|
9
9
|
use s::DefaultSite , 'http://api.bing.net/json.aspx'
|
@@ -62,7 +62,7 @@ module RestCore::Facebook::RailsUtil
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def rc_facebook_authorize error=nil, force_redirect=true
|
65
|
-
logger.
|
65
|
+
logger.info("INFO: Facebook: #{error.inspect}")
|
66
66
|
|
67
67
|
if force_redirect || rc_facebook_auto_authorize?
|
68
68
|
rc_facebook_cleanup
|
@@ -282,12 +282,19 @@ module RestCore::Facebook::RailsUtil
|
|
282
282
|
end
|
283
283
|
|
284
284
|
def rc_facebook_filter_uri uri
|
285
|
-
URI.parse(
|
285
|
+
URI.parse(uri).tap{ |uri|
|
286
286
|
uri.query = uri.query.split('&').reject{ |q|
|
287
287
|
q =~ /^(code|session|signed_request)\=/
|
288
288
|
}.join('&') if uri.query
|
289
289
|
uri.query = nil if uri.query.blank?
|
290
290
|
}.to_s
|
291
|
+
rescue URI::InvalidURIError => e
|
292
|
+
if @rc_facebook_filter_uri_retry
|
293
|
+
raise e
|
294
|
+
else
|
295
|
+
@rc_facebook_filter_uri_retry = uri = URI.encode(uri)
|
296
|
+
retry
|
297
|
+
end
|
291
298
|
end
|
292
299
|
|
293
300
|
def rc_facebook_in_canvas?
|
@@ -3,7 +3,7 @@ require 'rest-core'
|
|
3
3
|
|
4
4
|
# http://developer.linkedin.com/documents/linkedin-api-resource-map
|
5
5
|
RestCore::Linkedin = RestCore::Builder.client do
|
6
|
-
s =
|
6
|
+
s = RestCore
|
7
7
|
use s::Timeout , 10
|
8
8
|
|
9
9
|
use s::DefaultSite , 'https://api.linkedin.com/'
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# http://developer.mixi.co.jp/connect/mixi_graph_api/
|
3
3
|
RestCore::Mixi = RestCore::Builder.client(
|
4
4
|
:data, :consumer_key, :consumer_secret, :redirect_uri) do
|
5
|
-
s =
|
5
|
+
s = RestCore
|
6
6
|
use s::Timeout , 10
|
7
7
|
|
8
8
|
use s::DefaultSite , 'http://api.mixi-platform.com/'
|
@@ -47,7 +47,7 @@ module RestCore::Twitter::RailsUtil
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def rc_twitter_authorize error=nil, force_redirect=true
|
50
|
-
logger.
|
50
|
+
logger.info("INFO: Twitter: #{error.inspect}")
|
51
51
|
|
52
52
|
if force_redirect || rc_options_get(RestCore::Twitter, :auto_authorize)
|
53
53
|
rc_twitter_cleanup
|
data/lib/rest-more.rb
CHANGED
@@ -7,7 +7,6 @@ module RestCore
|
|
7
7
|
autoload :Bing , 'rest-core/client/bing'
|
8
8
|
autoload :Dropbox , 'rest-core/client/dropbox'
|
9
9
|
autoload :Facebook, 'rest-core/client/facebook'
|
10
|
-
autoload :Flurry , 'rest-core/client/flurry'
|
11
10
|
autoload :Github , 'rest-core/client/github'
|
12
11
|
autoload :Linkedin, 'rest-core/client/linkedin'
|
13
12
|
autoload :Mixi , 'rest-core/client/mixi'
|
data/lib/rest-more/version.rb
CHANGED
data/rest-more.gemspec
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "rest-more"
|
5
|
-
s.version = "1.0.
|
5
|
+
s.version = "1.0.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = [
|
9
9
|
"Cardinal Blue",
|
10
10
|
"Lin Jen-Shin (godfat)"]
|
11
|
-
s.date = "2012-
|
11
|
+
s.date = "2012-07-13"
|
12
12
|
s.description = "Various REST clients such as Facebook and Twitter built with [rest-core][]\n\n[rest-core]: https://github.com/cardinalblue/rest-core"
|
13
13
|
s.email = ["dev (XD) cardinalblue.com"]
|
14
14
|
s.executables = ["rib-rest-core"]
|
@@ -78,8 +78,6 @@ Gem::Specification.new do |s|
|
|
78
78
|
"lib/rest-core/client/dropbox.rb",
|
79
79
|
"lib/rest-core/client/facebook.rb",
|
80
80
|
"lib/rest-core/client/facebook/rails_util.rb",
|
81
|
-
"lib/rest-core/client/flurry.rb",
|
82
|
-
"lib/rest-core/client/flurry/rails_util.rb",
|
83
81
|
"lib/rest-core/client/github.rb",
|
84
82
|
"lib/rest-core/client/github/rails_util.rb",
|
85
83
|
"lib/rest-core/client/linkedin.rb",
|
@@ -95,8 +93,6 @@ Gem::Specification.new do |s|
|
|
95
93
|
"lib/rest-more/version.rb",
|
96
94
|
"lib/rib/app/rest-core.rb",
|
97
95
|
"rest-more.gemspec",
|
98
|
-
"task/.gitignore",
|
99
|
-
"task/gemgem.rb",
|
100
96
|
"test/bing/test_api.rb",
|
101
97
|
"test/dropbox/test_api.rb",
|
102
98
|
"test/facebook/config/rest-core.yaml",
|
@@ -113,7 +109,6 @@ Gem::Specification.new do |s|
|
|
113
109
|
"test/facebook/test_parse.rb",
|
114
110
|
"test/facebook/test_serialize.rb",
|
115
111
|
"test/facebook/test_timeout.rb",
|
116
|
-
"test/flurry/test_metrics.rb",
|
117
112
|
"test/mixi/test_api.rb",
|
118
113
|
"test/twitter/test_api.rb"]
|
119
114
|
s.homepage = "https://github.com/cardinalblue/rest-more"
|
@@ -136,7 +131,6 @@ Gem::Specification.new do |s|
|
|
136
131
|
"test/facebook/test_parse.rb",
|
137
132
|
"test/facebook/test_serialize.rb",
|
138
133
|
"test/facebook/test_timeout.rb",
|
139
|
-
"test/flurry/test_metrics.rb",
|
140
134
|
"test/mixi/test_api.rb",
|
141
135
|
"test/twitter/test_api.rb"]
|
142
136
|
|
data/test/facebook/test_misc.rb
CHANGED
@@ -24,21 +24,27 @@ describe RC::Facebook do
|
|
24
24
|
rg = RC::Facebook.new(:accept => 'text/html',
|
25
25
|
:lang => 'zh-tw')
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
rg.dry.call(rg.send(:build_env)){ |res|
|
28
|
+
headers = res[RC::REQUEST_HEADERS]
|
29
|
+
headers['Accept' ].should.eq 'text/html'
|
30
|
+
headers['Accept-Language'].should.eq 'zh-tw'
|
31
|
+
}
|
30
32
|
end
|
31
33
|
|
32
34
|
should 'build empty query string' do
|
35
|
+
# TODO: WTF is this trying to test!?
|
33
36
|
rg = RC::Facebook.new
|
34
|
-
|
35
|
-
should.eq({})
|
37
|
+
rg.dry.call(rg.send(:build_env)){ |res|
|
38
|
+
(res[RC::REQUEST_QUERY] || {}).should.eq({})
|
39
|
+
}
|
36
40
|
end
|
37
41
|
|
38
42
|
should 'create access_token in query string' do
|
39
43
|
rg = RC::Facebook.new(:access_token => 'token')
|
40
|
-
|
41
|
-
|
44
|
+
rg.dry.call(rg.send(:build_env)){ |res|
|
45
|
+
# TODO: WTF is this `|| {}` !?
|
46
|
+
(res[RC::REQUEST_QUERY] || {}).should.eq({'access_token' => 'token'})
|
47
|
+
}
|
42
48
|
end
|
43
49
|
|
44
50
|
should 'build correct query string' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-more
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-07-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-core
|
@@ -104,8 +104,6 @@ files:
|
|
104
104
|
- lib/rest-core/client/dropbox.rb
|
105
105
|
- lib/rest-core/client/facebook.rb
|
106
106
|
- lib/rest-core/client/facebook/rails_util.rb
|
107
|
-
- lib/rest-core/client/flurry.rb
|
108
|
-
- lib/rest-core/client/flurry/rails_util.rb
|
109
107
|
- lib/rest-core/client/github.rb
|
110
108
|
- lib/rest-core/client/github/rails_util.rb
|
111
109
|
- lib/rest-core/client/linkedin.rb
|
@@ -121,8 +119,6 @@ files:
|
|
121
119
|
- lib/rest-more/version.rb
|
122
120
|
- lib/rib/app/rest-core.rb
|
123
121
|
- rest-more.gemspec
|
124
|
-
- task/.gitignore
|
125
|
-
- task/gemgem.rb
|
126
122
|
- test/bing/test_api.rb
|
127
123
|
- test/dropbox/test_api.rb
|
128
124
|
- test/facebook/config/rest-core.yaml
|
@@ -139,7 +135,6 @@ files:
|
|
139
135
|
- test/facebook/test_parse.rb
|
140
136
|
- test/facebook/test_serialize.rb
|
141
137
|
- test/facebook/test_timeout.rb
|
142
|
-
- test/flurry/test_metrics.rb
|
143
138
|
- test/mixi/test_api.rb
|
144
139
|
- test/twitter/test_api.rb
|
145
140
|
homepage: https://github.com/cardinalblue/rest-more
|
@@ -182,7 +177,6 @@ test_files:
|
|
182
177
|
- test/facebook/test_parse.rb
|
183
178
|
- test/facebook/test_serialize.rb
|
184
179
|
- test/facebook/test_timeout.rb
|
185
|
-
- test/flurry/test_metrics.rb
|
186
180
|
- test/mixi/test_api.rb
|
187
181
|
- test/twitter/test_api.rb
|
188
182
|
has_rdoc:
|
@@ -1,137 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core'
|
3
|
-
|
4
|
-
require 'time' # for Time.parse
|
5
|
-
|
6
|
-
# http://wiki.flurry.com
|
7
|
-
RestCore::Flurry = RestCore::Builder.client(:apiKey, :apiAccessCode) do
|
8
|
-
s = self.class # this is only for ruby 1.8!
|
9
|
-
use s::Timeout , 10
|
10
|
-
|
11
|
-
use s::DefaultSite , 'http://api.flurry.com/'
|
12
|
-
use s::DefaultHeaders, {'Accept' => 'application/json'}
|
13
|
-
use s::DefaultQuery , {}
|
14
|
-
|
15
|
-
use s::CommonLogger , nil
|
16
|
-
use s::Cache , nil, 600 do
|
17
|
-
use s::ErrorHandler, lambda{ |env|
|
18
|
-
if env[s::ASYNC]
|
19
|
-
if env[s::RESPONSE_BODY].kind_of?(::Exception)
|
20
|
-
env
|
21
|
-
else
|
22
|
-
env.merge(s::RESPONSE_BODY =>
|
23
|
-
RuntimeError.new(env[s::RESPONSE_BODY]['message']))
|
24
|
-
end
|
25
|
-
else
|
26
|
-
raise env[s::RESPONSE_BODY]['message']
|
27
|
-
end}
|
28
|
-
use s::ErrorDetectorHttp
|
29
|
-
use s::JsonDecode , true
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
module RestCore::Flurry::Client
|
34
|
-
# see: http://wiki.flurry.com/index.php?title=AppInfo
|
35
|
-
# >> f.app_info
|
36
|
-
# => {"@platform"=>"iPhone", "@name"=>"PicCollage",
|
37
|
-
# "@createdDate"=>"2011-07-24", "@category"=>"Photography",
|
38
|
-
# "@version"=>"1.0", "@generatedDate"=>"9/15/11 7:08 AM",
|
39
|
-
# "version"=>[{"@name"=>"2.1", ...
|
40
|
-
def app_info query={}, opts={}
|
41
|
-
get('appInfo/getApplication', query, opts)
|
42
|
-
end
|
43
|
-
|
44
|
-
# see: http://wiki.flurry.com/index.php?title=EventMetrics
|
45
|
-
# >> f.event_names
|
46
|
-
# => ["Products", "Save To Photo Library", ...]
|
47
|
-
def event_names query={}, opts={}
|
48
|
-
event_summary(query, opts).keys
|
49
|
-
end
|
50
|
-
|
51
|
-
# see: http://wiki.flurry.com/index.php?title=EventMetrics
|
52
|
-
# >> f.event_summary({}, :days => 7)
|
53
|
-
# => {"Products" => {"@usersLastWeek" => "948" ,
|
54
|
-
# "@usersLastMonth" => "2046",
|
55
|
-
# "@usersLastDay" => "4" , ...}}
|
56
|
-
def event_summary query={}, opts={}
|
57
|
-
array2hash(get('eventMetrics/Summary',
|
58
|
-
*calculate_query_and_opts(query, opts))['event'],
|
59
|
-
'@eventName')
|
60
|
-
end
|
61
|
-
|
62
|
-
# see: http://wiki.flurry.com/index.php?title=EventMetrics
|
63
|
-
# >> f.event_metrics('Products', {}, :days => 7)
|
64
|
-
# => [["2011-11-23", {"@uniqueUsers" => "12" ,
|
65
|
-
# "@totalSessions" => "108392" ,
|
66
|
-
# "@totalCount" => "30" ,
|
67
|
-
# "@duration" => "9754723"}],
|
68
|
-
# ["2011-11-22", {...}]]
|
69
|
-
def event_metrics name, query={}, opts={}
|
70
|
-
array2hash(get('eventMetrics/Event',
|
71
|
-
*calculate_query_and_opts(
|
72
|
-
{'eventName' => name}.merge(query), opts))['day'],
|
73
|
-
'@date').sort{ |a, b| b <=> a }
|
74
|
-
end
|
75
|
-
|
76
|
-
# see: http://wiki.flurry.com/index.php?title=AppMetrics
|
77
|
-
# >> f.metrics('ActiveUsers', {}, :weeks => 4)
|
78
|
-
# => [["2011-09-19", 6516], ["2011-09-18", 43920], ["2011-09-17", 45412],
|
79
|
-
# ["2011-09-16", 40972], ["2011-09-15", 37587], ["2011-09-14", 34918],
|
80
|
-
# ...]
|
81
|
-
def metrics path, query={}, opts={}
|
82
|
-
get("appMetrics/#{path}", *calculate_query_and_opts(query, opts)
|
83
|
-
)['day'].map{ |i| [i['@date'], i['@value'].to_i] }.reverse
|
84
|
-
end
|
85
|
-
|
86
|
-
# >> f.weekly(f.metrics('ActiveUsers', {}, :weeks => 4))
|
87
|
-
# => [244548, 270227, 248513, 257149]
|
88
|
-
def weekly array
|
89
|
-
start = Time.parse(array.first.first, nil).to_i
|
90
|
-
array.group_by{ |(date, value)|
|
91
|
-
current = Time.parse(date, nil).to_i
|
92
|
-
- (current - start) / (86400*7)
|
93
|
-
# calling .last to discard week numbers created by group_by
|
94
|
-
}.sort.map(&:last).map{ |week|
|
95
|
-
week.map{ |(_, num)| num }.inject(&:+) }
|
96
|
-
end
|
97
|
-
|
98
|
-
# >> f.sum(f.weekly(f.metrics('ActiveUsers', {}, :weeks => 4)))
|
99
|
-
# => [1020437, 775889, 505662, 257149]
|
100
|
-
def sum array
|
101
|
-
reverse = array.reverse
|
102
|
-
(0...reverse.size).map{ |index|
|
103
|
-
reverse[1, index].inject(reverse.first, &:+)
|
104
|
-
}.reverse
|
105
|
-
end
|
106
|
-
|
107
|
-
def default_query
|
108
|
-
{'apiKey' => apiKey ,
|
109
|
-
'apiAccessCode' => apiAccessCode}
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
def calculate_query_and_opts query, opts
|
114
|
-
days = opts[:days] || (opts[:weeks] && opts[:weeks] * 7) ||
|
115
|
-
(opts[:months] && opts[:months] * 30) || 7
|
116
|
-
|
117
|
-
startDate = query[:startDate] || (Time.now + 86400 - 86400*days).
|
118
|
-
strftime('%Y-%m-%d')
|
119
|
-
|
120
|
-
endDate = query[:endDate] || Time.now.
|
121
|
-
strftime('%Y-%m-%d')
|
122
|
-
|
123
|
-
[query.merge(:startDate => startDate,
|
124
|
-
:endDate => endDate),
|
125
|
-
opts.reject{ |k, _| [:days, :weeks, :months].include?(k) }]
|
126
|
-
end
|
127
|
-
|
128
|
-
def array2hash array, key
|
129
|
-
array.inject({}){ |r, i|
|
130
|
-
r[i[key]] = i.reject{ |k, _| k == key }
|
131
|
-
r }
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
RestCore::Flurry.send(:include, RestCore::Flurry::Client)
|
136
|
-
require 'rest-core/client/flurry/rails_util' if
|
137
|
-
Object.const_defined?(:Rails)
|
@@ -1,13 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/util/rails_util_util'
|
3
|
-
|
4
|
-
module RestCore::Flurry::DefaultAttributes
|
5
|
-
def default_log_method; Rails.logger.method(:debug); end
|
6
|
-
def default_cache ; Rails.cache ; end
|
7
|
-
end
|
8
|
-
|
9
|
-
module RestCore::Flurry::RailsUtil
|
10
|
-
include RestCore::RailsUtilUtil
|
11
|
-
end
|
12
|
-
|
13
|
-
RestCore::Flurry::RailsUtil.init(Rails)
|
data/task/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
*.rbc
|
data/task/gemgem.rb
DELETED
@@ -1,265 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
module Gemgem
|
5
|
-
class << self
|
6
|
-
attr_accessor :dir, :spec
|
7
|
-
end
|
8
|
-
|
9
|
-
module_function
|
10
|
-
def create
|
11
|
-
yield(spec = Gem::Specification.new{ |s|
|
12
|
-
s.authors = ['Lin Jen-Shin (godfat)']
|
13
|
-
s.email = ['godfat (XD) godfat.org']
|
14
|
-
|
15
|
-
s.description = description.join
|
16
|
-
s.summary = description.first
|
17
|
-
|
18
|
-
s.rubygems_version = Gem::VERSION
|
19
|
-
s.date = Time.now.strftime('%Y-%m-%d')
|
20
|
-
s.files = gem_files
|
21
|
-
s.test_files = gem_files.grep(%r{^test/(.+?/)*test_.+?\.rb$})
|
22
|
-
s.executables = Dir['bin/*'].map{ |f| File.basename(f) }
|
23
|
-
s.require_paths = %w[lib]
|
24
|
-
})
|
25
|
-
spec.homepage ||= "https://github.com/godfat/#{spec.name}"
|
26
|
-
spec
|
27
|
-
end
|
28
|
-
|
29
|
-
def readme
|
30
|
-
path = %w[README.md README].find{ |name|
|
31
|
-
File.exist?("#{Gemgem.dir}/#{name}")
|
32
|
-
}
|
33
|
-
@readme ||=
|
34
|
-
if path
|
35
|
-
ps = File.read(path).scan(/#+[^\n]+\n\n.+?(?=\n\n#+[^\n]+\n)/m)
|
36
|
-
ps.inject({'HEADER' => ps.first}){ |r, s, i|
|
37
|
-
r[s[/\w+/]] = s
|
38
|
-
r
|
39
|
-
}
|
40
|
-
else
|
41
|
-
{}
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def description
|
46
|
-
@description ||= (readme['DESCRIPTION']||'').sub(/.+\n\n/, '').lines.to_a
|
47
|
-
end
|
48
|
-
|
49
|
-
def changes
|
50
|
-
path = %w[CHANGES.md CHANGES].find{ |name|
|
51
|
-
File.exist?("#{Gemgem.dir}/#{name}")
|
52
|
-
}
|
53
|
-
@changes ||=
|
54
|
-
if path
|
55
|
-
date = '\d+{4}\-\d+{2}\-\d{2}'
|
56
|
-
File.read(path).match(
|
57
|
-
/([^\n]+#{date}\n\n(.+?))(?=\n\n[^\n]+#{date}\n|\Z)/m)[1]
|
58
|
-
else
|
59
|
-
''
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def ann_md
|
64
|
-
"##{readme['HEADER'].sub(/([\w\-]+)/, "[\\1](#{spec.homepage})")}\n\n" \
|
65
|
-
"##{readme['DESCRIPTION'][/[^\n]+\n\n[^\n]+/]}\n\n" \
|
66
|
-
"### CHANGES:\n\n" \
|
67
|
-
"###{changes}\n\n" \
|
68
|
-
"##{readme['INSTALLATION']}\n\n" +
|
69
|
-
if readme['SYNOPSIS'] then "##{readme['SYNOPSIS']}" else '' end
|
70
|
-
end
|
71
|
-
|
72
|
-
def ann_html
|
73
|
-
gem 'nokogiri'
|
74
|
-
gem 'kramdown'
|
75
|
-
|
76
|
-
IO.popen('kramdown', 'r+') do |md|
|
77
|
-
md.puts Gemgem.ann_md
|
78
|
-
md.close_write
|
79
|
-
require 'nokogiri'
|
80
|
-
html = Nokogiri::XML.parse("<gemgem>#{md.read}</gemgem>")
|
81
|
-
html.css('*').each{ |n| n.delete('id') }
|
82
|
-
html.root.children.to_html
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def ann_email
|
87
|
-
"#{readme['HEADER'].sub(/([\w\-]+)/, "\\1 <#{spec.homepage}>")}\n\n" \
|
88
|
-
"#{readme['DESCRIPTION']}\n\n" \
|
89
|
-
"#{readme['INSTALLATION']}\n\n" +
|
90
|
-
if readme['SYNOPSIS'] then "##{readme['SYNOPSIS']}\n\n" else '' end +
|
91
|
-
"## CHANGES:\n\n" \
|
92
|
-
"##{changes}\n\n"
|
93
|
-
end
|
94
|
-
|
95
|
-
def gem_tag
|
96
|
-
"#{spec.name}-#{spec.version}"
|
97
|
-
end
|
98
|
-
|
99
|
-
def write
|
100
|
-
File.open("#{dir}/#{spec.name}.gemspec", 'w'){ |f|
|
101
|
-
f << split_lines(spec.to_ruby) }
|
102
|
-
end
|
103
|
-
|
104
|
-
def split_lines ruby
|
105
|
-
ruby.gsub(/(.+?)\[(.+?)\]/){ |s|
|
106
|
-
if $2.index(',')
|
107
|
-
"#{$1}[\n #{$2.split(',').map(&:strip).join(",\n ")}]"
|
108
|
-
else
|
109
|
-
s
|
110
|
-
end
|
111
|
-
}
|
112
|
-
end
|
113
|
-
|
114
|
-
def all_files
|
115
|
-
@all_files ||= find_files(Pathname.new(dir)).map{ |file|
|
116
|
-
if file.to_s =~ %r{\.git/}
|
117
|
-
nil
|
118
|
-
else
|
119
|
-
file.to_s
|
120
|
-
end
|
121
|
-
}.compact.sort
|
122
|
-
end
|
123
|
-
|
124
|
-
def gem_files
|
125
|
-
@gem_files ||= all_files - ignored_files
|
126
|
-
end
|
127
|
-
|
128
|
-
def ignored_files
|
129
|
-
@ignored_file ||= all_files.select{ |path| ignore_patterns.find{ |ignore|
|
130
|
-
path =~ ignore && !git_files.include?(path)}}
|
131
|
-
end
|
132
|
-
|
133
|
-
def git_files
|
134
|
-
@git_files ||= if File.exist?("#{dir}/.git")
|
135
|
-
`git ls-files`.split("\n")
|
136
|
-
else
|
137
|
-
[]
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# protected
|
142
|
-
def find_files path
|
143
|
-
path.children.select(&:file?).map{|file| file.to_s[(dir.size+1)..-1]} +
|
144
|
-
path.children.select(&:directory?).map{|dir| find_files(dir)}.flatten
|
145
|
-
end
|
146
|
-
|
147
|
-
def ignore_patterns
|
148
|
-
@ignore_files ||= expand_patterns(
|
149
|
-
gitignore.split("\n").reject{ |pattern|
|
150
|
-
pattern.strip == ''
|
151
|
-
}).map{ |pattern| %r{^([^/]+/)*?#{Regexp.escape(pattern)}(/[^/]+)*?$} }
|
152
|
-
end
|
153
|
-
|
154
|
-
def expand_patterns pathes
|
155
|
-
pathes.map{ |path|
|
156
|
-
if path !~ /\*/
|
157
|
-
path
|
158
|
-
else
|
159
|
-
expand_patterns(
|
160
|
-
Dir[path] +
|
161
|
-
Pathname.new(File.dirname(path)).children.select(&:directory?).
|
162
|
-
map{ |prefix| "#{prefix}/#{File.basename(path)}" })
|
163
|
-
end
|
164
|
-
}.flatten
|
165
|
-
end
|
166
|
-
|
167
|
-
def gitignore
|
168
|
-
if File.exist?(path = "#{dir}/.gitignore")
|
169
|
-
File.read(path)
|
170
|
-
else
|
171
|
-
''
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
namespace :gem do
|
177
|
-
|
178
|
-
desc 'Install gem'
|
179
|
-
task :install => [:build] do
|
180
|
-
sh("#{Gem.ruby} -S gem install pkg/#{Gemgem.gem_tag}")
|
181
|
-
end
|
182
|
-
|
183
|
-
desc 'Build gem'
|
184
|
-
task :build => [:spec] do
|
185
|
-
sh("#{Gem.ruby} -S gem build #{Gemgem.spec.name}.gemspec")
|
186
|
-
sh("mkdir -p pkg")
|
187
|
-
sh("mv #{Gemgem.gem_tag}.gem pkg/")
|
188
|
-
end
|
189
|
-
|
190
|
-
desc 'Release gem'
|
191
|
-
task :release => [:spec, :check, :build] do
|
192
|
-
sh("git tag #{Gemgem.gem_tag}")
|
193
|
-
sh("git push")
|
194
|
-
sh("git push --tags")
|
195
|
-
sh("#{Gem.ruby} -S gem push pkg/#{Gemgem.gem_tag}.gem")
|
196
|
-
end
|
197
|
-
|
198
|
-
task :check do
|
199
|
-
ver = Gemgem.spec.version.to_s
|
200
|
-
|
201
|
-
if ENV['VERSION'].nil?
|
202
|
-
puts("\e[35mExpected " \
|
203
|
-
"\e[33mVERSION\e[35m=\e[33m#{ver}\e[m")
|
204
|
-
exit(1)
|
205
|
-
|
206
|
-
elsif ENV['VERSION'] != ver
|
207
|
-
puts("\e[35mExpected \e[33mVERSION\e[35m=\e[33m#{ver} " \
|
208
|
-
"\e[35mbut got\n " \
|
209
|
-
"\e[33mVERSION\e[35m=\e[33m#{ENV['VERSION']}\e[m")
|
210
|
-
exit(2)
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
end # of gem namespace
|
215
|
-
|
216
|
-
desc 'Run tests in memory'
|
217
|
-
task :test do
|
218
|
-
require 'bacon'
|
219
|
-
Bacon.extend(Bacon::TestUnitOutput)
|
220
|
-
Bacon.summary_on_exit
|
221
|
-
$LOAD_PATH.unshift('lib')
|
222
|
-
Dir['./test/**/test_*.rb'].each{ |file| require file[0..-4] }
|
223
|
-
end
|
224
|
-
|
225
|
-
desc 'Run tests with shell'
|
226
|
-
task 'test:shell', :RUBY_OPTS do |t, args|
|
227
|
-
files = Dir['test/**/test_*.rb'].join(' ')
|
228
|
-
|
229
|
-
cmd = [Gem.ruby, args[:RUBY_OPTS],
|
230
|
-
'-I', 'lib', '-S', 'bacon', '--quiet', files]
|
231
|
-
|
232
|
-
sh(cmd.compact.join(' '))
|
233
|
-
end
|
234
|
-
|
235
|
-
desc 'Generate ann markdown'
|
236
|
-
task 'ann:md' => ['gem:spec'] do
|
237
|
-
puts Gemgem.ann_md
|
238
|
-
end
|
239
|
-
|
240
|
-
desc 'Generate ann html'
|
241
|
-
task 'ann:html' => ['gem:spec'] do
|
242
|
-
puts Gemgem.ann_html
|
243
|
-
end
|
244
|
-
|
245
|
-
desc 'Generate ann email'
|
246
|
-
task 'ann:email' => ['gem:spec'] do
|
247
|
-
puts Gemgem.ann_email
|
248
|
-
end
|
249
|
-
|
250
|
-
desc 'Generate rdoc'
|
251
|
-
task :doc => ['gem:spec'] do
|
252
|
-
sh("yardoc -o rdoc --main README.md" \
|
253
|
-
" --files #{Gemgem.spec.extra_rdoc_files.join(',')}")
|
254
|
-
end
|
255
|
-
|
256
|
-
desc 'Remove ignored files'
|
257
|
-
task :clean => ['gem:spec'] do
|
258
|
-
trash = "~/.Trash/#{Gemgem.spec.name}/"
|
259
|
-
sh "mkdir -p #{trash}" unless File.exist?(File.expand_path(trash))
|
260
|
-
Gemgem.ignored_files.each{ |file| sh "mv #{file} #{trash}" }
|
261
|
-
end
|
262
|
-
|
263
|
-
task :default do
|
264
|
-
puts `#{Gem.ruby} -S #{$PROGRAM_NAME} -T`
|
265
|
-
end
|
data/test/flurry/test_metrics.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-more/test'
|
3
|
-
|
4
|
-
require 'time'
|
5
|
-
|
6
|
-
describe RC::Flurry do
|
7
|
-
after do
|
8
|
-
WebMock.reset!
|
9
|
-
RR.verify
|
10
|
-
end
|
11
|
-
|
12
|
-
describe 'metrics' do
|
13
|
-
before do
|
14
|
-
startDate = '2011-08-23'
|
15
|
-
endDate = '2011-09-19'
|
16
|
-
@flurry = RestCore::Flurry.new
|
17
|
-
stub(Time).now{ Time.parse(endDate, nil) }
|
18
|
-
stub_request(:get,
|
19
|
-
"http://api.flurry.com/appMetrics/ActiveUsers?" \
|
20
|
-
"startDate=#{startDate}&endDate=#{endDate}").
|
21
|
-
to_return(:body =>
|
22
|
-
'{"@startDate":"2011-08-23",
|
23
|
-
"@metric":"ActiveUsersByDay",
|
24
|
-
"@endDate":"2011-09-19",
|
25
|
-
"@version":"1.0",
|
26
|
-
"@generatedDate":"9/19/11 5:54 AM",
|
27
|
-
"day":
|
28
|
-
[{"@value":"34722","@date":"2011-08-23"},
|
29
|
-
{"@value":"33560","@date":"2011-08-24"},
|
30
|
-
{"@value":"34392","@date":"2011-08-25"},
|
31
|
-
{"@value":"37737","@date":"2011-08-26"},
|
32
|
-
{"@value":"41332","@date":"2011-08-27"},
|
33
|
-
{"@value":"40456","@date":"2011-08-28"},
|
34
|
-
{"@value":"34950","@date":"2011-08-29"},
|
35
|
-
{"@value":"34076","@date":"2011-08-30"},
|
36
|
-
{"@value":"32096","@date":"2011-08-31"},
|
37
|
-
{"@value":"31558","@date":"2011-09-01"},
|
38
|
-
{"@value":"33467","@date":"2011-09-02"},
|
39
|
-
{"@value":"39306","@date":"2011-09-03"},
|
40
|
-
{"@value":"40233","@date":"2011-09-04"},
|
41
|
-
{"@value":"37777","@date":"2011-09-05"},
|
42
|
-
{"@value":"35829","@date":"2011-09-06"},
|
43
|
-
{"@value":"35960","@date":"2011-09-07"},
|
44
|
-
{"@value":"34871","@date":"2011-09-08"},
|
45
|
-
{"@value":"36683","@date":"2011-09-09"},
|
46
|
-
{"@value":"44077","@date":"2011-09-10"},
|
47
|
-
{"@value":"45057","@date":"2011-09-11"},
|
48
|
-
{"@value":"37750","@date":"2011-09-12"},
|
49
|
-
{"@value":"35223","@date":"2011-09-13"},
|
50
|
-
{"@value":"34918","@date":"2011-09-14"},
|
51
|
-
{"@value":"37587","@date":"2011-09-15"},
|
52
|
-
{"@value":"40972","@date":"2011-09-16"},
|
53
|
-
{"@value":"45412","@date":"2011-09-17"},
|
54
|
-
{"@value":"43920","@date":"2011-09-18"},
|
55
|
-
{"@value":"6516","@date":"2011-09-19"}]}')
|
56
|
-
|
57
|
-
@active_users =
|
58
|
-
[["2011-09-19", 6516], ["2011-09-18", 43920], ["2011-09-17", 45412],
|
59
|
-
["2011-09-16", 40972], ["2011-09-15", 37587], ["2011-09-14", 34918],
|
60
|
-
["2011-09-13", 35223], ["2011-09-12", 37750], ["2011-09-11", 45057],
|
61
|
-
["2011-09-10", 44077], ["2011-09-09", 36683], ["2011-09-08", 34871],
|
62
|
-
["2011-09-07", 35960], ["2011-09-06", 35829], ["2011-09-05", 37777],
|
63
|
-
["2011-09-04", 40233], ["2011-09-03", 39306], ["2011-09-02", 33467],
|
64
|
-
["2011-09-01", 31558], ["2011-08-31", 32096], ["2011-08-30", 34076],
|
65
|
-
["2011-08-29", 34950], ["2011-08-28", 40456], ["2011-08-27", 41332],
|
66
|
-
["2011-08-26", 37737], ["2011-08-25", 34392], ["2011-08-24", 33560],
|
67
|
-
["2011-08-23", 34722]]
|
68
|
-
|
69
|
-
@weekly = [244548, 270227, 248513, 257149]
|
70
|
-
end
|
71
|
-
|
72
|
-
should 'metrics("ActiveUsers")' do
|
73
|
-
@flurry.metrics('ActiveUsers', {}, :weeks => 4).should.eq @active_users
|
74
|
-
end
|
75
|
-
|
76
|
-
should 'weekly(metrics("ActiveUsers"))' do
|
77
|
-
@flurry.weekly(@active_users).should.eq @weekly
|
78
|
-
end
|
79
|
-
|
80
|
-
should 'sum(weekly(metrics("ActiveUsers")))' do
|
81
|
-
@flurry.sum(@weekly).should.eq [1020437, 775889, 505662, 257149]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
should 'bring apiKey and apiAccessCode' do
|
86
|
-
stub_request(:get,
|
87
|
-
"http://api.flurry.com/?apiKey=a&apiAccessCode=b").
|
88
|
-
to_return(:body => '["ok"]')
|
89
|
-
|
90
|
-
f = RC::Flurry.new(:apiKey => 'a', :apiAccessCode => 'b')
|
91
|
-
f.get('').should.eq ['ok']
|
92
|
-
end
|
93
|
-
end
|