koala 1.1.0rc2 → 1.1.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/.travis.yml +8 -0
- data/CHANGELOG +12 -6
- data/Gemfile +4 -0
- data/koala.gemspec +5 -5
- data/lib/koala/batch_operation.rb +74 -0
- data/lib/koala/graph_api.rb +78 -117
- data/lib/koala/graph_batch_api.rb +87 -0
- data/lib/koala/graph_collection.rb +54 -0
- data/lib/koala/http_services/net_http_service.rb +31 -26
- data/lib/koala/http_services/typhoeus_service.rb +4 -4
- data/lib/koala/http_services.rb +5 -3
- data/lib/koala/oauth.rb +3 -3
- data/lib/koala/rest_api.rb +1 -1
- data/lib/koala/uploadable_io.rb +122 -90
- data/lib/koala.rb +10 -5
- data/readme.md +39 -32
- data/spec/cases/api_base_spec.rb +2 -2
- data/spec/cases/graph_api_batch_spec.rb +171 -162
- data/spec/cases/http_services/http_service_spec.rb +27 -27
- data/spec/cases/http_services/net_http_service_spec.rb +169 -103
- data/spec/cases/oauth_spec.rb +1 -1
- data/spec/cases/realtime_updates_spec.rb +3 -3
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/mock_facebook_responses.yml +33 -22
- data/spec/spec_helper.rb +2 -1
- data/spec/support/graph_api_shared_examples.rb +79 -35
- data/spec/support/json_testing_fix.rb +18 -0
- data/spec/support/mock_http_service.rb +3 -0
- data/spec/support/rest_api_shared_examples.rb +2 -2
- data/spec/support/setup_mocks_or_live.rb +1 -2
- metadata +13 -6
- data/lib/koala/graph_api_batch.rb +0 -151
|
@@ -166,44 +166,87 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
|
166
166
|
@temporary_object_id.should_not be_nil
|
|
167
167
|
end
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
result = @api.put_picture(file, content_type)
|
|
174
|
-
@temporary_object_id = result["id"]
|
|
175
|
-
@temporary_object_id.should_not be_nil
|
|
176
|
-
end
|
|
169
|
+
describe ".put_picture" do
|
|
170
|
+
it "should be able to post photos to the user's wall with an open file object" do
|
|
171
|
+
content_type = "image/jpg"
|
|
172
|
+
file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))
|
|
177
173
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
174
|
+
result = @api.put_picture(file, content_type)
|
|
175
|
+
@temporary_object_id = result["id"]
|
|
176
|
+
@temporary_object_id.should_not be_nil
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "uses the base HTTP service if the upload is a StringIO or similar" do
|
|
180
|
+
source = stub("UploadIO")
|
|
181
|
+
Koala::UploadableIO.stub(:new).and_return(source)
|
|
182
|
+
source.stub(:requires_base_http_service).and_return(true)
|
|
183
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:http_service => Koala.base_http_service)).and_return(Koala::Response.new(200, "[]", {}))
|
|
184
|
+
@api.put_picture(StringIO.new)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "should be able to post photos to the user's wall without an open file object" do
|
|
188
|
+
content_type = "image/jpg",
|
|
189
|
+
file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
|
|
185
190
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
result = @api.put_picture(file_path, content_type)
|
|
192
|
+
@temporary_object_id = result["id"]
|
|
193
|
+
@temporary_object_id.should_not be_nil
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "should be able to verify a photo posted to a user's wall" do
|
|
197
|
+
content_type = "image/jpg",
|
|
198
|
+
file_path = File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg")
|
|
199
|
+
|
|
200
|
+
expected_message = "This is the test message"
|
|
201
|
+
|
|
202
|
+
result = @api.put_picture(file_path, content_type, :message => expected_message)
|
|
203
|
+
@temporary_object_id = result["id"]
|
|
204
|
+
@temporary_object_id.should_not be_nil
|
|
205
|
+
|
|
206
|
+
get_result = @api.get_object(@temporary_object_id)
|
|
207
|
+
get_result["name"].should == expected_message
|
|
208
|
+
end
|
|
193
209
|
end
|
|
210
|
+
|
|
211
|
+
describe ".put_video" do
|
|
212
|
+
before :each do
|
|
213
|
+
@cat_movie = File.join(File.dirname(__FILE__), "..", "fixtures", "cat.m4v")
|
|
214
|
+
@content_type = "video/mpeg4"
|
|
215
|
+
end
|
|
194
216
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
@temporary_object_id = result["id"]
|
|
203
|
-
@temporary_object_id.should_not be_nil
|
|
217
|
+
it "should set options[:video] to true" do
|
|
218
|
+
source = stub("UploadIO")
|
|
219
|
+
Koala::UploadableIO.stub(:new).and_return(source)
|
|
220
|
+
source.stub(:requires_base_http_service).and_return(false)
|
|
221
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:video => true)).and_return(Koala::Response.new(200, "[]", {}))
|
|
222
|
+
@api.put_video("foo")
|
|
223
|
+
end
|
|
204
224
|
|
|
205
|
-
|
|
206
|
-
|
|
225
|
+
it "should be able to post videos to the user's wall with an open file object" do
|
|
226
|
+
file = File.open(@cat_movie)
|
|
227
|
+
|
|
228
|
+
result = @api.put_video(file, @content_type)
|
|
229
|
+
@temporary_object_id = result["id"]
|
|
230
|
+
@temporary_object_id.should_not be_nil
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it "uses the base HTTP service if the upload is a StringIO or similar" do
|
|
234
|
+
source = stub("UploadIO")
|
|
235
|
+
Koala::UploadableIO.stub(:new).and_return(source)
|
|
236
|
+
source.stub(:requires_base_http_service).and_return(true)
|
|
237
|
+
Koala.should_receive(:make_request).with(anything, anything, anything, hash_including(:http_service => Koala.base_http_service)).and_return(Koala::Response.new(200, "[]", {}))
|
|
238
|
+
@api.put_video(StringIO.new)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it "should be able to post videos to the user's wall without an open file object" do
|
|
242
|
+
result = @api.put_video(@cat_movie, @content_type)
|
|
243
|
+
@temporary_object_id = result["id"]
|
|
244
|
+
@temporary_object_id.should_not be_nil
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# note: Facebook doesn't post videos immediately to the wall, due to processing time
|
|
248
|
+
# during which get_object(video_id) will return false
|
|
249
|
+
# hence we can't do the same verify test we do for photos
|
|
207
250
|
end
|
|
208
251
|
|
|
209
252
|
it "should be able to verify a message with an attachment posted to a feed" do
|
|
@@ -267,6 +310,7 @@ shared_examples_for "Koala GraphAPI with an access token" do
|
|
|
267
310
|
:search => 3,
|
|
268
311
|
# methods that have special arguments
|
|
269
312
|
:put_picture => ["x.jpg", "image/jpg", {}, "me"],
|
|
313
|
+
:put_video => ["x.mp4", "video/mpeg4", {}, "me"],
|
|
270
314
|
:get_objects => [["x"], {}]
|
|
271
315
|
}.each_pair do |method_name, params|
|
|
272
316
|
it "should pass http options through for #{method_name}" do
|
|
@@ -343,8 +387,8 @@ shared_examples_for "Koala GraphAPI with GraphCollection" do
|
|
|
343
387
|
end
|
|
344
388
|
|
|
345
389
|
it "should have a read-only paging attribute" do
|
|
346
|
-
|
|
347
|
-
|
|
390
|
+
@result.methods.map(&:to_sym).should include(:paging)
|
|
391
|
+
@result.methods.map(&:to_sym).should_not include(:paging=)
|
|
348
392
|
end
|
|
349
393
|
|
|
350
394
|
describe "when getting a whole page" do
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# when testing across Ruby versions, we found that JSON string creation inconsistently ordered keys
|
|
2
|
+
# which is a problem because our mock testing service ultimately matches strings to see if requests are mocked
|
|
3
|
+
# this fix solves that problem by ensuring all hashes are created with a consistent key order every time
|
|
4
|
+
|
|
5
|
+
module MultiJson
|
|
6
|
+
self.engine = :ok_json
|
|
7
|
+
|
|
8
|
+
def encode_with_ordering(object)
|
|
9
|
+
# if it's a hash, recreate it with k/v pairs inserted in sorted-by-key order
|
|
10
|
+
# (for some reason, REE 1.8.7 fails if we don't assign the ternary result as a local variable
|
|
11
|
+
# separate from calling encode_original)
|
|
12
|
+
new_object = object.is_a?(Hash) ? object.keys.sort.inject({}) {|hash, k| hash[k] = object[k]; hash} : object
|
|
13
|
+
encode_original(new_object)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
alias_method :encode_original, :encode
|
|
17
|
+
alias_method :encode, :encode_with_ordering
|
|
18
|
+
end
|
|
@@ -5,6 +5,9 @@ module Koala
|
|
|
5
5
|
module MockHTTPService
|
|
6
6
|
include Koala::HTTPService
|
|
7
7
|
|
|
8
|
+
# fix our specs to use ok_json, so we always get the same results from to_json
|
|
9
|
+
MultiJson.engine = :ok_json
|
|
10
|
+
|
|
8
11
|
# Mocks all HTTP requests for with koala_spec_with_mocks.rb
|
|
9
12
|
# Mocked values to be included in TEST_DATA used in specs
|
|
10
13
|
ACCESS_TOKEN = '*'
|
|
@@ -154,13 +154,13 @@ shared_examples_for "Koala RestAPI" do
|
|
|
154
154
|
"fql.multiquery", anything, anything
|
|
155
155
|
).and_return({})
|
|
156
156
|
|
|
157
|
-
@api.fql_multiquery
|
|
157
|
+
@api.fql_multiquery 'query string'
|
|
158
158
|
end
|
|
159
159
|
|
|
160
160
|
it "should pass a queries argument" do
|
|
161
161
|
queries = stub('query string')
|
|
162
162
|
queries_json = "some JSON"
|
|
163
|
-
|
|
163
|
+
MultiJson.stub(:encode).with(queries).and_return(queries_json)
|
|
164
164
|
|
|
165
165
|
@api.should_receive(:rest_call).with(
|
|
166
166
|
anything,
|
|
@@ -4,8 +4,7 @@ module KoalaTest
|
|
|
4
4
|
print "Validating permissions for live testing..."
|
|
5
5
|
# make sure we have the necessary permissions
|
|
6
6
|
api = Koala::Facebook::GraphAndRestAPI.new(token)
|
|
7
|
-
|
|
8
|
-
perms = api.fql_query("select read_stream, publish_stream, user_photos, read_insights from permissions where uid = #{uid}")[0]
|
|
7
|
+
perms = api.fql_query("select read_stream, publish_stream, user_photos, user_videos, read_insights from permissions where uid = me()")[0]
|
|
9
8
|
perms.each_pair do |perm, value|
|
|
10
9
|
if value == (perm == "read_insights" ? 1 : 0) # live testing depends on insights calls failing
|
|
11
10
|
puts "failed!\n" # put a new line after the print above
|
metadata
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: koala
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
prerelease:
|
|
5
|
-
version: 1.1.
|
|
4
|
+
prerelease:
|
|
5
|
+
version: 1.1.0
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Alex Koppel, Chris Baclig, Rafi Jacoby, Context Optional
|
|
@@ -10,11 +10,11 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
12
|
|
|
13
|
-
date: 2011-
|
|
13
|
+
date: 2011-07-18 00:00:00 +02:00
|
|
14
14
|
default_executable:
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
|
-
name:
|
|
17
|
+
name: multi_json
|
|
18
18
|
requirement: &id001 !ruby/object:Gem::Requirement
|
|
19
19
|
none: false
|
|
20
20
|
requirements:
|
|
@@ -80,6 +80,7 @@ extra_rdoc_files:
|
|
|
80
80
|
files:
|
|
81
81
|
- .autotest
|
|
82
82
|
- .gitignore
|
|
83
|
+
- .travis.yml
|
|
83
84
|
- CHANGELOG
|
|
84
85
|
- Gemfile
|
|
85
86
|
- LICENSE
|
|
@@ -88,8 +89,10 @@ files:
|
|
|
88
89
|
- autotest/discover.rb
|
|
89
90
|
- koala.gemspec
|
|
90
91
|
- lib/koala.rb
|
|
92
|
+
- lib/koala/batch_operation.rb
|
|
91
93
|
- lib/koala/graph_api.rb
|
|
92
|
-
- lib/koala/
|
|
94
|
+
- lib/koala/graph_batch_api.rb
|
|
95
|
+
- lib/koala/graph_collection.rb
|
|
93
96
|
- lib/koala/http_services.rb
|
|
94
97
|
- lib/koala/http_services/net_http_service.rb
|
|
95
98
|
- lib/koala/http_services/typhoeus_service.rb
|
|
@@ -113,10 +116,12 @@ files:
|
|
|
113
116
|
- spec/cases/test_users_spec.rb
|
|
114
117
|
- spec/cases/uploadable_io_spec.rb
|
|
115
118
|
- spec/fixtures/beach.jpg
|
|
119
|
+
- spec/fixtures/cat.m4v
|
|
116
120
|
- spec/fixtures/facebook_data.yml
|
|
117
121
|
- spec/fixtures/mock_facebook_responses.yml
|
|
118
122
|
- spec/spec_helper.rb
|
|
119
123
|
- spec/support/graph_api_shared_examples.rb
|
|
124
|
+
- spec/support/json_testing_fix.rb
|
|
120
125
|
- spec/support/live_testing_data_helper.rb
|
|
121
126
|
- spec/support/mock_http_service.rb
|
|
122
127
|
- spec/support/rest_api_shared_examples.rb
|
|
@@ -139,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
139
144
|
requirements:
|
|
140
145
|
- - ">="
|
|
141
146
|
- !ruby/object:Gem::Version
|
|
142
|
-
hash: -
|
|
147
|
+
hash: -702788258280667645
|
|
143
148
|
segments:
|
|
144
149
|
- 0
|
|
145
150
|
version: "0"
|
|
@@ -171,10 +176,12 @@ test_files:
|
|
|
171
176
|
- spec/cases/test_users_spec.rb
|
|
172
177
|
- spec/cases/uploadable_io_spec.rb
|
|
173
178
|
- spec/fixtures/beach.jpg
|
|
179
|
+
- spec/fixtures/cat.m4v
|
|
174
180
|
- spec/fixtures/facebook_data.yml
|
|
175
181
|
- spec/fixtures/mock_facebook_responses.yml
|
|
176
182
|
- spec/spec_helper.rb
|
|
177
183
|
- spec/support/graph_api_shared_examples.rb
|
|
184
|
+
- spec/support/json_testing_fix.rb
|
|
178
185
|
- spec/support/live_testing_data_helper.rb
|
|
179
186
|
- spec/support/mock_http_service.rb
|
|
180
187
|
- spec/support/rest_api_shared_examples.rb
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
module Koala
|
|
2
|
-
module Facebook
|
|
3
|
-
class BatchOperation
|
|
4
|
-
attr_reader :access_token, :http_options, :post_processing, :files
|
|
5
|
-
|
|
6
|
-
def initialize(options = {})
|
|
7
|
-
@args = (options[:args] || {}).dup # because we modify it below
|
|
8
|
-
@access_token = options[:access_token]
|
|
9
|
-
@http_options = (options[:http_options] || {}).dup # dup because we modify it below
|
|
10
|
-
@batch_args = @http_options.delete(:batch_args) || {}
|
|
11
|
-
@url = options[:url]
|
|
12
|
-
@method = options[:method].to_sym
|
|
13
|
-
@post_processing = options[:post_processing]
|
|
14
|
-
|
|
15
|
-
process_binary_args
|
|
16
|
-
|
|
17
|
-
raise Koala::KoalaError, "Batch operations require an access token, none provided." unless @access_token
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def to_batch_params(main_access_token)
|
|
21
|
-
# set up the arguments
|
|
22
|
-
args_string = Koala.http_service.encode_params(@access_token == main_access_token ? @args : @args.merge(:access_token => @access_token))
|
|
23
|
-
|
|
24
|
-
response = {
|
|
25
|
-
:method => @method,
|
|
26
|
-
:relative_url => @url,
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
# handle batch-level arguments, such as name, depends_on, and attached_files
|
|
30
|
-
@batch_args[:attached_files] = @files.keys.join(",") if @files
|
|
31
|
-
response.merge!(@batch_args) if @batch_args
|
|
32
|
-
|
|
33
|
-
# for get and delete, we append args to the URL string
|
|
34
|
-
# otherwise, they go in the body
|
|
35
|
-
if args_string.length > 0
|
|
36
|
-
if args_in_url?
|
|
37
|
-
response[:relative_url] += (@url =~ /\?/ ? "&" : "?") + args_string if args_string.length > 0
|
|
38
|
-
else
|
|
39
|
-
response[:body] = args_string if args_string.length > 0
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
response
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
protected
|
|
47
|
-
|
|
48
|
-
def process_binary_args
|
|
49
|
-
# collect binary files
|
|
50
|
-
@args.each_pair do |key, value|
|
|
51
|
-
if UploadableIO.binary_content?(value)
|
|
52
|
-
@files ||= {}
|
|
53
|
-
# we use object_id to ensure unique file identifiers across multiple batch operations
|
|
54
|
-
# remove it from the original hash and add it to the file store
|
|
55
|
-
id = "file#{GraphAPI.batch_calls.length}_#{@files.keys.length}"
|
|
56
|
-
@files[id] = @args.delete(key).is_a?(UploadableIO) ? value : UploadableIO.new(value)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def args_in_url?
|
|
62
|
-
@method == :get || @method == :delete
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
module GraphAPIBatchMethods
|
|
67
|
-
def self.included(base)
|
|
68
|
-
base.class_eval do
|
|
69
|
-
# batch mode flags
|
|
70
|
-
def self.batch_mode?
|
|
71
|
-
!!@batch_mode
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def self.batch_calls
|
|
75
|
-
raise KoalaError, "GraphAPI.batch_calls accessed when not in batch block!" unless batch_mode?
|
|
76
|
-
@batch_calls
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def self.batch(http_options = {}, &block)
|
|
80
|
-
@batch_mode = true
|
|
81
|
-
@batch_http_options = http_options
|
|
82
|
-
@batch_calls = []
|
|
83
|
-
yield
|
|
84
|
-
begin
|
|
85
|
-
results = batch_api(@batch_calls)
|
|
86
|
-
ensure
|
|
87
|
-
@batch_mode = false
|
|
88
|
-
end
|
|
89
|
-
results
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def self.batch_api(batch_calls)
|
|
93
|
-
return [] unless batch_calls.length > 0
|
|
94
|
-
# Facebook requires a top-level access token
|
|
95
|
-
|
|
96
|
-
# Get the access token for the user and start building a hash to store params
|
|
97
|
-
# Turn the call args collected into what facebook expects
|
|
98
|
-
args = {}
|
|
99
|
-
access_token = args["access_token"] = batch_calls.first.access_token
|
|
100
|
-
args['batch'] = batch_calls.map { |batch_op|
|
|
101
|
-
args.merge!(batch_op.files) if batch_op.files
|
|
102
|
-
batch_op.to_batch_params(access_token)
|
|
103
|
-
}.to_json
|
|
104
|
-
|
|
105
|
-
# Make the POST request for the batch call
|
|
106
|
-
# batch operations have to go over SSL, but since there's an access token, that secures that
|
|
107
|
-
result = Koala.make_request('/', args, 'post', @batch_http_options)
|
|
108
|
-
# Raise an error if we get a 500
|
|
109
|
-
raise APIError.new("type" => "HTTP #{result.status.to_s}", "message" => "Response body: #{result.body}") if result.status >= 500
|
|
110
|
-
|
|
111
|
-
response = JSON.parse(result.body.to_s)
|
|
112
|
-
# raise an error if we get a Batch API error message
|
|
113
|
-
raise APIError.new("type" => "Error #{response["error"]}", "message" => response["error_description"]) if response.is_a?(Hash) && response["error"]
|
|
114
|
-
|
|
115
|
-
# otherwise, map the results with post-processing included
|
|
116
|
-
index = 0 # keep compat with ruby 1.8 - no with_index for map
|
|
117
|
-
response.map do |call_result|
|
|
118
|
-
# Get the options hash
|
|
119
|
-
batch_op = batch_calls[index]
|
|
120
|
-
index += 1
|
|
121
|
-
|
|
122
|
-
if call_result
|
|
123
|
-
# (see note in regular api method about JSON parsing)
|
|
124
|
-
body = JSON.parse("[#{call_result['body'].to_s}]")[0]
|
|
125
|
-
unless call_result["code"].to_i >= 500 || error = GraphAPI.check_response(body)
|
|
126
|
-
# Get the HTTP component they want
|
|
127
|
-
data = case batch_op.http_options[:http_component]
|
|
128
|
-
when :status
|
|
129
|
-
call_result["code"].to_i
|
|
130
|
-
when :headers
|
|
131
|
-
# facebook returns the headers as an array of k/v pairs, but we want a regular hash
|
|
132
|
-
call_result['headers'].inject({}) { |headers, h| headers[h['name']] = h['value']; headers}
|
|
133
|
-
else
|
|
134
|
-
body
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# process it if we are given a block to process with
|
|
138
|
-
batch_op.post_processing ? batch_op.post_processing.call(data) : data
|
|
139
|
-
else
|
|
140
|
-
error || APIError.new({"type" => "HTTP #{call_result["code"].to_s}", "message" => "Response body: #{body}"})
|
|
141
|
-
end
|
|
142
|
-
else
|
|
143
|
-
nil
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|