instagram 1.1.4 → 1.1.5

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- M2Y3MDRiMGZmYTMzMzk1MDVkYTc3MGRjYTBjNWM5ZjFhMjY5NDA4Zg==
4
+ YTgwYTQ4MzU4NDI1ZmI4ZTM0MGNmZDIxM2I3ZTI3YWMyMDAyNDFlYg==
5
5
  data.tar.gz: !binary |-
6
- ZTY4N2RkYzBmYTdkNWZlM2ExNTgzN2FjNzhmYWQ5OGU3YjA0M2JiYg==
6
+ YTdiYWFiNTliYjdlNzAyMjdhMGE1YThmNjFjNmE1YjdkZjgyY2NhZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NjY2Nzg2MjM1YmIwYTM5MDVjYzRiMmZlNDdlNDY1YWFlYzZhN2ExMWE2NDZm
10
- NTI0NzIxNDkxMTNiMWIxYWMyZGMzZjE1ZGYxOWM2YWQ1MGQ3ZWEwMzJmZWU3
11
- NjJmMGEzMWY5YTUyZGQwOGIxZGIyOWZmNDk0ZjhiMDU3N2QwYjY=
9
+ ZTFjM2ViODI3NGE4ZTk4ZTM3Y2FlOTM3Nzk4MjFlYzgwYjEyMTE2YWUyODIz
10
+ MzY2ZmNhMTJlNzdhNWE3ZGY1NDkwMzIxNzJmYjI1ZWEzNWM2ZGIxZmI1ZTJi
11
+ MjJhYzVlZGQ4ZDVjYjE0OTQ4ZmMzNWQyOWZiOTQ4M2EyOTQwZDg=
12
12
  data.tar.gz: !binary |-
13
- ZmZhOTBhYTRiODQ1ZjE5ODZjM2RlN2IwYzBjMWM5NDUxMGQwYmM5MmQ3YWEx
14
- YjQ5YzRjMTFjODUxOTVmNGE0ZGMyMDNjNzVlMWY0NmNlYTAzYjM2MzBhY2Vi
15
- ODE3YTljY2ViYjdiZmZlNzRjNGM0YmUwMmRhZWE3MTAzYTcwYjc=
13
+ MzhlODQzNzE2YjJjZTllMGRkNGIxNTg4NjAyMWFkOTZmYjgyY2U2ZWQzZjY2
14
+ ZGNkMGQ1MmQwNmI1NjcxMDY5ODczNjE0YTA1MDJlZGRkYTlmNDZjZWIwODQz
15
+ MTBmNjczNjBjOWE4MTBkMGM5ZGIxN2ZkNmYzNzc3YjcyMTJmZDE=
@@ -0,0 +1,75 @@
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) {
13
+ require 'logger'
14
+ ::Logger.new($stdout)
15
+ }
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
+ "Started %s request to: %s" % [ env[:method].to_s.upcase, filter(env[:url]) ]
43
+ end
44
+
45
+ def response_info(env, response_time)
46
+ "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
+
74
+ end
75
+ end
@@ -18,7 +18,8 @@ module Instagram
18
18
  :format,
19
19
  :proxy,
20
20
  :user_agent,
21
- :no_response_wrapper
21
+ :no_response_wrapper,
22
+ :loud_logger,
22
23
  ].freeze
23
24
 
24
25
  # By default, don't set a user access token
@@ -72,6 +73,9 @@ module Instagram
72
73
  VALID_FORMATS = [
73
74
  :json].freeze
74
75
 
76
+ # By default, don't turn on loud logging
77
+ DEFAULT_LOUD_LOGGER = nil
78
+
75
79
  # @private
76
80
  attr_accessor *VALID_OPTIONS_KEYS
77
81
 
@@ -107,6 +111,7 @@ module Instagram
107
111
  self.proxy = DEFAULT_PROXY
108
112
  self.user_agent = DEFAULT_USER_AGENT
109
113
  self.no_response_wrapper= DEFAULT_NO_RESPONSE_WRAPPER
114
+ self.loud_logger = DEFAULT_LOUD_LOGGER
110
115
  end
111
116
  end
112
117
  end
@@ -23,6 +23,7 @@ module Instagram
23
23
  end
24
24
  end
25
25
  connection.use FaradayMiddleware::RaiseHttpException
