koala 2.4.0 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/test.yml +32 -0
  3. data/Gemfile +5 -3
  4. data/ISSUE_TEMPLATE +25 -0
  5. data/PULL_REQUEST_TEMPLATE +11 -0
  6. data/changelog.md +161 -4
  7. data/code_of_conduct.md +64 -12
  8. data/koala.gemspec +5 -1
  9. data/lib/koala/api/batch_operation.rb +3 -6
  10. data/lib/koala/api/{graph_api.rb → graph_api_methods.rb} +29 -104
  11. data/lib/koala/api/graph_batch_api.rb +112 -65
  12. data/lib/koala/api/graph_collection.rb +19 -12
  13. data/lib/koala/api/graph_error_checker.rb +4 -3
  14. data/lib/koala/api.rb +65 -26
  15. data/lib/koala/configuration.rb +56 -0
  16. data/lib/koala/errors.rb +22 -2
  17. data/lib/koala/http_service/request.rb +133 -0
  18. data/lib/koala/http_service/response.rb +6 -4
  19. data/lib/koala/http_service/uploadable_io.rb +0 -5
  20. data/lib/koala/http_service.rb +29 -76
  21. data/lib/koala/oauth.rb +8 -8
  22. data/lib/koala/realtime_updates.rb +26 -21
  23. data/lib/koala/test_users.rb +9 -8
  24. data/lib/koala/version.rb +1 -1
  25. data/lib/koala.rb +7 -9
  26. data/readme.md +83 -109
  27. data/spec/cases/api_spec.rb +176 -69
  28. data/spec/cases/configuration_spec.rb +11 -0
  29. data/spec/cases/error_spec.rb +16 -3
  30. data/spec/cases/graph_api_batch_spec.rb +75 -44
  31. data/spec/cases/graph_api_spec.rb +15 -29
  32. data/spec/cases/graph_collection_spec.rb +47 -34
  33. data/spec/cases/graph_error_checker_spec.rb +31 -2
  34. data/spec/cases/http_service/request_spec.rb +250 -0
  35. data/spec/cases/http_service/response_spec.rb +24 -0
  36. data/spec/cases/http_service_spec.rb +126 -286
  37. data/spec/cases/koala_spec.rb +7 -5
  38. data/spec/cases/oauth_spec.rb +41 -2
  39. data/spec/cases/realtime_updates_spec.rb +51 -13
  40. data/spec/cases/test_users_spec.rb +56 -2
  41. data/spec/cases/uploadable_io_spec.rb +31 -31
  42. data/spec/fixtures/cat.m4v +0 -0
  43. data/spec/fixtures/facebook_data.yml +4 -6
  44. data/spec/fixtures/mock_facebook_responses.yml +41 -78
  45. data/spec/fixtures/vcr_cassettes/app_test_accounts.yml +97 -0
  46. data/spec/integration/graph_collection_spec.rb +8 -5
  47. data/spec/spec_helper.rb +2 -2
  48. data/spec/support/graph_api_shared_examples.rb +152 -337
  49. data/spec/support/koala_test.rb +11 -13
  50. data/spec/support/mock_http_service.rb +11 -14
  51. data/spec/support/uploadable_io_shared_examples.rb +4 -4
  52. metadata +47 -48
  53. data/.autotest +0 -12
  54. data/.travis.yml +0 -17
  55. data/Guardfile +0 -6
  56. data/autotest/discover.rb +0 -1
  57. data/lib/koala/api/rest_api.rb +0 -135
  58. data/lib/koala/http_service/multipart_request.rb +0 -41
  59. data/spec/cases/multipart_request_spec.rb +0 -65
  60. data/spec/support/rest_api_shared_examples.rb +0 -168
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: aa79bc7b848a2513d2f1aac248d1aac70d8a392c
4
- data.tar.gz: edfd57c54b0b96a4682cf23af9e388ed59e4aa3d
2
+ SHA256:
3
+ metadata.gz: fe8f0af88bb59626abb6b309322ed98a0e5f5faceca7931968f6ce8842451b0d
4
+ data.tar.gz: f813925e9a5905f34b27c95b45cef4ca282e12cee0e4a09db58160b8f5de2e78
5
5
  SHA512:
