koala 3.0.0.beta1 → 3.0.0.beta2
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/changelog.md +19 -3
- data/koala.gemspec +3 -0
- data/lib/koala/api.rb +47 -19
- data/lib/koala/api/{graph_api.rb → graph_api_methods.rb} +9 -59
- data/lib/koala/api/graph_batch_api.rb +107 -62
- data/lib/koala/http_service/request.rb +1 -5
- data/lib/koala/http_service/response.rb +6 -0
- data/lib/koala/test_users.rb +5 -4
- data/lib/koala/version.rb +1 -1
- data/spec/cases/api_spec.rb +79 -51
- data/spec/cases/graph_api_batch_spec.rb +22 -22
- data/spec/cases/graph_api_spec.rb +15 -10
- data/spec/cases/graph_collection_spec.rb +3 -3
- data/spec/cases/http_service/response_spec.rb +24 -0
- data/spec/cases/test_users_spec.rb +11 -0
- data/spec/fixtures/cat.m4v +0 -0
- data/spec/fixtures/facebook_data.yml +1 -1
- data/spec/fixtures/mock_facebook_responses.yml +25 -28
- data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +97 -0
- data/spec/integration/graph_collection_spec.rb +8 -5
- data/spec/support/graph_api_shared_examples.rb +142 -199
- data/spec/support/koala_test.rb +2 -4
- data/spec/support/mock_http_service.rb +3 -3
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18d5d8c95bece65d5f4bab2640d75645dc5fb343
|
4
|
+
data.tar.gz: 6ec125b20dea63584e6dd69fc02ecd08f0800ce2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31a10322d86c4c49bd877ad5891cde67db496e506c6b8936d8cf3e67b6bc82e6faed1fe1e93f02dcd123ea8aee77026adc681a3b197006335e7d2f8aac40d968
|
7
|
+
data.tar.gz: f8d69365d42baf15acead1fcc5e38e334084dc49539358189aee046bf611d9c7761ec4ffeac690b07d3a647116ef81ac1e0fdfa2bc1d11010c5ae30dc239a189
|
data/.travis.yml
CHANGED
data/changelog.md
CHANGED
@@ -1,28 +1,44 @@
|
|
1
1
|
v3.0.0
|
2
2
|
======
|
3
3
|
|
4
|
-
Key breaking changes
|
4
|
+
**Key breaking changes:**
|
5
5
|
|
6
|
+
* Koala now requires Ruby 2.1+ (or equivalent for JRuby, etc.)
|
7
|
+
* API#api now returns a Koala::HTTPService::Response object; graph_call handles further processing
|
8
|
+
* GraphBatchAPI no longer inherits from API (the interface is otherwise unchanged)
|
9
|
+
* Empty response bodies in batch API calls will raise a JSON::ParserError rather than returning nil
|
6
10
|
* HTTPService.make_request now requires an HTTPService::Request object (Koala.make_request does
|
7
11
|
not)
|
8
12
|
* HTTPService behavior *should not* change, but in edge cases might. (If so, please let me know.)
|
9
|
-
*
|
13
|
+
* API#search now requires a "type"/:type argument, matching Facebook's behavior (improving their
|
14
|
+
cryptic error message)
|
15
|
+
|
16
|
+
Updated features:
|
17
|
+
|
18
|
+
* TestUser#befriend will provide the appsecret_proof if a secret is set (thanks, kwasimensah!)
|
19
|
+
* API#search now requires an object type parameter to be included, matching Facebook's API (#575)
|
10
20
|
|
11
21
|
Removed features:
|
12
22
|
|
13
23
|
* Removed support for the Rest API, since Facebook removed support for it (#568)
|
14
24
|
* Removed support for FQL, which Facebook removed on August 8, 2016 (#569)
|
15
25
|
* Removed legacy duplication of serveral constants in the Koala module (#569)
|
26
|
+
* Removed API#get_comments_for_urls, which pointed to a no-longer-extant endpoint(#570)
|
16
27
|
|
17
28
|
Internal improvements:
|
18
29
|
|
19
30
|
* Completely rewrote HTTPService.make_request and several others, extracting most logic into
|
20
31
|
HTTPService::Request (#566)
|
32
|
+
* API#api now returns a Koala::HTTPService::Response object (#584)
|
33
|
+
* GraphBatchAPI no longer inherits from API (#580)
|
34
|
+
* GraphBatchAPI has been refactored to be simpler and more readable (thanks, acuppy!) (#551)
|
21
35
|
* Use the more secure JSON.parse instead of JSON.load (thanks, lautis!) (#567)
|
36
|
+
* Use JSON's quirks_mode option to remove hacky JSON hack (#573 -- thanks sakuro for the
|
37
|
+
suggestion!)
|
22
38
|
|
23
39
|
Testing improvements:
|
24
40
|
|
25
|
-
* Fixed a bunch of failing specs
|
41
|
+
* Fixed a bunch of failing mocked specs
|
26
42
|
|
27
43
|
v2.5.0
|
28
44
|
======
|
data/koala.gemspec
CHANGED
@@ -21,6 +21,9 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.extra_rdoc_files = ["readme.md", "changelog.md"]
|
22
22
|
gem.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Koala"]
|
23
23
|
|
24
|
+
gem.required_ruby_version = '>= 2.1'
|
25
|
+
|
24
26
|
gem.add_runtime_dependency("faraday")
|
25
27
|
gem.add_runtime_dependency("addressable")
|
28
|
+
gem.add_runtime_dependency("json", ">= 2.0")
|
26
29
|
end
|
data/lib/koala/api.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# graph_batch_api and legacy are required at the bottom, since they depend on API being defined
|
2
|
-
require 'koala/api/
|
2
|
+
require 'koala/api/graph_api_methods'
|
3
3
|
require 'koala/api/graph_collection'
|
4
4
|
require 'openssl'
|
5
5
|
|
@@ -24,6 +24,45 @@ module Koala
|
|
24
24
|
|
25
25
|
include GraphAPIMethods
|
26
26
|
|
27
|
+
# Make a call directly to the Graph API.
|
28
|
+
# (See any of the other methods for example invocations.)
|
29
|
+
#
|
30
|
+
# @param path the Graph API path to query (no leading / needed)
|
31
|
+
# @param args (see #get_object)
|
32
|
+
# @param verb the type of HTTP request to make (get, post, delete, etc.)
|
33
|
+
# @options (see #get_object)
|
34
|
+
#
|
35
|
+
# @yield response when making a batch API call, you can pass in a block
|
36
|
+
# that parses the results, allowing for cleaner code.
|
37
|
+
# The block's return value is returned in the batch results.
|
38
|
+
# See the code for {#get_picture} for examples.
|
39
|
+
# (Not needed in regular calls; you'll probably rarely use this.)
|
40
|
+
#
|
41
|
+
# @raise [Koala::Facebook::APIError] if Facebook returns an error
|
42
|
+
#
|
43
|
+
# @return the result from Facebook
|
44
|
+
def graph_call(path, args = {}, verb = "get", options = {}, &post_processing)
|
45
|
+
# enable appsecret_proof by default
|
46
|
+
options = {:appsecret_proof => true}.merge(options) if @app_secret
|
47
|
+
response = api(path, args, verb, options)
|
48
|
+
|
49
|
+
error = GraphErrorChecker.new(response.status, response.body, response.headers).error_if_appropriate
|
50
|
+
raise error if error
|
51
|
+
|
52
|
+
# if we want a component other than the body (e.g. redirect header for images), provide that
|
53
|
+
http_component = options[:http_component]
|
54
|
+
desired_data = if options[:http_component]
|
55
|
+
http_component == :response ? response : response.send(http_component)
|
56
|
+
else
|
57
|
+
# turn this into a GraphCollection if it's pageable
|
58
|
+
API::GraphCollection.evaluate(response.data, self)
|
59
|
+
end
|
60
|
+
|
61
|
+
# now process as appropriate for the given call (get picture header, etc.)
|
62
|
+
post_processing ? post_processing.call(desired_data) : desired_data
|
63
|
+
end
|
64
|
+
|
65
|
+
|
27
66
|
# Makes a request to the appropriate Facebook API.
|
28
67
|
# @note You'll rarely need to call this method directly.
|
29
68
|
#
|
@@ -42,14 +81,10 @@ module Koala
|
|
42
81
|
# @option options [Boolean] :beta use Facebook's beta tier
|
43
82
|
# @option options [Boolean] :use_ssl force SSL for this request, even if it's tokenless.
|
44
83
|
# (All API requests with access tokens use SSL.)
|
45
|
-
# @param error_checking_block a block to evaluate the response status for additional JSON-encoded errors
|
46
|
-
#
|
47
|
-
# @yield The response for evaluation
|
48
|
-
#
|
49
84
|
# @raise [Koala::Facebook::ServerError] if Facebook returns an error (response status >= 500)
|
50
85
|
#
|
51
|
-
# @return
|
52
|
-
def api(path, args = {}, verb = "get", options = {}
|
86
|
+
# @return a Koala::HTTPService::Response object representing the returned Facebook data
|
87
|
+
def api(path, args = {}, verb = "get", options = {})
|
53
88
|
# we make a copy of args so the modifications (added access_token & appsecret_proof)
|
54
89
|
# do not affect the received argument
|
55
90
|
args = args.dup
|
@@ -58,6 +93,7 @@ module Koala
|
|
58
93
|
# This is explicitly needed in batch requests so GraphCollection
|
59
94
|
# results preserve any specific access tokens provided
|
60
95
|
args["access_token"] ||= @access_token || @app_access_token if @access_token || @app_access_token
|
96
|
+
|
61
97
|
if options.delete(:appsecret_proof) && args["access_token"] && @app_secret
|
62
98
|
args["appsecret_proof"] = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), @app_secret, args["access_token"])
|
63
99
|
end
|
@@ -75,18 +111,7 @@ module Koala
|
|
75
111
|
raise Koala::Facebook::ServerError.new(result.status.to_i, result.body)
|
76
112
|
end
|
77
113
|
|
78
|
-
|
79
|
-
|
80
|
-
# if we want a component other than the body (e.g. redirect header for images), return that
|
81
|
-
if component = options[:http_component]
|
82
|
-
component == :response ? result : result.send(options[:http_component])
|
83
|
-
else
|
84
|
-
# parse the body as JSON and run it through the error checker (if provided)
|
85
|
-
# Note: Facebook sometimes sends results like "true" and "false", which are valid[RFC7159]
|
86
|
-
# but unsupported by Ruby's stdlib[RFC4627] and cause JSON.parse to fail -- so we account for
|
87
|
-
# that by wrapping the result in []
|
88
|
-
JSON.parse("[#{result.body.to_s}]")[0]
|
89
|
-
end
|
114
|
+
result
|
90
115
|
end
|
91
116
|
|
92
117
|
private
|
@@ -112,6 +137,9 @@ module Koala
|
|
112
137
|
def preserve_form_arguments?(options)
|
113
138
|
options[:format] == :json || options[:preserve_form_arguments] || Koala.config.preserve_form_arguments
|
114
139
|
end
|
140
|
+
|
141
|
+
def check_response(http_status, body, headers)
|
142
|
+
end
|
115
143
|
end
|
116
144
|
end
|
117
145
|
end
|
@@ -32,7 +32,6 @@ module Koala
|
|
32
32
|
# for the active user from the cookie provided by Facebook.
|
33
33
|
# See the Koala and Facebook documentation for more information.
|
34
34
|
module GraphAPIMethods
|
35
|
-
|
36
35
|
# Objects
|
37
36
|
|
38
37
|
# Get information about a Facebook object.
|
@@ -107,7 +106,7 @@ module Koala
|
|
107
106
|
# @return true if successful, false (or an APIError) if not
|
108
107
|
def delete_object(id, options = {}, &block)
|
109
108
|
# Deletes the object with the given ID from the graph.
|
110
|
-
raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless
|
109
|
+
raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless access_token
|
111
110
|
graph_call(id, {}, "delete", options, &block)
|
112
111
|
end
|
113
112
|
|
@@ -157,7 +156,7 @@ module Koala
|
|
157
156
|
# @return a hash containing the new object's id
|
158
157
|
def put_connections(id, connection_name, args = {}, options = {}, &block)
|
159
158
|
# Posts a certain connection
|
160
|
-
raise AuthenticationError.new(nil, nil, "Write operations require an access token") unless
|
159
|
+
raise AuthenticationError.new(nil, nil, "Write operations require an access token") unless access_token
|
161
160
|
|
162
161
|
graph_call("#{id}/#{connection_name}", args, "post", options, &block)
|
163
162
|
end
|
@@ -175,7 +174,7 @@ module Koala
|
|
175
174
|
# @return (see #delete_object)
|
176
175
|
def delete_connections(id, connection_name, args = {}, options = {}, &block)
|
177
176
|
# Deletes a given connection
|
178
|
-
raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless
|
177
|
+
raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless access_token
|
179
178
|
graph_call("#{id}/#{connection_name}", args, "delete", options, &block)
|
180
179
|
end
|
181
180
|
|
@@ -336,7 +335,7 @@ module Koala
|
|
336
335
|
# @return (see #delete_object)
|
337
336
|
def delete_like(id, options = {}, &block)
|
338
337
|
# Unlikes a given object for the logged-in user
|
339
|
-
raise AuthenticationError.new(nil, nil, "Unliking requires an access token") unless
|
338
|
+
raise AuthenticationError.new(nil, nil, "Unliking requires an access token") unless access_token
|
340
339
|
graph_call("#{id}/likes", {}, "delete", options, &block)
|
341
340
|
end
|
342
341
|
|
@@ -344,14 +343,16 @@ module Koala
|
|
344
343
|
# See {http://developers.facebook.com/docs/reference/api/#searching Facebook documentation} for more information.
|
345
344
|
#
|
346
345
|
# @param search_terms the query to search for
|
347
|
-
# @param args additional arguments, such as
|
346
|
+
# @param args object type and any additional arguments, such as fields, etc.
|
348
347
|
# @param options (see #get_object)
|
349
348
|
# @param block (see Koala::Facebook::API#api)
|
350
349
|
#
|
351
350
|
# @return [Koala::Facebook::API::GraphCollection] an array of search results
|
352
351
|
def search(search_terms, args = {}, options = {}, &block)
|
353
|
-
|
354
|
-
|
352
|
+
# Normally we wouldn't enforce Facebook API behavior, but the API fails with cryptic error
|
353
|
+
# messages if you fail to include a type term. For a convenience method, that is valuable.
|
354
|
+
raise ArgumentError, "type must be includedin args when searching" unless args[:type] || args["type"]
|
355
|
+
graph_call("search", args.merge("q" => search_terms), "get", options, &block)
|
355
356
|
end
|
356
357
|
|
357
358
|
# Convenience Methods
|
@@ -391,21 +392,6 @@ module Koala
|
|
391
392
|
block ? block.call(access_token_info) : access_token_info
|
392
393
|
end
|
393
394
|
|
394
|
-
# Fetches the comments from fb:comments widgets for a given set of URLs (array or comma-separated string).
|
395
|
-
# See https://developers.facebook.com/blog/post/490.
|
396
|
-
#
|
397
|
-
# @param urls the URLs for which you want comments
|
398
|
-
# @param args (see #get_object)
|
399
|
-
# @param options (see #get_object)
|
400
|
-
# @param block (see Koala::Facebook::API#api)
|
401
|
-
#
|
402
|
-
# @returns a hash of urls => comment arrays
|
403
|
-
def get_comments_for_urls(urls = [], args = {}, options = {}, &block)
|
404
|
-
return [] if urls.empty?
|
405
|
-
args.merge!(:ids => urls.respond_to?(:join) ? urls.join(",") : urls)
|
406
|
-
get_object("comments", args, options, &block)
|
407
|
-
end
|
408
|
-
|
409
395
|
# App restrictions require you to JSON-encode the restriction value. This
|
410
396
|
# is neither obvious nor intuitive, so this convenience method is
|
411
397
|
# provided.
|
@@ -479,44 +465,8 @@ module Koala
|
|
479
465
|
end
|
480
466
|
end
|
481
467
|
|
482
|
-
# Make a call directly to the Graph API.
|
483
|
-
# (See any of the other methods for example invocations.)
|
484
|
-
#
|
485
|
-
# @param path the Graph API path to query (no leading / needed)
|
486
|
-
# @param args (see #get_object)
|
487
|
-
# @param verb the type of HTTP request to make (get, post, delete, etc.)
|
488
|
-
# @options (see #get_object)
|
489
|
-
#
|
490
|
-
# @yield response when making a batch API call, you can pass in a block
|
491
|
-
# that parses the results, allowing for cleaner code.
|
492
|
-
# The block's return value is returned in the batch results.
|
493
|
-
# See the code for {#get_picture} for examples.
|
494
|
-
# (Not needed in regular calls; you'll probably rarely use this.)
|
495
|
-
#
|
496
|
-
# @raise [Koala::Facebook::APIError] if Facebook returns an error
|
497
|
-
#
|
498
|
-
# @return the result from Facebook
|
499
|
-
def graph_call(path, args = {}, verb = "get", options = {}, &post_processing)
|
500
|
-
# enable appsecret_proof by default
|
501
|
-
options = {:appsecret_proof => true}.merge(options) if @app_secret
|
502
|
-
result = api(path, args, verb, options) do |response|
|
503
|
-
error = check_response(response.status, response.body, response.headers)
|
504
|
-
raise error if error
|
505
|
-
end
|
506
|
-
|
507
|
-
# turn this into a GraphCollection if it's pageable
|
508
|
-
result = API::GraphCollection.evaluate(result, self)
|
509
|
-
|
510
|
-
# now process as appropriate for the given call (get picture header, etc.)
|
511
|
-
post_processing ? post_processing.call(result) : result
|
512
|
-
end
|
513
|
-
|
514
468
|
private
|
515
469
|
|
516
|
-
def check_response(http_status, body, headers)
|
517
|
-
GraphErrorChecker.new(http_status, body, headers).error_if_appropriate
|
518
|
-
end
|
519
|
-
|
520
470
|
def parse_media_args(media_args, method)
|
521
471
|
# photo and video uploads can accept different types of arguments (see above)
|
522
472
|
# so here, we parse the arguments into a form directly usable in put_connections
|
@@ -4,13 +4,12 @@ require 'koala/api/batch_operation'
|
|
4
4
|
module Koala
|
5
5
|
module Facebook
|
6
6
|
# @private
|
7
|
-
class GraphBatchAPI
|
7
|
+
class GraphBatchAPI
|
8
8
|
# inside a batch call we can do anything a regular Graph API can do
|
9
9
|
include GraphAPIMethods
|
10
10
|
|
11
11
|
attr_reader :original_api
|
12
12
|
def initialize(api)
|
13
|
-
super(api.access_token, api.app_secret)
|
14
13
|
@original_api = api
|
15
14
|
end
|
16
15
|
|
@@ -18,7 +17,9 @@ module Koala
|
|
18
17
|
@batch_calls ||= []
|
19
18
|
end
|
20
19
|
|
21
|
-
|
20
|
+
# Enqueue a call into the batch for later processing.
|
21
|
+
# See API#graph_call
|
22
|
+
def graph_call(path, args = {}, verb = 'get', options = {}, &post_processing)
|
22
23
|
# normalize options for consistency
|
23
24
|
options = Koala::Utils.symbolize_hash(options)
|
24
25
|
|
@@ -34,73 +35,117 @@ module Koala
|
|
34
35
|
nil # batch operations return nothing immediately
|
35
36
|
end
|
36
37
|
|
37
|
-
# redefine the graph_call method so we can use this API inside the batch block
|
38
|
-
# just like any regular Graph API
|
39
|
-
alias_method :graph_call_outside_batch, :graph_call
|
40
|
-
alias_method :graph_call, :graph_call_in_batch
|
41
|
-
|
42
38
|
# execute the queued batch calls
|
43
39
|
def execute(http_options = {})
|
44
|
-
return []
|
40
|
+
return [] if batch_calls.empty?
|
41
|
+
|
45
42
|
# Turn the call args collected into what facebook expects
|
46
|
-
args = {}
|
47
|
-
|
48
|
-
args.merge!
|
49
|
-
|
50
|
-
})
|
43
|
+
args = { 'batch' => batch_args }
|
44
|
+
batch_calls.each do |call|
|
45
|
+
args.merge! call.files || {}
|
46
|
+
end
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
48
|
+
original_api.graph_call('/', args, 'post', http_options, &handle_response)
|
49
|
+
end
|
50
|
+
|
51
|
+
def handle_response
|
52
|
+
lambda do |response|
|
53
|
+
raise bad_response if response.nil?
|
54
|
+
response.map(&generate_results)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def generate_results
|
59
|
+
index = 0
|
60
|
+
lambda do |call_result|
|
61
|
+
batch_op = batch_calls[index]; index += 1
|
62
|
+
post_process = batch_op.post_processing
|
58
63
|
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
else
|
71
|
-
{}
|
72
|
-
end
|
73
|
-
|
74
|
-
if (error = check_response(call_result['code'], call_result['body'].to_s, parsed_headers))
|
75
|
-
raw_result = error
|
76
|
-
else
|
77
|
-
# (see note in regular api method about JSON parsing)
|
78
|
-
body = JSON.parse("[#{call_result['body'].to_s}]")[0]
|
79
|
-
|
80
|
-
# Get the HTTP component they want
|
81
|
-
raw_result = case batch_op.http_options[:http_component]
|
82
|
-
when :status
|
83
|
-
call_result["code"].to_i
|
84
|
-
when :headers
|
85
|
-
# facebook returns the headers as an array of k/v pairs, but we want a regular hash
|
86
|
-
parsed_headers
|
87
|
-
else
|
88
|
-
body
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# turn any results that are pageable into GraphCollections
|
94
|
-
# and pass to post-processing callback if given
|
95
|
-
result = GraphCollection.evaluate(raw_result, @original_api)
|
96
|
-
if batch_op.post_processing
|
97
|
-
batch_op.post_processing.call(result)
|
98
|
-
else
|
99
|
-
result
|
100
|
-
end
|
64
|
+
# turn any results that are pageable into GraphCollections
|
65
|
+
result = GraphCollection.evaluate(
|
66
|
+
result_from_response(call_result, batch_op),
|
67
|
+
original_api
|
68
|
+
)
|
69
|
+
|
70
|
+
# and pass to post-processing callback if given
|
71
|
+
if post_process
|
72
|
+
post_process.call(result)
|
73
|
+
else
|
74
|
+
result
|
101
75
|
end
|
102
76
|
end
|
103
77
|
end
|
78
|
+
|
79
|
+
def bad_response
|
80
|
+
# Facebook sometimes reportedly returns an empty body at times
|
81
|
+
BadFacebookResponse.new(200, '', 'Facebook returned an empty body')
|
82
|
+
end
|
83
|
+
|
84
|
+
def result_from_response(response, options)
|
85
|
+
return nil if response.nil?
|
86
|
+
|
87
|
+
headers = coerced_headers_from_response(response)
|
88
|
+
error = error_from_response(response, headers)
|
89
|
+
component = options.http_options[:http_component]
|
90
|
+
|
91
|
+
error || result_from_component({
|
92
|
+
:component => component,
|
93
|
+
:response => response,
|
94
|
+
:headers => headers
|
95
|
+
})
|
96
|
+
end
|
97
|
+
|
98
|
+
def coerced_headers_from_response(response)
|
99
|
+
headers = response.fetch('headers', [])
|
100
|
+
|
101
|
+
headers.each_with_object({}) do |h, memo|
|
102
|
+
memo.merge! h.fetch('name') => h.fetch('value')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def error_from_response(response, headers)
|
107
|
+
code = response['code']
|
108
|
+
body = response['body'].to_s
|
109
|
+
|
110
|
+
GraphErrorChecker.new(code, body, headers).error_if_appropriate
|
111
|
+
end
|
112
|
+
|
113
|
+
def batch_args
|
114
|
+
calls = batch_calls.map do |batch_op|
|
115
|
+
batch_op.to_batch_params(access_token, app_secret)
|
116
|
+
end
|
117
|
+
|
118
|
+
JSON.dump calls
|
119
|
+
end
|
120
|
+
|
121
|
+
def json_body(response)
|
122
|
+
# quirks_mode is needed because Facebook sometimes returns a raw true or false value --
|
123
|
+
# in Ruby 2.4 we can drop that.
|
124
|
+
JSON.parse(response.fetch('body'), quirks_mode: true)
|
125
|
+
end
|
126
|
+
|
127
|
+
def result_from_component(options)
|
128
|
+
component = options.fetch(:component)
|
129
|
+
response = options.fetch(:response)
|
130
|
+
headers = options.fetch(:headers)
|
131
|
+
|
132
|
+
# Get the HTTP component they want
|
133
|
+
case component
|
134
|
+
when :status then response['code'].to_i
|
135
|
+
# facebook returns the headers as an array of k/v pairs, but we want a regular hash
|
136
|
+
when :headers then headers
|
137
|
+
# (see note in regular api method about JSON parsing)
|
138
|
+
else json_body(response)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def access_token
|
143
|
+
original_api.access_token
|
144
|
+
end
|
145
|
+
|
146
|
+
def app_secret
|
147
|
+
original_api.app_secret
|
148
|
+
end
|
104
149
|
end
|
105
150
|
end
|
106
151
|
end
|