26
+ connection.use FaradayMiddleware::LoudLogger if loud_logger
26
27
  connection.adapter(adapter)
27
28
  end
28
29
  end
@@ -5,31 +5,43 @@ module Instagram
5
5
  # Defines HTTP request methods
6
6
  module Request
7
7
  # Perform an HTTP GET request
8
- def get(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper())
9
- request(:get, path, options, signature, raw, unformatted, no_response_wrapper)
8
+ def get(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper(), signed=false)
9
+ request(:get, path, options, signature, raw, unformatted, no_response_wrapper, signed)
10
10
  end
11
11
 
12
12
  # Perform an HTTP POST request
13
- def post(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper())
14
- request(:post, path, options, signature, raw, unformatted, no_response_wrapper)
13
+ def post(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper(), signed=false)
14
+ request(:post, path, options, signature, raw, unformatted, no_response_wrapper, signed)
15
15
  end
16
16
 
17
17
  # Perform an HTTP PUT request
18
- def put(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper())
19
- request(:put, path, options, signature, raw, unformatted, no_response_wrapper)
18
+ def put(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper(), signed=false)
19
+ request(:put, path, options, signature, raw, unformatted, no_response_wrapper, signed)
20
20
  end
21
21
 
22
22
  # Perform an HTTP DELETE request
23
- def delete(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper())
24
- request(:delete, path, options, signature, raw, unformatted, no_response_wrapper)
23
+ def delete(path, options={}, signature=false, raw=false, unformatted=false, no_response_wrapper=no_response_wrapper(), signed=false)
24
+ request(:delete, path, options, signature, raw, unformatted, no_response_wrapper, signed)
25
25
  end
26
26
 
27
27
  private
28
28
 
29
29
  # Perform an HTTP request
30
- def request(method, path, options, signature=false, raw=false, unformatted=false, no_response_wrapper=false)
30
+ def request(method, path, options, signature=false, raw=false, unformatted=false, no_response_wrapper=false, signed=false)
31
31
  response = connection(raw).send(method) do |request|
32
32
  path = formatted_path(path) unless unformatted
33
+
34
+ if signed == true
35
+ if client_id != nil
36
+ sig_options = options.merge({:client_id => client_id})
37
+ end
38
+ if access_token != nil
39
+ sig_options = options.merge({:access_token => access_token})
40
+ end
41
+ sig = generate_sig("/"+path, sig_options, client_secret)
42
+ options[:sig] = sig
43
+ end
44
+
33
45
  case method
34
46
  when :get, :delete
35
47
  request.url(path, options)
@@ -57,5 +69,14 @@ module Instagram
57
69
  return [ips, signature].join('|')
58
70
  end
59
71
 
72
+ def generate_sig(endpoint, params, secret)
73
+ sig = endpoint
74
+ params.sort.map do |key, val|
75
+ sig += '|%s=%s' % [key, val]
76
+ end
77
+ digest = OpenSSL::Digest::Digest.new('sha256')
78
+ return OpenSSL::HMAC.hexdigest(digest, secret, sig)
79
+ end
80
+
60
81
  end
61
82
  end
@@ -1,3 +1,3 @@
1
1
  module Instagram
2
- VERSION = '1.1.4'.freeze unless defined?(::Instagram::VERSION)
2
+ VERSION = '1.1.5'.freeze unless defined?(::Instagram::VERSION)
3
3
  end
@@ -43,6 +43,7 @@ describe Instagram::API do
43
43
  :scope => 'comments relationships',
44
44
  :user_agent => 'Custom User Agent',
45
45
  :no_response_wrapper => true,
46
+ :loud_logger => true,
46
47
  }
47
48
  end
48
49
 
@@ -213,5 +214,71 @@ describe Instagram::API do
213
214
  should have_been_made
214
215
  end
215
216
  end