6
- metadata.gz: ed4e62ff0f2d70c17cf0301be06e552940fd14654b1dc715f10477f63da89d2b6aa14b21105e2b9e90ca88ee1ff7a60e737f2f24744ab6cb86cf4b9f6aac80ce
7
- data.tar.gz: 7a5b55d226afdd6f8e6d8af440b7e714a1cb8ffd68c35a0f80dfdb61d042d988b8b7eb8fad95d30e3cff094a0a3ecfc07fe418d2ec61826a7338b027933d1636
6
+ metadata.gz: e6b17b4a746648c7910b6c946178f62b3fc9aadd79439e82c61169ecb98a9f1e0e47c2d54fb4a9918b620431dce46a6340c5fa1317c809ee9c287a8a9f38a14b
7
+ data.tar.gz: 1ba2fcc4f6bb844c14dba797d49d4042d7e8cab78d53251a0c2e3b88edbfcb31512a27e4f3e62e2cd2da8174f7e381c87571887954121edc3119324464e1014c
@@ -0,0 +1,32 @@
1
+ name: Test
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ name: on ruby ${{matrix.ruby}}
8
+ runs-on: ubuntu-latest
9
+
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby: [2.7, "3.0", 3.1, head]
14
+
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v2
18
+
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{matrix.ruby}}
23
+
24
+ - name: Install dependencies
25
+ run: bundle install --jobs 4 --retry 3
26
+
27
+ - name: Specs & Coverage
28
+ uses: paambaati/codeclimate-action@v3.0.0
29
+ env:
30
+ CC_TEST_REPORTER_ID: 7af99d9225b4c14640f9ec3cb2e24d2f7103ac49417b0bd989188fb6c25f2909
31
+ with:
32
+ coverageCommand: bundle exec rspec
data/Gemfile CHANGED
@@ -7,15 +7,17 @@ group :development do
7
7
  end
8
8
 
9
9
  group :development, :test do
10
+ gem "psych", '< 4.0.0' # safe_load signature not compatible with older rubies
10
11
  gem "rake"
11
12
  gem "typhoeus" unless defined? JRUBY_VERSION
13
+ gem 'faraday-typhoeus' unless defined? JRUBY_VERSION
12
14
  end
13
15
 
14
16
  group :test do
15
- gem "rspec", '~> 3.4'
16
- gem "vcr"
17
+ gem "rspec", "~> 3.0", "< 3.10" # resrict rspec version until https://github.com/rspec/rspec-support/pull/537 gets merged
18
+ gem "vcr", github: 'vcr/vcr', ref: '8ced6c96e01737a418cd270e0382a8c2c6d85f7f' # needs https://github.com/vcr/vcr/pull/907 for ruby 3.1
17
19
  gem "webmock"
18
- gem "codeclimate-test-reporter", require: nil
20
+ gem "simplecov"
19
21
  end
20
22
 
21
23
  gem "jruby-openssl" if defined? JRUBY_VERSION
