resizing 1.1.0.pre → 1.2.1

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +17 -2
  3. data/Gemfile +6 -2
  4. data/README.md +59 -32
  5. data/lib/resizing/active_storage/service/resizing_service.rb +6 -2
  6. data/lib/resizing/active_storage/service.rb +9 -0
  7. data/lib/resizing/active_storage.rb +7 -0
  8. data/lib/resizing/carrier_wave/storage/file.rb +35 -16
  9. data/lib/resizing/carrier_wave/storage/remote.rb +7 -3
  10. data/lib/resizing/carrier_wave.rb +10 -11
  11. data/lib/resizing/client.rb +40 -24
  12. data/lib/resizing/configurable.rb +1 -1
  13. data/lib/resizing/configuration.rb +6 -16
  14. data/lib/resizing/http_clientable.rb +3 -3
  15. data/lib/resizing/mock_client.rb +6 -5
  16. data/lib/resizing/public_id.rb +5 -4
  17. data/lib/resizing/version.rb +1 -1
  18. data/lib/resizing.rb +15 -12
  19. data/resizing.gemspec +5 -8
  20. data/test/resizing/active_storage_service_test.rb +98 -0
  21. data/test/resizing/carrier_wave/storage/file_test.rb +149 -8
  22. data/test/resizing/carrier_wave/storage/remote_test.rb +75 -0
  23. data/test/resizing/carrier_wave_test.rb +99 -37
  24. data/test/resizing/client_test.rb +96 -11
  25. data/test/resizing/configurable_test.rb +82 -0
  26. data/test/resizing/configuration_test.rb +118 -2
  27. data/test/resizing/constants_test.rb +25 -0
  28. data/test/resizing/error_test.rb +73 -0
  29. data/test/resizing/http_clientable_test.rb +84 -0
  30. data/test/resizing/mock_client_test.rb +75 -0
  31. data/test/resizing/public_id_test.rb +1 -1
  32. data/test/resizing_module_test.rb +206 -0
  33. data/test/test_helper.rb +89 -9
  34. metadata +33 -47
  35. data/lib/resizing/video/client.rb +0 -116
  36. data/lib/resizing/video.rb +0 -8
  37. data/test/resizing/video/client_test.rb +0 -158
  38. data/test/vcr/video/metadata/success.yml +0 -47
  39. data/test/vcr/video/prepare/success.yml +0 -47
  40. data/test/vcr/video/upload_completed/success.yml +0 -47
  41. /data/{exe → bin}/console +0 -0
  42. /data/{exe → bin}/generate-changelog +0 -0
  43. /data/{exe → bin}/setup +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d601d6b8f87f6440de0c1c4d4dcbb74e7bc386dd3e217b66b8ac259d35939f0
4
- data.tar.gz: 3f2ce39dcb8879dee7a9717142bfa794e6cad5671e19cdd01afbb5f7dacc6787
3
+ metadata.gz: c35a202fce460c80d3b476d4d9307f6345d9d13ed95c385a0e41108f35e46e61
4
+ data.tar.gz: 14f7f3a20d83859f121b9138931164d5eb27a5a9764cd6ff2dee2dfc71aa72cd
5
5
  SHA512:
6
- metadata.gz: c221c9290ccf562d804bb9f5dca6657568c891ce4c14d825fb8a19627feec1982c09773bfb55304cd5a13b8c4bb786a57d1abe3589684da312fd0167ecfc9a28
7
- data.tar.gz: ee2dde3b29accd86dae059daf0e164fef634476886fb254b2145e3be33764d3a81308d9eea382a557817951714cbc8d4e98b02318417042a38590a4109334630
6
+ metadata.gz: 25a5f49e162e691ed72d147132d4a7aea069a6d148af8a1d22b0b3b3cedecc0b8bd46b674c177fdbef88179684342a230ffc23edb56340db42540beadc5f6947
7
+ data.tar.gz: 03b8a3544e711973f79ef66dec2400ad09fba7d571a4518f0424ede8eb3da8420fb0c8fd299bc1a7c0ad734894bcbb59fa566857790277c0c8d4f0aa67537700
@@ -7,18 +7,33 @@ on:
7
7
  - master
8
8
 
9
9
  permissions:
