imgurapi 3.0.2 → 3.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 264b754ad1bbbc5beae5b00bc28280502866d7b0
4
- data.tar.gz: f63f1d965d99acbe5512cebd6b44345d4c66f6bd
3
+ metadata.gz: cff8c35e8361a8f17f30d62cf865c9dfc12dbbc2
4
+ data.tar.gz: a6612b4296b9ec7a33418c382cd80684cd78bab9
5
5
  SHA512:
6
- metadata.gz: 8d58037624698e6c5fca78b770d2a17edc4d9911a57013710727ee1ca960e7f856fca25105b127576f441981b82580a8eebfe96ed8eb1161fe7f607dc1cca48c
7
- data.tar.gz: 337e0d31f5ee6e004a82fb489f738fe7a632e9fca3d7eca07da613458a70259f3e0040af844fca1b18dc405168a57c0f4c0ee07148c7a4aa39884ece52c7d282
6
+ metadata.gz: e89da47ea0da8ba5c26db3a2adf7403184325dbd8dbaa9ef22050a05b590d4920c6766650e23a76d373bd48f5e5057d0e95c797fc6a7d5eea33abb832df35a83
7
+ data.tar.gz: c98fcd1d38fe797f5bb0f63f8a9b8c1834b81e5e919751caf24c03f9d1e8ce4549f67d933beea88aec40c779d75fdd9e13d98e15852e8900efd48f782ca22480
data/README.md CHANGED
@@ -46,7 +46,7 @@ Copy the credentials shown as JSON or YAML, depending how you're going to use th
46
46
 
47
47
  Create a session object to communicate to Imgur.
48
48
  ```ruby
49
- imgur_session = Imgurapi::Session.new(client_id: 'CLIENT_ID', client_secret: 'CLIENT_SECRET', refresh_token: 'REFRESH_TOKEN')
49
+ imgur_session = Imgurapi::Session.instance(client_id: 'CLIENT_ID', client_secret: 'CLIENT_SECRET', refresh_token: 'REFRESH_TOKEN')
50
50
  ```
51
51
 
52
52
  Your account:
@@ -60,9 +60,13 @@ How many images you have:
60
60
  puts imgur_session.account.image_count
61
61
  ```
62
62
 
63
- Upload your first image. Argument can be either a String or a File:
63
+ Upload your first image. Argument can either be a path to a file, a File or a link:
64
64
  ```ruby
65
65
  image = imgur_session.image.image_upload('portrait.jpg')