data/ISSUE_TEMPLATE ADDED
@@ -0,0 +1,25 @@
1
+ Thanks for using Koala! Sorry you've run into an issue 😓 Here are some questions to help get things figured out as quickly as possible.
2
+
3
+ You don't have to fill this all out -- it's more of a guide. If in doubt, delete any sections that aren't relevant and open the issue. I want to help.
4
+
5
+ [ ] This is a Koala bug/issue/documentation problem.
6
+
7
+ Koala is a labor of love both from me and from the awesome community members who answer questions here. Much as we'd love to be able to help with everything, I have to focus my time on issues with the gem itself and can't help with questions on how to _use_ Facebook. (Plus, Facebook is huge!)
8
+
9
+ If you have questions about using the Facebook API, [facebook.stackoverflow.com](http://facebook.stackoverflow.com) is a great resource.
10
+
11
+ _For code issues:_
12
+
13
+ [ ] What I'm doing works on the [Graph API explorer](https://developers.facebook.com/tools/explorer/)/curl/another tool.
14
+
15
+ Seeing an example of what works helps diagnose what doesn't work.
16
+
17
+ [ ] I'm using the newest version
18
+ [ ] Here's code to replicate the issue:
19
+
20
+ Obviously not all code can be shared -- feel free to put variables in place of any sensitive information and describe what should be used to replicate it.
21
+
22
+ Thanks for submitting an issue! Looking forward to working with you to figure it out.
23
+
24
+
25
+ Note: Koala has a [code of conduct](https://github.com/arsduo/koala/blob/master/code_of_conduct.md). Check it out.
@@ -0,0 +1,11 @@
1
+ Thanks for submitting a pull request to Koala! A huge portion of the gem has been built by awesome people (like you) from the Ruby community.
2
+
3
+ Here are a few things that will help get your pull request merged in quickly. None of this is required -- you can delete anything not relevant. If in doubt, open the PR! I want to help.
4
+
5
+ [ ] My PR has tests and they pass!
6
+ [ ] The live tests pass for my changes (`LIVE=true rspec` -- unrelated failures are okay).
7
+ [ ] The PR is based on the most recent master commit and has no merge conflicts.
8
+
9
+ If you have any questions, feel free to open an issue or comment on your PR!
10
+
11
+ Note: Koala has a [code of conduct](https://github.com/arsduo/koala/blob/master/code_of_conduct.md). Check it out.
data/changelog.md CHANGED
@@ -1,4 +1,161 @@
1
- v2.4.0
1
+ Unreleased
2
+ ==========
3
+
4
+ **Key breaking changes:**
5
+
6
+ New features:
7
+
8
+ Updated features:
9
+
10
+ Removed features:
11
+
12
+ Internal improvements:
13
+
14
+ Testing improvements:
15
+
16
+ Others:
17
+
18
+ v3.5.0 (2023-08-23)
19
+ ======
20
+
21
+ Internal improvements:
22
+ * Raise ClientError instead of NoMethodError when body is 'null' ([#673](https://github.com/arsduo/koala/issues/673))
23
+
24
+ v3.4.0 (2023-01-05)
25
+ ======
26
+
27
+ Updated features:
28
+
29
+ * Force use by default of HTTPS (instead of HTTP) when there is no access token.
30
+ HTTP can still be used by passing :use_ssl => false in the options hash for an api call ([#678](https://github.com/arsduo/koala/pull/678/files))
31
+
32
+ v3.3.0 (2022-09-27)
33
+ ======
34
+
35
+ Updated features:
36
+
37
+ * Removed restriction on faraday < 2 ([#666](https://github.com/arsduo/koala/pull/666))
38
+
39
+ Internal improvements:
40
+
41
+ * Remove multipart hack and use default faraday multipart middleware ([#664](https://github.com/arsduo/koala/pull/664))
42
+
43
+ Testing improvements:
44
+
45
+ * Fix tests with ruby-head ([#674](https://github.com/arsduo/koala/pull/674))
46
+ * Keep supported rubies (non EOL) for CI ([#675](https://github.com/arsduo/koala/pull/675))
47
+
48
+ v3.2.0 (2022-05-27)
49
+ ======
50
+
51
+ New features:
52
+
53
+ * Exposes limiting headers(`x-business-use-case-usage, x-ad-account-usage, x-app-usage`) to APIError ([#668](https://github.com/arsduo/koala/pull/668))
54
+ * Add `rate_limit_hook` configuration to get rate limiting headers (`x-business-use-case-usage, x-ad-account-usage, x-app-usage`) ([#670](https://github.com/arsduo/koala/pull/670))
55
+
56
+ Testing improvements:
57
+
58
+ * Fix builds for ruby 3.x
59
+
60
+ v3.1.0 (2022-01-18)
61
+ ======
62
+
63
+ New features:
64
+
65
+ * mask_tokens config (default: true) to mask tokens in logs
66
+
67
+ Updated features:
68
+
69
+ * Log before and after sending request
70
+
71
+ Internal improvements:
72
+
73
+ * Lock Faraday to < 2
74
+ * Compatibility with ruby 3.x
75
+
76
+ Testing improvements:
77
+
78
+ * Use Github actions for CI
79
+ * Run CI on latest rubies
80
+
81
+ v3.0.0 (2017-03-17)
82
+ ======
83
+
84
+ Most users should not see any difference upgrading from 2.x to 3.0. Most of the changes are
85
+ internal to how requests go from a graph method (like `get_connections`) through the API to the
86
+ HTTP layer and back. If you're not using API#api or HTTPService.make_request directly, upgrading
87
+ should (in theory) require no code changes. (Let me know if you run into any issues.)
88
+
89
+ **Key breaking changes:**
90
+
91
+ * Koala now requires Ruby 2.1+ (or equivalent for JRuby, etc.)
92
+ * API#api now returns a Koala::HTTPService::Response object; graph_call handles further processing
93
+ * GraphBatchAPI no longer inherits from API (the interface is otherwise unchanged)
94
+ * Empty response bodies in batch API calls will raise a JSON::ParserError rather than returning nil
95
+ * HTTPService.make_request now requires an HTTPService::Request object (Koala.make_request does
96
+ not)
97
+ * HTTPService behavior *should not* change, but in edge cases might. (If so, please let me know.)
98
+ * API#search now requires a "type"/:type argument, matching Facebook's behavior (improving their
99
+ cryptic error message)
100
+
101
+ New features:
102
+
103
+ * Koala now supports global configuration for tokens, secrets, etc! See the readme.
104
+ * GraphCollection now exposes #headers, allowing access to etag/rate limiting/etc. info (thanks,
105
+ pawandubey and jessieay!) (#589)
106
+
107
+ Updated features:
108
+
109
+ * Koala.config now uses a dedicated Koala::Configuration object
110
+ * TestUser#befriend will provide the appsecret_proof if a secret is set (thanks, kwasimensah!)
111
+ * API#search now requires an object type parameter to be included, matching Facebook's API (#575)
112
+ * RealtimeUpdates will now only fetch the app access token if necessary, avoiding unnecessary calls
113
+
114
+ Removed features:
115
+
116
+ * Removed support for the Rest API, since Facebook removed support for it (#568)
117
+ * Removed support for FQL, which Facebook removed on August 8, 2016 (#569)
118
+ * Removed legacy duplication of serveral constants in the Koala module (#569)
119
+ * Removed API#get_comments_for_urls, which pointed to a no-longer-extant endpoint(#570)
120
+
121
+ Internal improvements:
122
+
123
+ * Completely rewrote HTTPService.make_request and several others, extracting most logic into
124
+ HTTPService::Request (#566)
125
+ * API#api now returns a Koala::HTTPService::Response object (#584)
126
+ * GraphBatchAPI no longer inherits from API (#580)
127
+ * GraphBatchAPI has been refactored to be simpler and more readable (thanks, acuppy!) (#551)
128
+ * Use the more secure JSON.parse instead of JSON.load (thanks, lautis!) (#567)
129
+ * Use JSON's quirks_mode option to remove hacky JSON hack (#573 -- thanks sakuro for the
130
+ suggestion!)
131
+ * The gemspec now allows both JSON 1.8 and 2.0 (#596) (thanks, pawandubey!)
132
+ * Remove Autotest and Guard references (no longer used/needed)
133
+
134
+ Testing improvements:
135
+
136
+ * Fixed a bunch of failing mocked specs
137
+
138
+ Others:
139
+
140
+ * Added an issue and pull request template
141
+ * Updated Code of Conduct to 1.4
142
+
143
+ v2.5.0 (2017-02-17)
144
+ ======
145
+
146
+ New features:
147
+
148
+ * API#get_object_metadata provides a convenient accessor to an object's graph metadata (thanks, sancopanco!)
149
+
150
+ Documentation improvements:
151
+
152
+ * Add explicit require to examples in readme.md (thanks, dwkns!)
153
+
154
+ Internal improvements:
155
+
156
+ * Remove MultiJson dependency (thanks, sakuro!)
157
+
158
+ v2.4.0 (2016-07-08)
2
159
  ======
3
160
 
4
161
  **Note:** Koala is no longer officially supported on Ruby 1.9.3 (which was [end-of-lifed back in
@@ -18,10 +175,10 @@ Internal improvements:
18
175
 
19
176
  Testing improvements:
20
177
 
21
- * Test Koala against Ruby 2.3.0
178
+ * Test Koala against Ruby 2.3.0 (thanks, thedrow!)
22
179
 
23
180
 
24
- v2.3.0
181
+ v2.3.0 (2016-04-10)
25
182
  ======
26
183
 
27
184
  Updated features:
@@ -42,7 +199,7 @@ Testing improvements:
42
199
  * Removed pended specs that were no longer relevant
43
200
  * Improved https regex in test suite (thanks, lucaskds!)
44
201
 
45
- v2.2.0
202
+ v2.2.0 (2015-08-11)
46
203
  ======
47
204
 
48
205
  Updated features:
data/code_of_conduct.md CHANGED
@@ -1,22 +1,74 @@
1
- # Contributor Code of Conduct
1
+ # Contributor Covenant Code of Conduct
2
2
 
3
- As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
3
+ ## Our Pledge
4
4
 
5
- We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
6
22
 
7
23
  Examples of unacceptable behavior by participants include:
8
24
 
9
- * The use of sexualized language or imagery
10
- * Personal attacks
11
- * Trolling or insulting/derogatory comments
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
12
28
  * Public or private harassment
13
- * Publishing other's private information, such as physical or electronic addresses, without explicit permission
14
- * Other unethical or unprofessional conduct.
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
15
63
 
16
- Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
17
67
 
18
- This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
68
+ ## Attribution
19
69
 
20
- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
21
72
 
22
- This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/koala.gemspec CHANGED
@@ -21,7 +21,11 @@ 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.add_runtime_dependency("multi_json", ">= 1.3.0")
24
+ gem.required_ruby_version = '>= 2.1'
25
+
25
26
  gem.add_runtime_dependency("faraday")
27
+ gem.add_runtime_dependency("faraday-multipart")
26
28
  gem.add_runtime_dependency("addressable")
29
+ gem.add_runtime_dependency("json", ">= 1.8")
30
+ gem.add_runtime_dependency("rexml")
27
31
  end
@@ -1,4 +1,5 @@
1
1
  require 'koala/api'
2
+ require 'koala/api/graph_batch_api'
2
3
 
3
4
  module Koala
4
5
  module Facebook
@@ -65,13 +66,13 @@ module Koala
65
66
  def process_binary_args
66
67
  # collect binary files
67
68
  @args.each_pair do |key, value|
68
- if UploadableIO.binary_content?(value)
69
+ if HTTPService::UploadableIO.binary_content?(value)
69
70
  @files ||= {}
70
71
  # we use a class-level counter to ensure unique file identifiers across multiple batch operations
71
72
  # (this is thread safe, since we just care about uniqueness)
72
73
  # so remove the file from the original hash and add it to the file store
73
74
  id = "op#{identifier}_file#{@files.keys.length}"
74
- @files[id] = @args.delete(key).is_a?(UploadableIO) ? value : UploadableIO.new(value)
75
+ @files[id] = @args.delete(key).is_a?(HTTPService::UploadableIO) ? value : HTTPService::UploadableIO.new(value)
75
76
  end
76
77
  end
77
78
  end
@@ -81,9 +82,5 @@ module Koala
81
82
  end
82
83
  end
83
84
  end
84
-
85
- # @private
86
- # legacy support for when BatchOperation lived directly under Koala::Facebook
87
- BatchOperation = GraphBatchAPI::BatchOperation
88
85
  end
89
86
  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.
@@ -57,6 +56,20 @@ module Koala
57
56
  graph_call(id, args, "get", options, &block)
58
57
  end
59
58
 
59
+ # Get the metadata of a Facebook object, including its type.
60
+ #
61
+ # @param id the object ID (string or number)
62
+ #
63
+ # @raise [Koala::Facebook::ClientError] if the ID is invalid
64
+ # @example
65
+ # get_object_metadata("442575165800306")=>{"metadata" => "page", ...}
66
+ # get_object_metadata("190822584430113")=>{"metadata" => "status", ...}
67
+ # @return a string of Facebook object type
68
+ def get_object_metadata(id, &block)
69
+ result = graph_call(id, {"metadata" => "1"}, "get", {}, &block)
70
+ result["metadata"]
71
+ end
72
+
60
73
  # Get information about multiple Facebook objects in one call.
61
74
  #
62
75
  # @param ids an array or comma-separated string of object IDs
@@ -93,7 +106,7 @@ module Koala
93
106
  # @return true if successful, false (or an APIError) if not
94
107
  def delete_object(id, options = {}, &block)
95
108
  # Deletes the object with the given ID from the graph.
96
- raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless @access_token
109
+ raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless access_token
97
110
  graph_call(id, {}, "delete", options, &block)
98
111
  end
99
112
 
@@ -143,7 +156,7 @@ module Koala
143
156
  # @return a hash containing the new object's id
144
157
  def put_connections(id, connection_name, args = {}, options = {}, &block)
145
158
  # Posts a certain connection
146
- raise AuthenticationError.new(nil, nil, "Write operations require an access token") unless @access_token
159
+ raise AuthenticationError.new(nil, nil, "Write operations require an access token") unless access_token
147
160
 
148
161
  graph_call("#{id}/#{connection_name}", args, "post", options, &block)
149
162
  end
@@ -161,7 +174,7 @@ module Koala
161
174
  # @return (see #delete_object)
162
175
  def delete_connections(id, connection_name, args = {}, options = {}, &block)
163
176
  # Deletes a given connection
164
- raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless @access_token
177
+ raise AuthenticationError.new(nil, nil, "Delete requires an access token") unless access_token
165
178
  graph_call("#{id}/#{connection_name}", args, "delete", options, &block)
166
179
  end
167
180
 
@@ -274,7 +287,7 @@ module Koala
274
287
  # @return (see #put_connections)
275
288
  def put_wall_post(message, attachment = {}, target_id = "me", options = {}, &block)
276
289
  if properties = attachment.delete(:properties) || attachment.delete("properties")
277
- properties = MultiJson.dump(properties) if properties.is_a?(Hash) || properties.is_a?(Array)
290
+ properties = JSON.dump(properties) if properties.is_a?(Hash) || properties.is_a?(Array)
278
291
  attachment["properties"] = properties
279
292
  end
280
293
  put_connections(target_id, "feed", attachment.merge({:message => message}), options, &block)
@@ -322,7 +335,7 @@ module Koala
322
335
  # @return (see #delete_object)
323
336
  def delete_like(id, options = {}, &block)
324
337
  # Unlikes a given object for the logged-in user
325
- raise AuthenticationError.new(nil, nil, "Unliking requires an access token") unless @access_token
338
+ raise AuthenticationError.new(nil, nil, "Unliking requires an access token") unless access_token
326
339
  graph_call("#{id}/likes", {}, "delete", options, &block)
327
340
  end
328
341
 
@@ -330,14 +343,16 @@ module Koala
330
343
  # See {http://developers.facebook.com/docs/reference/api/#searching Facebook documentation} for more information.
331
344
  #
332
345
  # @param search_terms the query to search for
333
- # @param args additional arguments, such as type, fields, etc.
346
+ # @param args object type and any additional arguments, such as fields, etc.
334
347
  # @param options (see #get_object)
335
348
  # @param block (see Koala::Facebook::API#api)
336
349
  #
337
350
  # @return [Koala::Facebook::API::GraphCollection] an array of search results
338
351
  def search(search_terms, args = {}, options = {}, &block)
339
- args.merge!({:q => search_terms}) unless search_terms.nil?
340
- graph_call("search", args, "get", options, &block)
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)
341
356
  end
342
357
 
343
358
  # Convenience Methods
@@ -345,45 +360,6 @@ module Koala
345
360
  # except to support cases where the Facebook API requires non-standard input
346
361
  # such as JSON-encoding arguments, posts directly to objects, etc.
347
362
 
348
- # Make an FQL query.
349
- # Convenience method equivalent to get_object("fql", :q => query).
350
- #
351
- # @param query the FQL query to perform
352
- # @param args (see #get_object)
353
- # @param options (see #get_object)
354
- # @param block (see Koala::Facebook::API#api)
355
- #
356
- # @return the result of the FQL query.
357
- def fql_query(query, args = {}, options = {}, &block)
358
- get_object("fql", args.merge(:q => query), options, &block)
359
- end
360
-
361
- # Make an FQL multiquery.
362
- # This method simplifies the result returned from multiquery into a more logical format.
363
- #
364
- # @param queries a hash of query names => FQL queries
365
- # @param args (see #get_object)
366
- # @param options (see #get_object)
367
- # @param block (see Koala::Facebook::API#api)
368
- #
369
- # @example
370
- # @api.fql_multiquery({
371
- # "query1" => "select post_id from stream where source_id = me()",
372
- # "query2" => "select fromid from comment where post_id in (select post_id from #query1)"
373
- # })
374
- # # returns {"query1" => [obj1, obj2, ...], "query2" => [obj3, ...]}
375
- # # instead of [{"name":"query1", "fql_result_set":[]},{"name":"query2", "fql_result_set":[]}]
376
- #
377
- # @return a hash of FQL results keyed to the appropriate query
378
- def fql_multiquery(queries = {}, args = {}, options = {}, &block)
379
- resolved_results = if results = get_object("fql", args.merge(:q => MultiJson.dump(queries)), options)
380
- # simplify the multiquery result format
381
- results.inject({}) {|outcome, data| outcome[data["name"]] = data["fql_result_set"]; outcome}
382
- end
383
-
384
- block ? block.call(resolved_results) : resolved_results
385
- end
386
-
387
363
  # Get a page's access token, allowing you to act as the page.
388
364
  # Convenience method for @api.get_object(page_id, :fields => "access_token").
389
365
  #
@@ -416,21 +392,6 @@ module Koala
416
392
  block ? block.call(access_token_info) : access_token_info
417
393
  end
418
394
 
419
- # Fetches the comments from fb:comments widgets for a given set of URLs (array or comma-separated string).
420
- # See https://developers.facebook.com/blog/post/490.
421
- #
422
- # @param urls the URLs for which you want comments
423
- # @param args (see #get_object)
424
- # @param options (see #get_object)
425
- # @param block (see Koala::Facebook::API#api)
426
- #
427
- # @returns a hash of urls => comment arrays
428
- def get_comments_for_urls(urls = [], args = {}, options = {}, &block)
429
- return [] if urls.empty?
430
- args.merge!(:ids => urls.respond_to?(:join) ? urls.join(",") : urls)
431
- get_object("comments", args, options, &block)
432
- end
433
-
434
395
  # App restrictions require you to JSON-encode the restriction value. This
435
396
  # is neither obvious nor intuitive, so this convenience method is
436
397
  # provided.
@@ -441,7 +402,7 @@ module Koala
441
402
  # @param options (see #get_object)
442
403
  # @param block (see Koala::Facebook::API#api)
443
404
  def set_app_restrictions(app_id, restrictions_hash, args = {}, options = {}, &block)
444
- graph_call(app_id, args.merge(:restrictions => MultiJson.dump(restrictions_hash)), "post", options, &block)
405
+ graph_call(app_id, args.merge(:restrictions => JSON.dump(restrictions_hash)), "post", options, &block)
445
406
  end
446
407
 
447
408
  # Certain calls such as {#get_connections} return an array of results which you can page through
@@ -449,13 +410,13 @@ module Koala
449
410
  # Those methods use get_page to request another set of results from Facebook.
450
411
  #
451
412
  # @note You'll rarely need to use this method unless you're using Sinatra or another non-Rails framework
452
- # (see {Koala::Facebook::GraphCollection GraphCollection} for more information).
413
+ # (see {Koala::Facebook::API::GraphCollection GraphCollection} for more information).
453
414
  #
454
415
  # @param params an array of arguments to graph_call
455
- # as returned by {Koala::Facebook::GraphCollection.parse_page_url}.
416
+ # as returned by {Koala::Facebook::API::GraphCollection.parse_page_url}.
456
417
  # @param block (see Koala::Facebook::API#api)
457
418
  #
458
- # @return Koala::Facebook::GraphCollection the appropriate page of results (an empty array if there are none)
419
+ # @return Koala::Facebook::API::GraphCollection the appropriate page of results (an empty array if there are none)
459
420
  def get_page(params, &block)
460
421
  graph_call(*params, &block)
461
422
  end
@@ -504,44 +465,8 @@ module Koala
504
465
  end
505
466
  end
506
467
 
507
- # Make a call directly to the Graph API.
508
- # (See any of the other methods for example invocations.)
509
- #
510
- # @param path the Graph API path to query (no leading / needed)
511
- # @param args (see #get_object)
512
- # @param verb the type of HTTP request to make (get, post, delete, etc.)
513
- # @options (see #get_object)
514
- #
515
- # @yield response when making a batch API call, you can pass in a block
516
- # that parses the results, allowing for cleaner code.
517
- # The block's return value is returned in the batch results.
518
- # See the code for {#get_picture} or {#fql_multiquery} for examples.
519
- # (Not needed in regular calls; you'll probably rarely use this.)
520
- #
521
- # @raise [Koala::Facebook::APIError] if Facebook returns an error
522
- #
523
- # @return the result from Facebook
524
- def graph_call(path, args = {}, verb = "get", options = {}, &post_processing)
525
- # enable appsecret_proof by default
526
- options = {:appsecret_proof => true}.merge(options) if @app_secret
527
- result = api(path, args, verb, options) do |response|
528
- error = check_response(response.status, response.body, response.headers)
529
- raise error if error
530
- end
531
-
532
- # turn this into a GraphCollection if it's pageable
533
- result = GraphCollection.evaluate(result, self)
534
-
535
- # now process as appropriate for the given call (get picture header, etc.)
536
- post_processing ? post_processing.call(result) : result
537
- end
538
-
539
468
  private
540
469
 
541
- def check_response(http_status, body, headers)
542
- GraphErrorChecker.new(http_status, body, headers).error_if_appropriate
543
- end
544
-
545
470
  def parse_media_args(media_args, method)
546
471
  # photo and video uploads can accept different types of arguments (see above)
547
472
  # so here, we parse the arguments into a form directly usable in put_connections
@@ -559,7 +484,7 @@ module Koala
559
484
  fb_expected_arg_name = method == "photos" ? :url : :file_url
560
485
  args.merge!(fb_expected_arg_name => media_args.first)
561
486
  else
562
- args["source"] = Koala::UploadableIO.new(*media_args.slice(0, 1 + args_offset))
487
+ args["source"] = Koala::HTTPService::UploadableIO.new(*media_args.slice(0, 1 + args_offset))
563
488
  end
564
489
 
565
490
  [target_id, method, args, options]