instagram 1.1.4 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
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