nitroapi 0.0.5 → 0.0.7
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 +51 -0
- data/Gemfile +4 -16
- data/Gemfile.lock +26 -20
- data/README.md +9 -3
- data/Rakefile +1 -13
- data/lib/nitro_api.rb +114 -94
- data/lib/nitro_api/batch_calls.rb +62 -0
- data/lib/nitro_api/challenge.rb +5 -0
- data/lib/nitro_api/rule.rb +5 -0
- data/lib/nitro_api/site_calls.rb +33 -0
- data/lib/nitro_api/user_calls.rb +155 -0
- data/lib/nitro_api/version.rb +3 -0
- data/nitroapi.gemspec +21 -62
- data/spec/nitro_api_spec.rb +321 -18
- metadata +56 -41
- data/VERSION +0 -1
data/.gitignore
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
examples/my*
|
2
|
+
# rcov generated
|
3
|
+
coverage
|
4
|
+
|
5
|
+
# rdoc generated
|
6
|
+
rdoc
|
7
|
+
|
8
|
+
# yard generated
|
9
|
+
doc
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# bundler
|
13
|
+
.bundle
|
14
|
+
|
15
|
+
# jeweler generated
|
16
|
+
pkg
|
17
|
+
|
18
|
+
keys.json
|
19
|
+
|
20
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
21
|
+
#
|
22
|
+
# * Create a file at ~/.gitignore
|
23
|
+
# * Include files you want ignored
|
24
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
25
|
+
#
|
26
|
+
# After doing this, these files will be ignored in all your git projects,
|
27
|
+
# saving you from having to 'pollute' every project you touch with them
|
28
|
+
#
|
29
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
30
|
+
#
|
31
|
+
# For MacOS:
|
32
|
+
#
|
33
|
+
#.DS_Store
|
34
|
+
|
35
|
+
# For TextMate
|
36
|
+
#*.tmproj
|
37
|
+
#tmtags
|
38
|
+
|
39
|
+
# For emacs:
|
40
|
+
#*~
|
41
|
+
#\#*
|
42
|
+
#.\#*
|
43
|
+
|
44
|
+
# For vim:
|
45
|
+
#*.swp
|
46
|
+
|
47
|
+
# For redcar:
|
48
|
+
#.redcar
|
49
|
+
|
50
|
+
# For rubinius:
|
51
|
+
#*.rbc
|
data/Gemfile
CHANGED
@@ -1,20 +1,8 @@
|
|
1
|
-
source '
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
gem 'json'
|
6
|
-
|
7
|
-
# Please keep me alphabetized!
|
8
|
-
|
9
|
-
# Add dependencies to develop your gem here.
|
10
|
-
# Include everything needed to run rake, tests, features, etc.
|
11
|
-
group :development do
|
12
|
-
gem "rspec", "~> 2.3.0"
|
13
|
-
gem "bundler", "~> 1.0.0"
|
14
|
-
gem "jeweler", "~> 1.6.4"
|
15
|
-
gem "rcov", ">= 0"
|
16
|
-
end
|
3
|
+
# Specify your gem's dependencies in nitroapi.gemspec
|
4
|
+
gemspec
|
17
5
|
|
18
6
|
group :test do
|
19
7
|
gem "webmock"
|
20
|
-
end
|
8
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,22 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
nitroapi (0.0.6)
|
5
|
+
activesupport
|
6
|
+
json
|
7
|
+
|
1
8
|
GEM
|
2
|
-
remote:
|
9
|
+
remote: https://rubygems.org/
|
3
10
|
specs:
|
4
|
-
activesupport (3.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
json (1.5.3)
|
14
|
-
rake (0.8.7)
|
15
|
-
rcov (0.9.9)
|
11
|
+
activesupport (3.2.9)
|
12
|
+
i18n (~> 0.6)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
addressable (2.3.2)
|
15
|
+
crack (0.3.1)
|
16
|
+
diff-lcs (1.1.3)
|
17
|
+
i18n (0.6.1)
|
18
|
+
json (1.7.5)
|
19
|
+
multi_json (1.4.0)
|
16
20
|
rspec (2.3.0)
|
17
21
|
rspec-core (~> 2.3.0)
|
18
22
|
rspec-expectations (~> 2.3.0)
|
@@ -21,18 +25,20 @@ GEM
|
|
21
25
|
rspec-expectations (2.3.0)
|
22
26
|
diff-lcs (~> 1.1.2)
|
23
27
|
rspec-mocks (2.3.0)
|
24
|
-
|
25
|
-
|
28
|
+
simplecov (0.7.1)
|
29
|
+
multi_json (~> 1.0)
|
30
|
+
simplecov-html (~> 0.7.1)
|
31
|
+
simplecov-html (0.7.1)
|
32
|
+
webmock (1.9.0)
|
33
|
+
addressable (>= 2.2.7)
|
26
34
|
crack (>= 0.1.7)
|
27
35
|
|
28
36
|
PLATFORMS
|
29
37
|
ruby
|
30
38
|
|
31
39
|
DEPENDENCIES
|
32
|
-
|
33
|
-
|
34
|
-
jeweler (~> 1.6.4)
|
35
|
-
json
|
36
|
-
rcov
|
40
|
+
bundler (~> 1.2.2)
|
41
|
+
nitroapi!
|
37
42
|
rspec (~> 2.3.0)
|
43
|
+
simplecov (~> 0.7.1)
|
38
44
|
webmock
|
data/README.md
CHANGED
@@ -31,18 +31,24 @@ nitro.log_action "Video_Watch"
|
|
31
31
|
|
32
32
|
```ruby
|
33
33
|
nitro.action_history "Video_Watch"
|
34
|
-
nitro.challenge_progress "Watch 10 Videos"
|
34
|
+
nitro.challenge_progress :challenge => "Watch 10 Videos"
|
35
35
|
```
|
36
36
|
|
37
37
|
Installing
|
38
38
|
----------
|
39
|
-
add to your Gemfile
|
39
|
+
1) add to your Gemfile
|
40
|
+
|
40
41
|
```
|
41
|
-
gem 'nitroapi'
|
42
|
+
gem 'nitroapi'
|
42
43
|
```
|
43
44
|
|
45
|
+
2) Create a keys.json file with your api_key and secret (see keys.json.example file)
|
46
|
+
|
44
47
|
Change Log
|
45
48
|
----------
|
49
|
+
0.0.6
|
50
|
+
* add rules descriptions in challenge_progress call
|
51
|
+
|
46
52
|
0.0.5
|
47
53
|
|
48
54
|
#### Bug fixes:
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'bundler'
|
5
|
+
require "bundler/gem_tasks"
|
5
6
|
begin
|
6
7
|
Bundler.setup(:default, :development)
|
7
8
|
rescue Bundler::BundlerError => e
|
@@ -11,19 +12,6 @@ rescue Bundler::BundlerError => e
|
|
11
12
|
end
|
12
13
|
require 'rake'
|
13
14
|
|
14
|
-
require 'jeweler'
|
15
|
-
Jeweler::Tasks.new do |gem|
|
16
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
-
gem.name = "nitroapi"
|
18
|
-
gem.homepage = "http://github.com/Keasinc/nitroapi"
|
19
|
-
gem.license = "MIT"
|
20
|
-
gem.summary = "Api client for Bunchball's Nitro"
|
21
|
-
gem.description = "Api client for Bunchball's Nitro. http://www.bunchball.com/nitro/"
|
22
|
-
gem.authors = ["Gilad Buchman"]
|
23
|
-
# dependencies defined in Gemfile
|
24
|
-
end
|
25
|
-
Jeweler::RubygemsDotOrgTasks.new
|
26
|
-
|
27
15
|
require 'rspec/core'
|
28
16
|
require 'rspec/core/rake_task'
|
29
17
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
data/lib/nitro_api.rb
CHANGED
@@ -2,10 +2,12 @@ require 'json'
|
|
2
2
|
require 'digest/md5'
|
3
3
|
require 'net/http'
|
4
4
|
require 'nitro_api/challenge'
|
5
|
+
require 'nitro_api/rule'
|
6
|
+
require 'nitro_api/batch_calls'
|
7
|
+
require 'nitro_api/user_calls'
|
8
|
+
require 'nitro_api/site_calls'
|
5
9
|
|
6
10
|
module NitroApi
|
7
|
-
HOST = "http://sandbox.bunchball.net/nitro/"
|
8
|
-
ACCEPT = "json?"
|
9
11
|
|
10
12
|
class NitroError < StandardError
|
11
13
|
attr_accessor :code
|
@@ -16,130 +18,148 @@ module NitroApi
|
|
16
18
|
end
|
17
19
|
|
18
20
|
class NitroApi
|
19
|
-
attr_accessor :session
|
20
21
|
|
22
|
+
include BatchCalls
|
23
|
+
include SiteCalls
|
24
|
+
include UserCalls
|
25
|
+
|
26
|
+
attr_accessor :protocol, :host, :accepts, :session
|
27
|
+
|
28
|
+
# Initialize an instance
|
29
|
+
# user_id - The id for the user in the nitro system
|
30
|
+
# api_key - The API key for your Bunchball account
|
31
|
+
# secret - The secret for your Bunchball account
|
21
32
|
def initialize (user_id, api_key, secret)
|
22
|
-
# Required Parameters
|
23
33
|
@secret = secret
|
24
34
|
@api_key = api_key
|
25
35
|
@user = user_id
|
36
|
+
@batch = nil
|
37
|
+
|
38
|
+
self.protocol = 'https'
|
39
|
+
self.host = 'sandbox.bunchball.net'
|
40
|
+
self.accepts = 'json'
|
41
|
+
end
|
42
|
+
|
43
|
+
# Start a batch call to the nitro API. Uses the "batch.run" method defined
|
44
|
+
# here: https://bunchballnet-main.pbworks.com/w/page/53132313/batch_run
|
45
|
+
# returns - false if a batch is already being composed, true otherwise
|
46
|
+
def start_batch
|
47
|
+
if @batch.nil?
|
48
|
+
@batch = []
|
49
|
+
return true
|
50
|
+
end
|
51
|
+
|
52
|
+
return false
|
53
|
+
end
|
54
|
+
|
55
|
+
# Start a batch call to the nitro API. Uses the "batch.run" method defined
|
56
|
+
# here: https://bunchballnet-main.pbworks.com/w/page/53132313/batch_run
|
57
|
+
# If a batch is already being composed, an error will be raised.
|
58
|
+
def start_batch!
|
59
|
+
if not start_batch
|
60
|
+
raise NitroError.new, "A batch is already being composed."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Run the batch job. Requires that the 'start_batch' method has been called first.
|
65
|
+
def run_batch
|
66
|
+
make_run_batch_call
|
67
|
+
end
|
68
|
+
|
69
|
+
# Cancel the batch job. It clears out the any accumulated calls that have
|
70
|
+
# been made since first calling start_batch
|
71
|
+
def cancel_batch
|
72
|
+
@batch = nil
|
26
73
|
end
|
27
74
|
|
28
75
|
# Method for constructing a signature
|
29
|
-
def sign
|
30
|
-
time = Time.now.utc.to_i.to_s
|
76
|
+
def sign(time)
|
31
77
|
unencrypted_signature = @api_key + @secret + time + @user.to_s
|
32
78
|
to_digest = unencrypted_signature + unencrypted_signature.length.to_s
|
33
79
|
return Digest::MD5.hexdigest(to_digest)
|
34
80
|
end
|
35
81
|
|
82
|
+
# Login the user to the nitro system
|
36
83
|
def login
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def log_action(actions, opts={})
|
49
|
-
value = opts.delete(:value)
|
50
|
-
user_id = opts.delete(:other_user)
|
51
|
-
params = {
|
52
|
-
:tags => actions.is_a?(Array) ? actions.join(",") : actions,
|
53
|
-
:sessionKey => @session,
|
54
|
-
:method => 'user.logAction'
|
55
|
-
}
|
56
|
-
params[:value] = value.to_s if value && !value.to_s.empty?
|
57
|
-
params[:userId] = user_id if user_id && !user_id.to_s.empty
|
58
|
-
make_call(params)
|
59
|
-
end
|
60
|
-
|
61
|
-
def challenge_progress(opts={})
|
62
|
-
params = {
|
63
|
-
:sessionKey => @session,
|
64
|
-
:method => 'user.getChallengeProgress'
|
65
|
-
}
|
66
|
-
challenge = opts[:challenge]
|
67
|
-
params['challengeName'] = challenge if challenge and !challenge.to_s.empty?
|
68
|
-
params['showOnlyTrophies'] = opts.delete(:trophies_only) || false
|
69
|
-
params['folder'] = opts.delete(:folder) if opts.has_key?(:folder)
|
70
|
-
|
71
|
-
response = make_call(params)
|
72
|
-
|
73
|
-
if valid_response?(response['challenges'])
|
74
|
-
items = ensure_array(response['challenges']['Challenge'])
|
75
|
-
items.reduce([]) do |challenges, item|
|
76
|
-
challenge = Challenge.new
|
77
|
-
challenge.name = item["name"]
|
78
|
-
challenge.description = item["description"]
|
79
|
-
challenge.full_url = item["fullUrl"]
|
80
|
-
challenge.thumb_url = item["thumbUrl"]
|
81
|
-
challenge.completed = item["completionCount"].to_i
|
82
|
-
|
83
|
-
challenges<< challenge
|
84
|
-
end
|
85
|
-
end
|
84
|
+
make_login_call
|
85
|
+
end
|
86
|
+
|
87
|
+
# Log actions to the nitro system
|
88
|
+
# @param [String, Array[String]] actions The (list of) action tag(s) to log
|
89
|
+
# @param [Hash] opts The options. They are:
|
90
|
+
# :value - the value to send
|
91
|
+
# :other_user - the ID of the user to which the action should be applied
|
92
|
+
# :session_key - the session key to use for this call
|
93
|
+
def log_action actions, opts={}
|
94
|
+
make_log_action_call actions, opts
|
86
95
|
end
|
87
96
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
}
|
95
|
-
make_call(params)
|
97
|
+
def challenge_progress opts={}
|
98
|
+
make_challenge_progress_call opts
|
99
|
+
end
|
100
|
+
|
101
|
+
def award_challenge challenge
|
102
|
+
make_award_challenge_call challenge
|
96
103
|
end
|
97
104
|
|
98
105
|
def action_history actions=[]
|
99
|
-
|
100
|
-
:sessionKey => @session,
|
101
|
-
:method => 'user.getActionHistory'
|
102
|
-
}
|
103
|
-
if actions && !actions.empty?
|
104
|
-
params[:tags] = actions.is_a?(Array) ? actions.join(",") : actions
|
105
|
-
end
|
106
|
-
response = make_call(params)
|
107
|
-
if valid_response?(response['ActionHistoryRecord'])
|
108
|
-
items = ensure_array(response['ActionHistoryRecord']['ActionHistoryItem'])
|
109
|
-
items.reduce([]) do
|
110
|
-
|history, item|
|
111
|
-
history<< {:tags => item['tags'],
|
112
|
-
:ts => Time.at(item['ts'].to_i),
|
113
|
-
:value => item['value'].to_i
|
114
|
-
}
|
115
|
-
end
|
116
|
-
else
|
117
|
-
[]
|
118
|
-
end
|
106
|
+
make_action_history_call actions
|
119
107
|
end
|
120
108
|
|
121
109
|
def join_group group
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
110
|
+
make_join_group_call group
|
111
|
+
end
|
112
|
+
|
113
|
+
# Get the points for a user.
|
114
|
+
# @param [Hash] opts The list of options. The keys in the list are the
|
115
|
+
# snake_case versions names of the parameters to the getPointsBalance
|
116
|
+
# API call as defined here:
|
117
|
+
# https://bunchballnet-main.pbworks.com/w/page/53132548/user_getPointsBalance
|
118
|
+
def get_points_balance opts={}
|
119
|
+
make_get_points_balance_call opts
|
120
|
+
end
|
121
|
+
|
122
|
+
# Get the list of point leaders for the specified options.
|
123
|
+
# opts - The list of options. The keys in the list are the snake_case
|
124
|
+
# versions names of the parameters to the getPointsLeaders API call
|
125
|
+
# as defined here:
|
126
|
+
# https://bunchballnet-main.pbworks.com/w/page/53132408/site_getPointsLeaders
|
127
|
+
def get_points_leaders opts
|
128
|
+
make_points_leaders_call opts
|
129
|
+
end
|
130
|
+
|
131
|
+
def base_url
|
132
|
+
"#{self.protocol}://#{self.host}/nitro/#{self.accepts}"
|
128
133
|
end
|
129
134
|
|
130
135
|
private
|
131
136
|
|
132
|
-
def valid_response?
|
137
|
+
def valid_response? obj
|
133
138
|
obj.is_a?(Array) || obj.is_a?(Hash)
|
134
139
|
end
|
135
140
|
|
136
|
-
def ensure_array
|
141
|
+
def ensure_array items
|
137
142
|
items.is_a?(Array) ? items : [items]
|
138
143
|
end
|
139
144
|
|
140
|
-
def make_call
|
141
|
-
|
142
|
-
|
145
|
+
def make_call params, method=:get
|
146
|
+
if @batch.nil?
|
147
|
+
return really_make_call params, method
|
148
|
+
else
|
149
|
+
@batch << { params: params, method: method }
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def really_make_call params, method
|
155
|
+
if :get == method
|
156
|
+
request = "#{base_url}?#{to_query(params)}"
|
157
|
+
data = Net::HTTP.get(URI.parse(request))
|
158
|
+
elsif :post == method
|
159
|
+
data = Net::HTTP.post_form(URI.parse(base_url), params)
|
160
|
+
data = data.body
|
161
|
+
end
|
162
|
+
|
143
163
|
json = JSON.parse(data)
|
144
164
|
response = json["Nitro"]
|
145
165
|
error = response["Error"]
|