10
- id-token: write # This is required for requesting the JWT
10
+ id-token: write # This is required for codecov/codecov-action
11
11
  contents: read # This is required for actions/checkout
12
12
 
13
13
  jobs:
14
14
  test:
15
+ name: Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }}
15
16
  strategy:
16
17
  fail-fast: false
17
18
  matrix:
18
- ruby: ['2.7.6', '3.1', '3.2','3.3']
19
+ ruby: ['3.1', '3.2','3.3', '3.4']
20
+ rails: ['6.1', '7.0', '7.1', '7.2']
21
+ exclude:
22
+ # Rails 7.2 requires Ruby 3.1+
23
+ - ruby: '3.1'
24
+ rails: '7.2'
25
+ # Rails 7.1 requires Ruby 3.1+
26
+ - ruby: '3.1'
27
+ rails: '7.1'
28
+ # Rails 6.1 requires Ruby under 3.3
29
+ - ruby: '3.4'
30
+ rails: '6.1'
19
31
 
20
32
  runs-on: ubuntu-22.04
21
33
 
34
+ env:
35
+ RAILS_VERSION: ${{ matrix.rails }}
36
+
22
37
  steps:
23
38
  - uses: actions/checkout@v4
24
39
 
data/Gemfile CHANGED
@@ -5,8 +5,12 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in resizing.gemspec
6
6
  gemspec
7
7
 
8
- gem 'rake', '~> 13.0'
8
+ # Allow testing against different Rails versions
9
+ rails_version = ENV['RAILS_VERSION'] || '7.0'
10
+ gem 'rails', "~> #{rails_version}"
11
+
12
+ gem 'byebug'
9
13
  gem 'github_changelog_generator'
10
14
  gem 'mysql2'
11
- gem 'byebug'
12
15
  gem 'pry-byebug'