66
+ # or
67
+ image = imgur_session.image.image_upload(portrait_file)
68
+ # or
69
+ image = imgur_session.image.image_upload('http://domain.tld/portrait.jpg')
66
70
  ```
67
71
 
68
72
  image is now an instance of Imgurapi::Image, a convenient way to manage all the attributes of your image (at least more convenient than a multilevel dictionary):
@@ -115,6 +119,7 @@ imgur_session.image.image_delete('xyzzy')
115
119
  It will return true if succeeded, false otherwise.
116
120
 
117
121
  ## Available endpoints
122
+
118
123
  Not all the endpoints available at https://api.imgur.com/ have been implemented.
119
124
  Feel free to suggest or pull request your needs.
120
125
 
@@ -129,3 +134,15 @@ Although I consider this is clearer, in the future it may change to follow the n
129
134
  | Image | image.image | https://api.imgur.com/endpoints/image#image |
130
135
  | Image | image.image_upload | https://api.imgur.com/endpoints/image#image-upload |
131
136
  | Image | image.image_delete | https://api.imgur.com/endpoints/image#image-delete |
137
+
138
+ ## Accessing more than one account at once
139
+
140
+ Imgur's ACCESS_TOKEN expires after 1 month. When you make an API request, if the ACCESS_TOKEN is invalid, the library will attempt to get a new one via the REFRESH_TOKEN. This new ACCESS_TOKEN will live with the instance of the library, if you instantiated the Imgurapi::Session with `.new`. So if you instantiate a new session, the token will be requested again.
141
+
142
+ Given requesting a new ACCESS_TOKEN on every API call is slow, the recommended way of using Imgurapi::Session is via `.instance`, not `.new` so it requests a fresh ACCESS_TOKEN only once, which will be stored at class level, reducing optimally the number of token requests.
143
+
144
+ This approach is not feasible if you want to handle several Imgur accounts at once.
145
+
146
+ In short:
147
+ - instantiate Imgurapi::Session via `.instance` if you manage 1 account
148
+ - instantiate Imgurapi::Session via `.new` if you manage 2 or more accounts
data/lib/imgurapi.rb CHANGED
@@ -9,6 +9,7 @@ require 'imgurapi/api/base'
9
9
  require 'imgurapi/api/account'
10
10
  require 'imgurapi/api/image'
11
11
  require 'imgurapi/communication'
12
+ require 'imgurapi/file_type'
12
13
  require 'imgurapi/session'
13
14
  require 'imgurapi/models/base'
14
15
  require 'imgurapi/models/account'
@@ -11,15 +11,19 @@ module Imgurapi
11
11
 
12
12
  # https://api.imgur.com/endpoints/image#image-upload
13
13
  def image_upload(local_file)
14
- if local_file.is_a?(String)
15
- file = File.open(local_file, 'rb')
16
- elsif local_file.respond_to? :read
17
- file = local_file
18
- else
19
- raise 'Must provide a File or file path'
20
- end
14
+ file_type = FileType.new(local_file)
15
+
16
+ image = if file_type.url?
17
+ local_file
18
+ else
19
+ raise 'File must be an image' unless file_type.image?
20
+
21
+ file = local_file.respond_to?(:read) ? local_file : File.open(local_file, 'rb')
22
+
23
+ Base64.encode64(file.read)
24
+ end
21
25
 
22
- Imgurapi::Image.new communication.call(:post, 'image', image: Base64.encode64(file.read))
26
+ Imgurapi::Image.new communication.call(:post, 'image', image: image)
23
27
  end
24
28
 
25
29
  # https://api.imgur.com/endpoints/image#image-delete
@@ -24,13 +24,17 @@ module Imgurapi
24
24
  case response.status
25
25
  when 200, 404
26
26
  return parse_message(response.body)['data']
27
- when 401, 500
27
+ when 400
28
+ raise 'Payload is not an image or recognized by Imgur'
29
+ when 401
28
30
  error_message = parse_message response.body
29
31
  raise "Unauthorized: #{error_message['error']['message']}"
30
32
  when 403
31
33
  get_new_and_reset_token
32
34
 
33
35
  request attempt + 1, &block # and retry the request once more
36
+ when 500
37
+ raise 'Imgur internal error'
34
38
  else
35
39
  raise "Response code #{response.status} not recognized"
36
40
  end
@@ -0,0 +1,34 @@
1
+ module Imgurapi
2
+ class FileType
3
+
4
+ GIF = /^GIF8/
5
+ PNG = Regexp.new("^\x89PNG".force_encoding('binary'))
6
+ JPG = Regexp.new("^\xff\xd8\xff\xe0\x00\x10JFIF".force_encoding('binary'))
7
+ JPG2 = Regexp.new("^\xff\xd8\xff\xe1(.*){2}Exif".force_encoding('binary'))
8
+
9
+ def initialize(path)
10
+ @path = path
11
+ end
12
+
13
+ def mime_type
14
+ case IO.read(@path, 10)
15
+ when GIF
16
+ 'image/gif'
17
+ when PNG
18
+ 'image/png'
19
+ when JPG
20
+ 'image/jpeg'
21
+ when JPG2
22
+ 'image/jpeg'
23
+ end
24
+ end
25
+
26
+ def image?
27
+ !!mime_type
28
+ end
29
+
30
+ def url?
31
+ !!(@path =~ %r(^(http://|https://|ftp://)))
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Imgurapi
2
2
 
3
- VERSION = '3.0.2'
3
+ VERSION = '3.1.0'
4
4
 
5
5
  end
@@ -4,7 +4,6 @@ require 'imgurapi'
4
4
  describe Imgurapi::Api::Image do
5
5
 
6
6
  before :all do
7
- credentials = read_credentials_file
8
7
  @session = Imgurapi::Session.new(credentials)
9
8
  end
10
9
 
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'imgurapi'
3
+
4
+ describe Imgurapi::FileType do
5
+
6
+ describe '#mime_type' do
7
+ it 'returns the right types' do
8
+ expect(described_class.new('sample.gif').mime_type).to eq 'image/gif'
9
+ expect(described_class.new('sample.png').mime_type).to eq 'image/png'
10
+ expect(described_class.new('sample.jpg').mime_type).to eq 'image/jpeg'
11
+ expect(described_class.new('sample.jpg2').mime_type).to eq 'image/jpeg'
12
+ expect(described_class.new('sample.txt').mime_type).to be_nil
13
+ end
14
+ end
15
+
16
+ describe '#image?' do
17
+ it 'returns true for images' do
18
+ expect(described_class.new('sample.jpg').image?).to be true
19
+ end
20
+
21
+ it 'returns false for anything else' do
22
+ expect(described_class.new('sample.txt').image?).to be false
23
+ end
24
+ end
25
+
26
+
27
+ describe '#url?' do
28
+ it 'returns true for a valid URL' do
29
+ expect(described_class.new('http://domain.tld/sample.jpg').url?).to be true
30
+ expect(described_class.new('https://domain.tld/sample.jpg').url?).to be true
31
+ expect(described_class.new('ftp://domain.tld/sample.jpg').url?).to be true
32
+ end
33
+
34
+ it 'returns false for anything else' do
35
+ expect(described_class.new('smb://sample.txt').url?).to be false
36
+ expect(described_class.new('sample.txt').url?).to be false
37
+ end
38
+ end
39
+ end
@@ -4,23 +4,29 @@ require 'imgurapi'
4
4
  describe Imgurapi do
5
5
 
6
6
  it 'does an integration test by uploading, retrieving and deleting an image' do
7
- credentials = read_credentials_file
8
- @session = Imgurapi::Session.new(credentials)
9
- @upload_path, @upload_file = my_sample_image
7
+ session = Imgurapi::Session.new(credentials)
10
8
 
11
- # Upload image
12
- image = @session.image.image_upload(@upload_path)
9
+ # Upload image via path
10
+ image = session.image.image_upload('sample.jpg')
11
+
12
+ # Upload image via file
13
+ image2 = session.image.image_upload(File.open('sample.jpg', 'r'))
14
+
15
+ # Upload image via link
16
+ image3 = session.image.image_upload('http://www.nationalcrimesyndicate.com/wp-content/uploads/2014/02/Ace.jpg')
13
17
 
14
18
  # It is there
15
- expect(@session.account.image_count).to be > 0
19
+ expect(session.account.image_count).to be > 0
16
20
 
17
21
  # Retrieve same image
18
- retrieved_image = @session.image.image(image.id)
22
+ retrieved_image = session.image.image(image.id)
19
23
 
20
24
  # Same, indeed
21
25
  expect(retrieved_image.id).to eq(image.id)
22
26
 
23
- # Delete image
24
- expect(@session.image.image_delete(image)).to eq true
27
+ # Delete all images
28
+ expect(session.image.image_delete(image)).to eq true
29
+ expect(session.image.image_delete(image2)).to eq true
30
+ expect(session.image.image_delete(image3)).to eq true
25
31
  end
26
32
  end
data/spec/spec_helper.rb CHANGED
@@ -1,30 +1,22 @@
1
1
  module EverythingAsExpected
2
2
 
3
- def read_credentials_file
3
+ def credentials
4
4
  unless File.exist? 'credentials.json'
5
5
  raise "Please add a credentials.json file to the project directory containing your Imgur app_key, app_secret, access_token and access_token_secret. See credentials.json.example to get started."
6
6
  end
7
7
 
8
8
  credentials_file_contents = File.open('credentials.json', 'r').read
9
- credentials = JSON.parse(credentials_file_contents)
10
- if credentials.keys.count != 4 and credentials.keys & [:app_key, :app_secret, :access_token, :access_token_secret] != [:app_key, :app_secret, :access_token, :access_token_secret]
9
+ credentials_hash = JSON.parse(credentials_file_contents)
10
+ if credentials_hash.keys.count != 4 and credentials_hash.keys & [:app_key, :app_secret, :access_token, :access_token_secret] != [:app_key, :app_secret, :access_token, :access_token_secret]
11
11
  raise "Your credentials.json file does contain all the required information. See credentials.json.example for more help."
12
12
  end
13
13
 
14
- credentials.inject({}) do |options, (key, value)|
14
+ credentials_hash.inject({}) do |options, (key, value)|
15
15
  options[key.to_sym] = value
16
16
  options
17
17
  end
18
18
  end
19
19
 
20
- def my_sample_image
21
- unless File.exist? 'sample.jpg'
22
- raise "Please add a sample.jpg file to the project directory to test upload and download. Recommended size: under 30kB"
23
- end
24
-
25
- ['sample.jpg', File.open('sample.jpg', 'r')]
26
- end
27
-
28
20
  end
29
21
 
30
22
  RSpec.configure do |config|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imgurapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Cruz Horts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-12 00:00:00.000000000 Z
11
+ date: 2017-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -80,6 +80,7 @@ files:
80
80
  - lib/imgurapi/api/base.rb
81
81
  - lib/imgurapi/api/image.rb
82
82
  - lib/imgurapi/communication.rb
83
+ - lib/imgurapi/file_type.rb
83
84
  - lib/imgurapi/models/account.rb
84
85
  - lib/imgurapi/models/base.rb
85
86
  - lib/imgurapi/models/image.rb
@@ -89,6 +90,7 @@ files:
89
90
  - lib/imgurapi/tasks/tasks.rake
90
91
  - lib/imgurapi/version.rb
91
92
  - spec/imgurapi/api/image_spec.rb
93
+ - spec/imgurapi/file_type_spec.rb
92
94
  - spec/imgurapi/models/image_spec.rb
93
95
  - spec/imgurapi/session_spec.rb
94
96
  - spec/imgurapi_spec.rb
@@ -113,12 +115,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
115
  version: '0'
114
116
  requirements: []
115
117
  rubyforge_project:
116
- rubygems_version: 2.6.11
118
+ rubygems_version: 2.6.13
117
119
  signing_key:
118
120
  specification_version: 4
119
121
  summary: Imgur authenticated API
120
122
  test_files:
121
123
  - spec/imgurapi/api/image_spec.rb
124
+ - spec/imgurapi/file_type_spec.rb
122
125
  - spec/imgurapi/models/image_spec.rb
123
126
  - spec/imgurapi/session_spec.rb
124
127
  - spec/imgurapi_spec.rb