instagram-continued-continued 1.5.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.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.hound.yml +2 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +15 -0
  6. data/.travis.yml +20 -0
  7. data/.yardopts +9 -0
  8. data/Gemfile +3 -0
  9. data/LICENSE.md +30 -0
  10. data/PATENTS.md +23 -0
  11. data/README.md +15 -0
  12. data/Rakefile +23 -0
  13. data/instagram-continued-continued.gemspec +34 -0
  14. data/lib/faraday/loud_logger.rb +74 -0
  15. data/lib/faraday/oauth2.rb +40 -0
  16. data/lib/faraday/raise_http_exception.rb +61 -0
  17. data/lib/instagram.rb +28 -0
  18. data/lib/instagram/api.rb +31 -0
  19. data/lib/instagram/client.rb +21 -0
  20. data/lib/instagram/client/comments.rb +62 -0
  21. data/lib/instagram/client/embedding.rb +28 -0
  22. data/lib/instagram/client/geographies.rb +29 -0
  23. data/lib/instagram/client/likes.rb +58 -0
  24. data/lib/instagram/client/locations.rb +75 -0
  25. data/lib/instagram/client/media.rb +82 -0
  26. data/lib/instagram/client/subscriptions.rb +211 -0
  27. data/lib/instagram/client/tags.rb +59 -0
  28. data/lib/instagram/client/users.rb +310 -0
  29. data/lib/instagram/client/utils.rb +28 -0
  30. data/lib/instagram/configuration.rb +123 -0
  31. data/lib/instagram/connection.rb +33 -0
  32. data/lib/instagram/error.rb +34 -0
  33. data/lib/instagram/hashie_wrapper.rb +8 -0
  34. data/lib/instagram/oauth.rb +36 -0
  35. data/lib/instagram/request.rb +79 -0
  36. data/lib/instagram/response.rb +27 -0
  37. data/lib/instagram/version.rb +3 -0
  38. data/spec/faraday/response_spec.rb +85 -0
  39. data/spec/fixtures/access_token.json +9 -0
  40. data/spec/fixtures/approve_user.json +8 -0
  41. data/spec/fixtures/block_user.json +8 -0
  42. data/spec/fixtures/deny_user.json +8 -0
  43. data/spec/fixtures/follow_user.json +8 -0
  44. data/spec/fixtures/followed_by.json +1 -0
  45. data/spec/fixtures/follows.json +1 -0
  46. data/spec/fixtures/geography_recent_media.json +1 -0
  47. data/spec/fixtures/liked_media.json +1 -0
  48. data/spec/fixtures/location.json +1 -0
  49. data/spec/fixtures/location_recent_media.json +1 -0
  50. data/spec/fixtures/location_search.json +1 -0
  51. data/spec/fixtures/location_search_facebook.json +1 -0
  52. data/spec/fixtures/media.json +1 -0
  53. data/spec/fixtures/media_comment.json +1 -0
  54. data/spec/fixtures/media_comment_deleted.json +1 -0
  55. data/spec/fixtures/media_comments.json +1 -0
  56. data/spec/fixtures/media_liked.json +1 -0
  57. data/spec/fixtures/media_likes.json +1 -0
  58. data/spec/fixtures/media_popular.json +1 -0
  59. data/spec/fixtures/media_search.json +1 -0
  60. data/spec/fixtures/media_shortcode.json +1 -0
  61. data/spec/fixtures/media_unliked.json +1 -0
  62. data/spec/fixtures/mikeyk.json +1 -0
  63. data/spec/fixtures/oembed.json +14 -0
  64. data/spec/fixtures/recent_media.json +1 -0
  65. data/spec/fixtures/relationship.json +9 -0
  66. data/spec/fixtures/requested_by.json +12 -0
  67. data/spec/fixtures/shayne.json +1 -0
  68. data/spec/fixtures/subscription.json +12 -0
  69. data/spec/fixtures/subscription_deleted.json +1 -0
  70. data/spec/fixtures/subscription_payload.json +14 -0
  71. data/spec/fixtures/subscriptions.json +22 -0
  72. data/spec/fixtures/tag.json +1 -0
  73. data/spec/fixtures/tag_recent_media.json +1 -0
  74. data/spec/fixtures/tag_search.json +1 -0
  75. data/spec/fixtures/unblock_user.json +8 -0
  76. data/spec/fixtures/unfollow_user.json +8 -0
  77. data/spec/fixtures/user_media_feed.json +1 -0
  78. data/spec/fixtures/user_search.json +1 -0
  79. data/spec/instagram/api_spec.rb +259 -0
  80. data/spec/instagram/client/comments_spec.rb +67 -0
  81. data/spec/instagram/client/embedding_spec.rb +36 -0
  82. data/spec/instagram/client/geography_spec.rb +34 -0
  83. data/spec/instagram/client/likes_spec.rb +62 -0
  84. data/spec/instagram/client/locations_spec.rb +121 -0
  85. data/spec/instagram/client/media_spec.rb +95 -0
  86. data/spec/instagram/client/subscriptions_spec.rb +162 -0
  87. data/spec/instagram/client/tags_spec.rb +75 -0
  88. data/spec/instagram/client/users_spec.rb +407 -0
  89. data/spec/instagram/client/utils_spec.rb +31 -0
  90. data/spec/instagram/client_spec.rb +23 -0
  91. data/spec/instagram/request_spec.rb +56 -0
  92. data/spec/instagram_spec.rb +105 -0
  93. data/spec/spec_helper.rb +66 -0
  94. metadata +293 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b0da98540743f2d7e7748e4a1199254f7cb2eb4aa2f43eb81a3e049ee772591d