16
+ gem 'rake', '~> 13.0'
data/README.md CHANGED
@@ -1,8 +1,14 @@
1
1
  # Resizing
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/resizing`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Gem Version](https://img.shields.io/gem/v/resizing.svg)](https://rubygems.org/gems/resizing)
4
+ [![test](https://github.com/jksy/resizing-gem/actions/workflows/test.yml/badge.svg)](https://github.com/jksy/resizing-gem/actions/workflows/test.yml)
5
+ [![codecov](https://codecov.io/gh/jksy/resizing-gem/graph/badge.svg)](https://codecov.io/gh/jksy/resizing-gem)
4
6
 
5
- TODO: Delete this and the text above, and describe your gem
7
+ Client and utilities for [Resizing](https://www.resizing.net/) - an image hosting and transformation service.
8
+
9
+ ## Requirements
10
+
11
+ - Ruby 3.1.0 or later
6
12
 
7
13
  ## Installation
8
14
 
@@ -20,37 +26,59 @@ Or install it yourself as:
20
26
 
21
27
  $ gem install resizing
22
28
 
29
+ ## Configuration
30
+
31
+ ```ruby
32
+ Resizing.configure = {
33
+ image_host: 'https://img.resizing.net',
34
+ video_host: 'https://video.resizing.net',
35
+ project_id: 'your-project-id',
36
+ secret_token: 'your-secret-token'
37
+ }
38
+ ```
39
+
23
40
  ## Usage
24
41
 
42
+ ### Basic Client Usage
43
+
44
+ ```ruby
45
+ # Initialize client
46
+ client = Resizing::Client.new
47
+
48
+ # Upload image to resizing
49
+ file = File.open('sample.jpg', 'r')
50
+ response = client.post(file)
51
+ # => {
52
+ # "id"=>"a4ed2bf0-a4cf-44fa-9c82-b53e581cb469",
53
+ # "project_id"=>"098a2a0d-0000-0000-0000-000000000000",
54
+ # "content_type"=>"image/jpeg",
55
+ # "latest_version_id"=>"LJY5bxBF7Ryxfr5kC1F.63W8bzp3pcUm",
56
+ # "latest_etag"=>"\"190143614e6c342637584f46f18f8c58\"",
57
+ # "created_at"=>"2020-05-15T15:33:10.711Z",
58
+ # "updated_at"=>"2020-05-15T15:33:10.711Z",
59
+ # "url"=>"/projects/098a2a0d-0000-0000-0000-000000000000/upload/images/a4ed2bf0-a4cf-44fa-9c82-b53e581cb469"
60
+ # }
61
+
62
+ # Generate transformation URL
63
+ image_id = response['id']
64
+ transformation_url = Resizing.url_from_image_id(image_id, nil, ['w_200', 'h_300'])
65
+ # => "https://img.resizing.net/projects/.../upload/images/.../w_200,h_300"
25
66
  ```
26
- # initialize client
27
- options = {
28
- project_id: '098a2a0d-0000-0000-0000-000000000000',
29
- secret_token: '4g1cshg......rbs6'
30
- }
31
- client = Resizing::Client.new(options)
32
-
33
- # upload image to resizing
34
- file = File.open('sample.jpg', 'r')
35
- response = client.post(file)
36
- => {
37
- "id"=>"a4ed2bf0-a4cf-44fa-9c82-b53e581cb469",
38
- "project_id"=>"098a2a0d-0000-0000-0000-000000000000",
39
- "content_type"=>"image/jpeg",
40
- "latest_version_id"=>"LJY5bxBF7Ryxfr5kC1F.63W8bzp3pcUm",
41
- "latest_etag"=>"\"190143614e6c342637584f46f18f8c58\"",
42
- "created_at"=>"2020-05-15T15:33:10.711Z",
43
- "updated_at"=>"2020-05-15T15:33:10.711Z",
44
- "url"=>"/projects/098a2a0d-0000-0000-0000-000000000000/upload/images/a4ed2bf0-a4cf-44fa-9c82-b53e581cb469"
45
- }
46
-
47
- name = response['url']
48
- # get transformation url
49
- name = response['url']
50
- transform = {width: 200, height: 300}
51
-
52
- transformation_url = Resizing.url(name, transform)
53
- => "https://www.resizing.net/projects/098a2a0d-0000-0000-0000-000000000000/upload/images/a4ed2bf0-a4cf-44fa-9c82-b53e581cb469/width_200,height_300"
67
+
68
+ ### CarrierWave Integration
69
+
70
+ ```ruby
71
+ class ImageUploader < CarrierWave::Uploader::Base
72
+ include Resizing::CarrierWave
73
+
74
+ version :list_smallest do
75
+ process resize_to_fill: [200, 200]
76
+ end
77
+ end
78
+
79
+ class User
80
+ mount_uploader :image, ImageUploader
81
+ end
54
82
  ```
55
83
 
56
84
  ## Development
@@ -61,8 +89,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
61
89
 
62
90
  ## Contributing
63
91
 
64
- Bug reports and pull requests are welcome on GitHub at https://github.com/jksy/resizing.
65
-
92
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jksy/resizing-gem.
66
93
 
67
94
  ## License
68
95
 
@@ -1,15 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_storage/service'
4
+
3
5
  module Resizing
4
6
  module ActiveStorage
5
7
  module Service
6
8
  # ref.
7
9
  # https://github.com/rails/rails/blob/master/activestorage/lib/active_storage/service/s3_service.rb
8
10
  #
9
- # rubocop:disable Lint/UnusedMethodArgument,Metrics/ParameterLists
11
+ # rubocop:disable Metrics/ParameterLists
10
12
  class ResizingService < ::ActiveStorage::Service
11
13
  # def initialize(bucket:, upload: {}, public: false, **options)
14
+ # rubocop:disable Lint/MissingSuper
12
15
  def initialize; end
16
+ # rubocop:enable Lint/MissingSuper
13
17
 
14
18
  def upload(_key, _io, checksum: nil, filename: nil, content_type: nil, disposition: nil, **)
15
19
  raise NotImplementedError, 'upload is not implemented'
@@ -51,7 +55,7 @@ module Resizing
51
55
  raise NotImplementedError, 'public_url is not implemented'
52
56
  end
53
57
  end
54
- # rubocop:enable Lint/UnusedMethodArgument,Metrics/ParameterLists
58
+ # rubocop:enable Metrics/ParameterLists
55
59
  end
56
60
  end
57
61
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resizing
4
+ module ActiveStorage
5
+ module Service
6
+ autoload :ResizingService, 'resizing/active_storage/service/resizing_service'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resizing
4
+ module ActiveStorage
5
+ autoload :Service, 'resizing/active_storage/service'
6
+ end
7
+ end
@@ -3,6 +3,7 @@
3
3
  module Resizing
4
4
  module CarrierWave
5
5
  module Storage
6
+ # rubocop:disable Metrics/ClassLength
6
7
  class File
7
8
  include ::CarrierWave::Utilities::Uri
8
9
 
@@ -28,10 +29,24 @@ module Resizing
28
29
  @content_type || file.try(:content_type)
29
30
  end
30
31
 
32
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
31
33
  def delete
32
- @public_id = Resizing::PublicId.new(model.send :read_attribute, serialization_column)
34
+ # Use the identifier from constructor if available, otherwise try to get from model
35
+ if @public_id.present?
36
+ # Already set from constructor or retrieve
37
+ elsif model.respond_to?(:attribute_was)
38
+ # Try to get the value before changes (for remove! scenario)
39
+ column_value = model.attribute_was(serialization_column) || model.send(:read_attribute,
40
+ serialization_column)
41
+ @public_id = Resizing::PublicId.new(column_value)
42
+ else
43
+ column_value = model.send(:read_attribute, serialization_column)
44
+ @public_id = Resizing::PublicId.new(column_value)
45
+ end
46
+
33
47
  return if @public_id.empty? # do nothing
34
48
 
49
+ # 以下、既存のコード(変更なし)
35
50
  resp = client.delete(@public_id.image_id)
36
51
  if resp['error'] == 'ActiveRecord::RecordNotFound' # 404 not found
37
52
  model.send :write_attribute, serialization_column, nil unless model.destroyed?
@@ -45,6 +60,7 @@ module Resizing
45
60
 
46
61
  raise APIError, "raise someone error:#{resp.inspect}"
47
62
  end
63
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
48
64
 
49
65
  def extension
50
66
  raise NotImplementedError, 'this method is do not used. maybe'
@@ -83,30 +99,30 @@ module Resizing
83
99
  end
84
100
  alias path current_path
85
101
 
102
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
103
+ # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
86
104
  def store(new_file)
87
105
  if new_file.is_a?(self.class)
88
106
  # new_file.copy_to(path)
89
107
  raise NotImplementedError, 'new file is required duplicating'
90
108
  end
91
109
 
92
- if new_file.respond_to? :content_type
93
- @content_type ||= new_file.content_type
94
- else
95
- # guess content-type from extension
96
- @content_type ||= MIME::Types.type_for(new_file.path).first.content_type
97
- end
110
+ @content_type ||= if new_file.respond_to? :content_type
111
+ new_file.content_type
112
+ else
113
+ # guess content-type from extension
114
+ MIME::Types.type_for(new_file.path).first.content_type
115
+ end
98
116
 
99
117
  original_filename = new_file.try(:original_filename) || new_file.try(:filename) || new_file.try(:path)
100
- if original_filename.present?
101
- original_filename = ::File.basename(original_filename)
102
- end
118
+ original_filename = ::File.basename(original_filename) if original_filename.present?
103
119
 
104
120
  content = if new_file.respond_to?(:to_io)
105
121
  new_file.to_io.tap(&:rewind)
106
122
  elsif new_file.respond_to?(:read) && new_file.respond_to?(:rewind)
107
- new_file.read.tap do
108
- new_file.rewind
109
- end
123
+ # Pass the IO object itself, not the read result
124
+ new_file.rewind
125
+ new_file
110
126
  else
111
127
  new_file
112
128
  end
@@ -125,9 +141,11 @@ module Resizing
125
141
 
126
142
  true
127
143
  end
144
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
145
+ # rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
128
146
 
129
- def name(options = {})
130
- @public_id = PublicId.new(model.send :read_attribute, serialization_column)
147
+ def name(_options = {})
148
+ @public_id = PublicId.new(model.send(:read_attribute, serialization_column))
131
149
  CGI.unescape(@public_id.filename)
132
150
  end
133
151
 
@@ -138,6 +156,7 @@ module Resizing
138
156
  def retrieve(identifier)
139
157
  @public_id = Resizing::PublicId.new(identifier)
140
158
  end
159
+
141
160
  private
142
161
 
143
162
  attr_reader :uploader
@@ -195,7 +214,6 @@ module Resizing
195
214
  parameters.count == 2 && parameters[1].include?(:options)
196
215
  end
197
216
 
198
-
199
217
  # def retrieve_from_cache!(identifier)
200
218
  # raise NotImplementedError,
201
219
  # "Need to implement #retrieve_from_cache! if you want to use #{self.class.name} as a cache storage."
@@ -211,6 +229,7 @@ module Resizing
211
229
  # "Need to implement #clean_cache! if you want to use #{self.class.name} as a cache storage."
212
230
  # end
213
231
  end
232
+ # rubocop:enable Metrics/ClassLength
214
233
  end
215
234
  end
216
235
  end
@@ -18,9 +18,13 @@ module Resizing
18
18
  f
19
19
  end
20
20
 
21
- # def retrieve!(identifier)
22
- # super
23
- # end
21
+ def retrieve!(identifier)
22
+ return nil if identifier.blank?
23
+
24
+ f = Resizing::CarrierWave::Storage::File.new(uploader, identifier)
25
+ f.retrieve(identifier)
26
+ f
27
+ end
24
28
 
25
29
  def cache!(new_file)
26
30
  f = Resizing::CarrierWave::Storage::File.new(uploader)
@@ -4,6 +4,7 @@ require 'resizing/carrier_wave/storage/file'
4
4
  require 'resizing/carrier_wave/storage/remote'
5
5
 
6
6
  module Resizing
7
+ # rubocop:disable Metrics/ModuleLength
7
8
  module CarrierWave
8
9
  class Railtie < ::Rails::Railtie
9
10
  # Railtie skelton codes
@@ -32,11 +33,12 @@ module Resizing
32
33
  end
33
34
 
34
35
  def file
35
- return if identifier.nil?
36
- return @file unless defined? @file
36
+ file_identifier = identifier || read_column
37
+
38
+ return nil if file_identifier.blank?
37
39
 
38
40
  @file ||= Resizing::CarrierWave::Storage::File.new(self)
39
- @file.retrieve(identifier)
41
+ @file.retrieve(file_identifier)
40
42
  @file
41
43
  end
42
44
 
@@ -45,7 +47,8 @@ module Resizing
45
47
 
46
48
  transforms = args.map do |version|
47
49
  version = version.intern
48
- raise "No version is found: #{version}, #{versions.keys} are exists." unless versions.has_key? version
50
+ raise "No version is found: #{version}, #{versions.keys} are exists." unless versions.key? version
51
+
49
52
  versions[version].transform_string
50
53
  end.compact
51
54
 
@@ -108,11 +111,6 @@ module Resizing
108
111
  read_column
109
112
  end
110
113
 
111
- def store!
112
- # DO NOTHING
113
- super
114
- end
115
-
116
114
  def serialization_column
117
115
  model.send(:_mounter, mounted_as).send(:serialization_column)
118
116
  end
@@ -150,7 +148,7 @@ module Resizing
150
148
 
151
149
  private
152
150
 
153
- # rubocop:disable Metrics/AbcSize
151
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
154
152
  def transform_string_from(processor)
155
153
  action = processor.first
156
154
  value = processor.second
@@ -173,6 +171,7 @@ module Resizing
173
171
  "#{key}_#{value}"
174
172
  end.compact.join(',')
175
173
  end
176
- # rubocop:enable Metrics/AbcSize
174
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
177
175
  end
176
+ # rubocop:enable Metrics/ModuleLength
178
177
  end
@@ -24,6 +24,7 @@ module Resizing
24
24
  # }
25
25
  #
26
26
  #++
27
+ # rubocop:disable Metrics/ClassLength
27
28
  class Client
28
29
  include Resizing::Constants
29
30
  include Resizing::Configurable
@@ -37,13 +38,14 @@ module Resizing
37
38
  raise NotImplementedError
38
39
  end
39
40
 
40
- def post(file_or_binary, options = {})
41
+ def post(filename_or_io, options = {})
41
42
  ensure_content_type(options)
42
- filename = gather_filename file_or_binary, options
43
+ ensure_filename_or_io(filename_or_io)
44
+ filename = gather_filename filename_or_io, options
43
45
 
44
46
  url = build_post_url
45
47
  params = {
46
- image: Faraday::Multipart::FilePart.new(file_or_binary, options[:content_type], filename)
48
+ image: Faraday::Multipart::FilePart.new(filename_or_io, options[:content_type], filename)
47
49
  }
48
50
 
49
51
  response = handle_faraday_error do
@@ -52,17 +54,17 @@ module Resizing
52
54
  end
53
55
  end
54
56
 
55
- result = handle_create_response(response)
56
- result
57
+ handle_create_response(response)
57
58
  end
58
59
 
59
- def put(image_id, file_or_binary, options)
60
+ def put(image_id, filename_or_io, options)
60
61
  ensure_content_type(options)
61
- filename = gather_filename file_or_binary, options
62
+ ensure_filename_or_io(filename_or_io)
63
+ filename = gather_filename filename_or_io, options
62
64
 
63
65
  url = build_put_url(image_id)
64
66
  params = {
65
- image: Faraday::Multipart::FilePart.new(file_or_binary, options[:content_type], filename)
67
+ image: Faraday::Multipart::FilePart.new(filename_or_io, options[:content_type], filename)
66
68
  }
67
69
 
68
70
  response = handle_faraday_error do
@@ -71,8 +73,7 @@ module Resizing
71
73
  end
72
74
  end
73
75
 
74
- result = handle_create_response(response)
75
- result
76
+ handle_create_response(response)
76
77
  end
77
78
 
78
79
  def delete(image_id)
@@ -84,8 +85,7 @@ module Resizing
84
85
  end
85
86
  end
86
87
 
87
- result = handle_delete_response(response)
88
- result
88
+ handle_delete_response(response)
89
89
  end
90
90
 
91
91
  def metadata(image_id, options = {})
@@ -97,8 +97,7 @@ module Resizing
97
97
  end
98
98
  end
99
99
 
100
- result = handle_metadata_response(response, options)
101
- result
100
+ handle_metadata_response(response, options)
102
101
  end
103
102
 
104
103
  private
@@ -111,9 +110,8 @@ module Resizing
111
110
  "#{config.image_host}/projects/#{config.project_id}/upload/images/"
112
111
  end
113
112
 
114
- def gather_filename file_or_binary, options
115
- filename = options[:filename]
116
- filename ||= file_or_binary.respond_to?(:path) ? File.basename(file_or_binary.path) : nil
113
+ def gather_filename(filename_or_io, options)
114
+ options[:filename] || (filename_or_io.respond_to?(:path) ? File.basename(filename_or_io.path) : nil)
117
115
  end
118
116
 
119
117
  def build_put_url(image_id)
@@ -132,8 +130,20 @@ module Resizing
132
130
  raise ArgumentError, "need options[:content_type] for #{options.inspect}" unless options[:content_type]
133
131
  end
134
132
 
133
+ def ensure_filename_or_io(filename_or_io)
134
+ return if filename_or_io.is_a?(File)
135
+
136
+ # Accept IO-like objects (StringIO, Tempfile, etc.)
137
+ return if filename_or_io.respond_to?(:read) && filename_or_io.respond_to?(:rewind)
138
+
139
+ return if filename_or_io.is_a?(String) && File.exist?(filename_or_io)
140
+
141
+ raise ArgumentError,
142
+ "filename_or_io must be a File object, an IO-like object, or a path to a file (#{filename_or_io.class})"
143
+ end
144
+
135
145
  def handle_create_response(response)
136
- raise APIError, "No response is returned" if response.nil?
146
+ raise APIError, 'No response is returned' if response.nil?
137
147
 
138
148
  case response.status
139
149
  when HTTP_STATUS_OK, HTTP_STATUS_CREATED
@@ -144,7 +154,7 @@ module Resizing
144
154
  end
145
155
 
146
156
  def handle_delete_response(response)
147
- raise APIError, "No response is returned" if response.nil?
157
+ raise APIError, 'No response is returned' if response.nil?
148
158
 
149
159
  case response.status
150
160
  when HTTP_STATUS_OK, HTTP_STATUS_NOT_FOUND
@@ -157,24 +167,30 @@ module Resizing
157
167
  def handle_metadata_response(response, options = {})
158
168
  when_not_found = options[:when_not_found] || nil
159
169
 
160
- raise APIError, "No response is returned" if response.nil?
170
+ raise APIError, 'No response is returned' if response.nil?
161
171
 
162
172
  case response.status
163
- when HTTP_STATUS_OK, HTTP_STATUS_NOT_FOUND
173
+ when HTTP_STATUS_OK
164
174
  JSON.parse(response.body)
165
175
  when HTTP_STATUS_NOT_FOUND
166
176
  raise decode_error_from(response) if when_not_found == :raise
167
- nil
177
+
178
+ JSON.parse(response.body)
168
179
  else
169
180
  raise decode_error_from(response)
170
181
  end
171
182
  end
172
183
 
173
- def decode_error_from response
174
- result = JSON.parse(response.body) rescue {}
184
+ def decode_error_from(response)
185
+ result = begin
186
+ JSON.parse(response.body)
187
+ rescue StandardError
188
+ {}
189
+ end
175
190
  err = APIError.new(result['message'] || "invalid http status code #{response.status}")
176
191
  err.decoded_body = result
177
192
  err
178
193
  end
179
194
  end
195
+ # rubocop:enable Metrics/ClassLength
180
196
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Resizing
4
4
  module Configurable
5
- def self.included mod
5
+ def self.included(mod)
6
6
  mod.send(:attr_reader, :config)
7
7
  end
8
8
 
@@ -27,12 +27,8 @@ module Resizing
27
27
  def initialize(*attrs)
28
28
  case attr = attrs.first
29
29
  when Hash
30
- if attr[:project_id].nil? || attr[:secret_token].nil?
31
- raise_configiration_error
32
- end
33
- if attr[:host].present?
34
- raise_configiration_error
35
- end
30
+ raise_configiration_error if attr[:project_id].nil? || attr[:secret_token].nil?
31
+ raise_configiration_error if attr[:host].present?
36
32
 
37
33
  initialize_by_hash attr
38
34
  return
@@ -41,11 +37,6 @@ module Resizing
41
37
  raise_configiration_error
42
38
  end
43
39
 
44
- def host
45
- Kernel.warn "[DEPRECATED] The Configuration#host is deprecated. Use Configuration#image_host."
46
- self.image_host
47
- end
48
-
49
40
  def generate_auth_header
50
41
  current_timestamp = Time.now.to_i
51
42
  data = [current_timestamp, secret_token].join('|')
@@ -102,13 +93,11 @@ module Resizing
102
93
  raise ConfigurationError, 'need hash and some keys like :image_host, video_host, :project_id, :secret_token'
103
94
  end
104
95
 
96
+ # rubocop:disable Metrics/AbcSize
105
97
  def initialize_by_hash(attr)
106
- @image_host = attr[:image_host].dup.freeze || DEFAULT_IMAGE_HOST
107
- if attr[:host].present?
108
- Kernel.warn "[DEPRECATED] The host on configration is deprecated. Use image_host, video_host" if attr[:host].present?
109
- @image_host ||= attr[:host].dup.freeze || DEFAULT_HOST # for backward compatible
110
- end
98
+ raise 'The host on configuration is deprecated. Use image_host, video_host' if attr[:host].present?
111
99
 
100
+ @image_host = attr[:image_host].dup.freeze || DEFAULT_IMAGE_HOST
112
101
  @video_host = attr[:video_host].dup.freeze || DEFAULT_VIDEO_HOST
113
102
  @project_id = attr[:project_id].dup.freeze
114
103
  @secret_token = attr[:secret_token].dup.freeze
@@ -116,5 +105,6 @@ module Resizing
116
105
  @response_timeout = attr[:response_timeout] || DEFAULT_RESPONSE_TIMEOUT
117
106
  @enable_mock = attr[:enable_mock] || false
118
107
  end
108
+ # rubocop:enable Metrics/AbcSize
119
109
  end
120
110
  end
@@ -12,14 +12,14 @@ module Resizing
12
12
  end
13
13
  end
14
14
 
15
- def handle_faraday_error &block
15
+ def handle_faraday_error
16
16
  yield
17
17
  rescue Faraday::TimeoutError => e
18
18
  handle_timeout_error e
19
19
  end
20
20
 
21
- def handle_timeout_error error
22
- raise APIError.new("TimeoutError: #{error.inspect}")
21
+ def handle_timeout_error(error)
22
+ raise APIError, "TimeoutError: #{error.inspect}"
23
23
  end
24
24
  end
25
25
  end