217
+
218
+ describe "loud_logger param" do
219
+
220
+ before do
221
+ @client = Instagram::Client.new(:loud_logger => true)
222
+ end
223
+
224
+ context "outputs to STDOUT with faraday logs when enabled" do
225
+ before do
226
+ stub_get('users/self/feed.json').
227
+ to_return(:body => fixture("user_media_feed.json"), :headers => {:content_type => "application/json; charset=utf-8"})
228
+ end
229
+
230
+ it "should return the body error message" do
231
+ output = capture_output do
232
+ @client.user_media_feed()
233
+ end
234
+
235
+ expect(output).to include 'INFO -- : Started GET request to: https://api.instagram.com/v1/users/self/feed.json'
236
+ expect(output).to include 'DEBUG -- : Response Headers:'
237
+ expect(output).to include "User-Agent : Instagram Ruby Gem #{Instagram::VERSION}"
238
+ expect(output).to include 'http://distillery.s3.amazonaws.com/media/2011/01/31/0f8e832c3dc6420bb6ddf0bd09f032f6_6.jpg'
239
+ end
240
+ end
241
+
242
+ context "shows STDOUT output when errors occur" do
243
+
244
+ before do
245
+ stub_get('users/self/feed.json').
246
+ to_return(:body => '{"meta":{"error_message": "Bad words are bad."}}', :status => 400)
247
+ end
248
+
249
+ it "should return the body error message" do
250
+ output = capture_output do
251
+ @client.user_media_feed() rescue nil
252
+ end
253
+
254
+ expect(output).to include 'INFO -- : Started GET request to: https://api.instagram.com/v1/users/self/feed.json'
255
+ expect(output).to include 'DEBUG -- : Response Headers:'
256
+ expect(output).to include "User-Agent : Instagram Ruby Gem #{Instagram::VERSION}"
257
+ expect(output).to include '{"meta":{"error_message": "Bad words are bad."}}'
258
+ end
259
+ end
260
+
261
+ context "will redact API keys if INSTAGRAM_GEM_REDACT=true" do
262
+ before do
263
+ stub_get('users/self/feed.json').
264
+ to_return(:body => fixture("user_media_feed.json"), :headers => {:content_type => "application/json; charset=utf-8"})
265
+ end
266
+
267
+ it "should redact API keys" do
268
+ ENV.stub(:[]).with('http_proxy').and_return(nil)
269
+ ENV.stub(:[]).with('INSTAGRAM_GEM_REDACT').and_return('true')
270
+
271
+ output = capture_output do
272
+ @client.user_media_feed()
273
+ end
274
+
275
+ expect(output).to include 'INFO -- : Started GET request to: https://api.instagram.com/v1/users/self/feed.json'
276
+ expect(output).to include 'DEBUG -- : Response Headers:'
277
+ expect(output).to include "User-Agent : Instagram Ruby Gem #{Instagram::VERSION}"
278
+ expect(output).to include 'http://distillery.s3.amazonaws.com/media/2011/01/31/0f8e832c3dc6420bb6ddf0bd09f032f6_6.jpg'
279
+ expect(output).to include 'access_token=[ACCESS-TOKEN]'
280
+ end
281
+ end
282
+ end
216
283
  end
217
284
  end
@@ -81,6 +81,19 @@ describe Instagram do
81
81
  end
82
82
  end
83
83
 
84
+ describe ".loud_logger" do
85
+ it "should return the loud_logger status" do
86
+ Instagram.loud_logger.should == nil
87
+ end
88
+ end
89
+
90
+ describe ".loud_logger=" do
91
+ it "should set the loud_logger" do
92
+ Instagram.loud_logger = true
93
+ Instagram.loud_logger.should == true
94
+ end
95
+ end
96
+
84
97
  describe ".configure" do
85
98
 
86
99
  Instagram::Configuration::VALID_OPTIONS_KEYS.each do |key|
@@ -18,6 +18,18 @@ RSpec.configure do |config|
18
18
  config.include WebMock::API
19
19
  end
20
20
 
21
+ def capture_output(&block)
22
+ begin
23
+ old_stdout = $stdout
24
+ $stdout = StringIO.new
25
+ block.call
26
+ result = $stdout.string
27
+ ensure
28
+ $stdout = old_stdout
29
+ end
30
+ result
31
+ end
32
+
21
33
  def a_delete(path)
22
34
  a_request(:delete, Instagram.endpoint + path)
23
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instagram
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shayne Sweeney
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-16 00:00:00.000000000 Z
11
+ date: 2015-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -157,6 +157,7 @@ files:
157
157
  - README.md
158
158
  - Rakefile
159
159
  - instagram.gemspec
160
+ - lib/faraday/loud_logger.rb
160
161
  - lib/faraday/oauth2.rb
161
162
  - lib/faraday/raise_http_exception.rb
162
163
  - lib/instagram.rb