4
+ data.tar.gz: 68a5eb6c40d2ad2bd2984506ea725c906be422dd4f3d5d270b4ed85d942910a7
5
+ SHA512:
6
+ metadata.gz: 0164e10150ecceda7d6d4cafd6e8870a0762f36cddd577705b9916328886f1a495c8130c8e4e84bbdbd9007ef80fd9d2c5ff0dfe251830ebfa665e78eb8d515f
7
+ data.tar.gz: 0b2c65dbc1b798c88d741f69e0d4bf9bb64dde633616418cefba5189ef013302afb15439b9558bc35ab3961a679afa596fb2eb0669c21b4235bef3548e43dc89
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ *.gem
2
+ *.rbc
3
+ .DS_Store
4
+ .bundle
5
+ .rvmrc
6
+ .ruby-version
7
+ .yardoc
8
+ .rake_tasks~
9
+ Gemfile.lock
10
+ coverage/*
11
+ doc/*
12
+ log/*
13
+ pkg/*
14
+ .idea/*
data/.hound.yml ADDED
@@ -0,0 +1,2 @@
1
+ ruby:
2
+ config_file: .rubocop.yml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=documentation
3
+ --backtrace
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ Style/StringLiterals:
2
+ EnforcedStyle: double_quotes
3
+ Style/StringLiteralsInInterpolation:
4
+ EnforcedStyle: double_quotes
5
+ Metrics/LineLength:
6
+ Enabled: false
7
+ Metrics/BlockLength:
8
+ Enabled: false
9
+ Style/TrailingCommaInLiteral:
10
+ EnforcedStyleForMultiline: comma
11
+ AllCops:
12
+ Exclude:
13
+ - "vendor/**/*"
14
+ UseCache: false
15
+ TargetRubyVersion: 2.2
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ matrix:
3
+ fast_finish: true
4
+ include:
5
+ - rvm: 2.1
6
+ - rvm: 2.2
7
+ - rvm: 2.3
8
+ - rvm: 2.4
9
+ - rvm: ruby-head
10
+ - rvm: jruby-head
11
+ allow_failures:
12
+ - rvm: jruby-head
13
+ - rvm: ruby-head
14
+ - rvm: 2.0
15
+ - rvm: 2.1
16
+ install:
17
+ - bundle install --jobs=3 --retry=3
18
+ script:
19
+ - rake
20
+ - rake build
data/.yardopts ADDED
@@ -0,0 +1,9 @@
1
+ --no-private
2
+ --protected
3
+ --tag format:"Supported formats"
4
+ --tag authenticated:"Requires Authentication"
5
+ --tag rate_limited:"Rate Limited"
6
+ --markup markdown
7
+ -
8
+ HISTORY.mkd
9
+ LICENSE.mkd
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,30 @@
1
+ BSD License
2
+
3
+ For Ruby Instagram Gem software
4
+
5
+ Copyright (c) 2014, Facebook, Inc. All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification,
8
+ are permitted provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice, this
11
+ list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright notice,
14
+ this list of conditions and the following disclaimer in the documentation
15
+ and/or other materials provided with the distribution.
16
+
17
+ * Neither the name Facebook nor the names of its contributors may be used to
18
+ endorse or promote products derived from this software without specific
19
+ prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/PATENTS.md ADDED
@@ -0,0 +1,23 @@
1
+ Additional Grant of Patent Rights
2
+
3
+ "Software" means the Instagram Ruby Gem software distributed by Facebook, Inc.
4
+
5
+ Facebook hereby grants you a perpetual, worldwide, royalty-free, non-exclusive,
6
+ irrevocable (subject to the termination provision below) license under any
7
+ rights in any patent claims owned by Facebook, to make, have made, use, sell,
8
+ offer to sell, import, and otherwise transfer the Software. For avoidance of
9
+ doubt, no license is granted under Facebook’s rights in any patent claims that
10
+ are infringed by (i) modifications to the Software made by you or a third party,
11
+ or (ii) the Software in combination with any software or other technology
12
+ provided by you or a third party.
13
+
14
+ The license granted hereunder will terminate, automatically and without notice,
15
+ for anyone that makes any claim (including by filing any lawsuit, assertion or
16
+ other action) alleging (a) direct, indirect, or contributory infringement or
17
+ inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or
18
+ affiliates, whether or not such claim is related to the Software, (ii) by any
19
+ party if such claim arises in whole or in part from any software, product or
20
+ service of Facebook or any of its subsidiaries or affiliates, whether or not
21
+ such claim is related to the Software, or (iii) by any party relating to the
22
+ Software; or (b) that any right in any patent claim of Facebook is invalid or
23
+ unenforceable.
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # Instagram-Continued
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/instagram-continued.svg)](https://badge.fury.io/rb/instagram-continued) [![Build Status](https://travis-ci.org/icco/instagram-continued.svg?branch=master)](https://travis-ci.org/icco/instagram-continued)
4
+
5
+ [![Dependency Status](https://gemnasium.com/badges/github.com/icco/instagram-continued.svg)](https://gemnasium.com/github.com/icco/instagram-continued)
6
+
7
+ This is an attempt to get the instagram gem working again, despite it's abandonment by Facebook.
8
+
9
+ ## Installation
10
+
11
+ - `gem install instagram-continued` or `gem "instagram-continued", require: "instagram"`
12
+
13
+ This gem only supports Ruby >= 2.2
14
+
15
+ The original Gem, and its docs are at https://github.com/facebookarchive/instagram-ruby-gem.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec/core/rake_task"
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: :spec
8
+ task test: :spec
9
+
10
+ namespace :doc do
11
+ require "yard"
12
+ YARD::Rake::YardocTask.new do |task|
13
+ task.files = ["HISTORY.mkd", "LICENSE.mkd", "lib/**/*.rb"]
14
+ task.options = [
15
+ "--protected",
16
+ "--output-dir", "doc/yard",
17
+ "--tag", "format:Supported formats",
18
+ "--tag", "authenticated:Requires Authentication",
19
+ "--tag", "rate_limited:Rate Limited",
20
+ "--markup", "markdown"
21
+ ]
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path("../lib/instagram/version", __FILE__)
4
+
5
+ Gem::Specification.new do |s|
6
+ s.add_development_dependency("bluecloth", "~> 2.2")
7
+ s.add_development_dependency("rake", "~> 11.2")
8
+ s.add_development_dependency("rspec", "~> 3.4")
9
+ s.add_development_dependency("rubocop")
10
+ s.add_development_dependency("simplecov")
11
+ s.add_development_dependency("webmock", "~> 1.22")
12
+ s.add_development_dependency("yard", "~> 0.9")
13
+
14
+ s.add_runtime_dependency("faraday", "~> 0.12")
15
+ s.add_runtime_dependency("faraday_middleware")
16
+ s.add_runtime_dependency("multi_json")
17
+ s.add_runtime_dependency("hashie", ">= 3.5.1")
18
+
19
+ s.authors = ["Shayne Sweeney", "Nat Welch", "Esther Lozano"]
20
+ s.description = "A Ruby wrapper for the Instagram REST and Search APIs"
21
+ s.email = ["shayne@instagr.am", "nat@natwelch.com", "elozano@carto.com"]
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
23
+ s.files = `git ls-files`.split("\n")
24
+ s.homepage = "https://github.com/esloho/instagram-continued-continued"
25
+ s.name = "instagram-continued-continued"
26
+ s.platform = Gem::Platform::RUBY
27
+ s.require_paths = ["lib"]
28
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6")
29
+ s.required_ruby_version = Gem::Requirement.new(">= 2.0.0")
30
+ s.rubyforge_project = s.name
31
+ s.summary = "Ruby wrapper for the Instagram API"
32
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
33
+ s.version = Instagram::VERSION.dup
34
+ end
@@ -0,0 +1,74 @@
1
+ require "faraday"
2
+
3
+ # @private
4
+ module FaradayMiddleware
5
+ # @private
6
+ class LoudLogger < Faraday::Middleware
7
+ extend Forwardable
8
+ def_delegators :@logger, :debug, :info, :warn, :error, :fatal
9
+
10
+ def initialize(app, options = {})
11
+ @app = app
12
+ @logger = options.fetch(:logger) do
13
+ require "logger"
14
+ ::Logger.new($stdout)
15
+ end
16
+ end
17
+
18
+ def call(env)
19
+ start_time = Time.now
20
+ info { request_info(env) }
21
+ debug { request_debug(env) }
22
+ @app.call(env).on_complete do
23
+ end_time = Time.now
24
+ response_time = end_time - start_time
25
+ info { response_info(env, response_time) }
26
+ debug { response_debug(env) }
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def filter(output)
33
+ if ENV["INSTAGRAM_GEM_REDACT"]
34
+ output = output.to_s.gsub(/client_id=[a-zA-Z0-9]*/, "client_id=[CLIENT-ID]")
35
+ output = output.to_s.gsub(/access_token=[a-zA-Z0-9]*/, "access_token=[ACCESS-TOKEN]")
36
+ else
37
+ output
38
+ end
39
+ end
40
+
41
+ def request_info(env)
42
+ format("Started %s request to: %s", env[:method].to_s.upcase, filter(env[:url]))
43
+ end
44
+
45
+ def response_info(env, response_time)
46
+ format("Response from %s; Status: %d; Time: %.1fms", filter(env[:url]), env[:status], (response_time * 1_000.0))
47
+ end
48
+
49
+ def request_debug(env)
50
+ debug_message("Request", env[:request_headers], env[:body])
51
+ end
52
+
53
+ def response_debug(env)
54
+ debug_message("Response", env[:response_headers], env[:body])
55
+ end
56
+
57
+ def debug_message(name, headers, body)
58
+ <<-MESSAGE.gsub(/^ +([^ ])/m, '\\1')
59
+ #{name} Headers:
60
+ ----------------
61
+ #{format_headers(headers)}
62
+
63
+ #{name} Body:
64
+ -------------
65
+ #{filter(body)}
66
+ MESSAGE
67
+ end
68
+
69
+ def format_headers(headers)
70
+ length = headers.map { |k, _v| k.to_s.size }.max
71
+ headers.map { |name, value| "#{name.to_s.ljust(length)} : #{filter(value)}" }.join("\n")
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,40 @@
1
+ require "faraday"
2
+
3
+ # @private
4
+ module FaradayMiddleware
5
+ # @private
6
+ class InstagramOAuth2 < Faraday::Middleware
7
+ def call(env)
8
+ if (env[:method] == :get) || (env[:method] == :delete)
9
+ query = if env[:url].query.nil?
10
+ {}
11
+ else
12
+ Faraday::Utils.parse_query(env[:url].query)
13
+ end
14
+
15
+ if @access_token && !(query["client_secret"])
16
+ env[:url].query = Faraday::Utils.build_query(query.merge(access_token: @access_token))
17
+ env[:request_headers] = env[:request_headers].merge("Authorization" => "Token token=\"#{@access_token}\"")
18
+ elsif @client_id
19
+ env[:url].query = Faraday::Utils.build_query(query.merge(client_id: @client_id))
20
+ end
21
+ else
22
+ if @access_token && !(env[:body] && env[:body][:client_secret])
23
+ env[:body] = {} if env[:body].nil?
24
+ env[:body] = env[:body].merge(access_token: @access_token)
25
+ env[:request_headers] = env[:request_headers].merge("Authorization" => "Token token=\"#{@access_token}\"")
26
+ elsif @client_id
27
+ env[:body] = env[:body].merge(client_id: @client_id)
28
+ end
29
+ end
30
+
31
+ @app.call env
32
+ end
33
+
34
+ def initialize(app, client_id, access_token = nil)
35
+ @app = app
36
+ @client_id = client_id
37
+ @access_token = access_token
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ require "faraday"
2
+
3
+ # @private
4
+ module FaradayMiddleware
5
+ # @private
6
+ class RaiseHttpException < Faraday::Middleware
7
+ def call(env)
8
+ @app.call(env).on_complete do |response|
9
+ case response[:status].to_i
10
+ when 400
11
+ raise Instagram::BadRequest, error_message_400(response)
12
+ when 403
13
+ raise Instagram::Forbidden, error_message_400(response)
14
+ when 404
15
+ raise Instagram::NotFound, error_message_400(response)
16
+ when 429
17
+ raise Instagram::TooManyRequests, error_message_400(response)
18
+ when 500
19
+ raise Instagram::InternalServerError, error_message_500(response, "Something is technically wrong.")
20
+ when 502
21
+ raise Instagram::BadGateway, error_message_500(response, "The server returned an invalid or incomplete response.")
22
+ when 503
23
+ raise Instagram::ServiceUnavailable, error_message_500(response, "Instagram is rate limiting your requests.")
24
+ when 504
25
+ raise Instagram::GatewayTimeout, error_message_500(response, "504 Gateway Time-out")
26
+ end
27
+ end
28
+ end
29
+
30
+ def initialize(app)
31
+ super app
32
+ @parser = nil
33
+ end
34
+
35
+ private
36
+
37
+ def error_message_400(response)
38
+ "#{response[:method].to_s.upcase} #{response[:url]}: #{response[:status]}#{error_body(response[:body])}"
39
+ end
40
+
41
+ def error_body(body)
42
+ # body gets passed as a string, not sure if it is passed as something else from other spots?
43
+ if !body.nil? && !body.empty? && body.is_a?(String)
44
+ # removed multi_json thanks to wesnolte's commit
45
+ body = ::JSON.parse(body)
46
+ end
47
+
48
+ if body.nil?
49
+ nil
50
+ elsif body["meta"] && body["meta"]["error_message"] && !body["meta"]["error_message"].empty?
51
+ ": #{body["meta"]["error_message"]}"
52
+ elsif body["error_message"] && !body["error_message"].empty?
53
+ ": #{body["error_type"]}: #{body["error_message"]}"
54
+ end
55
+ end
56
+
57
+ def error_message_500(response, body = nil)
58
+ "#{response[:method].to_s.upcase} #{response[:url]}: #{[response[:status].to_s + ":", body].compact.join(" ")}"
59
+ end
60
+ end
61
+ end
data/lib/instagram.rb ADDED
@@ -0,0 +1,28 @@
1
+ require File.expand_path("../instagram/error", __FILE__)
2
+ require File.expand_path("../instagram/configuration", __FILE__)
3
+ require File.expand_path("../instagram/api", __FILE__)
4
+ require File.expand_path("../instagram/client", __FILE__)
5
+ require File.expand_path("../instagram/response", __FILE__)
6
+ require File.expand_path("../instagram/hashie_wrapper", __FILE__)
7
+
8
+ module Instagram
9
+ extend Configuration
10
+
11
+ # Alias for Instagram::Client.new
12
+ #
13
+ # @return [Instagram::Client]
14
+ def self.client(options = {})
15
+ Instagram::Client.new(options)
16
+ end
17
+
18
+ # Delegate to Instagram::Client
19
+ def self.method_missing(method, *args, &block)
20
+ return super unless client.respond_to?(method)
21
+ client.send(method, *args, &block)
22
+ end
23
+
24
+ # Delegate to Instagram::Client
25
+ def self.respond_to?(method, include_all = false)
26
+ client.respond_to?(method, include_all) || super
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path("../connection", __FILE__)
2
+ require File.expand_path("../request", __FILE__)
3
+ require File.expand_path("../oauth", __FILE__)
4
+
5
+ module Instagram
6
+ # @private
7
+ class API
8
+ # @private
9
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
10
+
11
+ # Creates a new API
12
+ def initialize(options = {})
13
+ options = Instagram.options.merge(options)
14
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
15
+ send("#{key}=", options[key])
16
+ end
17
+ end
18
+
19
+ def config
20
+ conf = {}
21
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
22
+ conf[key] = send key
23
+ end
24
+ conf
25
+ end
26
+
27
+ include Connection
28
+ include Request
29
+ include OAuth
30
+ end
31
+ end