resizing 1.2.0 → 1.2.2
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 +4 -4
- data/.github/workflows/test.yml +17 -2
- data/.gitignore +6 -0
- data/Gemfile +6 -2
- data/README.md +59 -32
- data/lib/resizing/active_storage/service/resizing_service.rb +6 -2
- data/lib/resizing/active_storage/service.rb +9 -0
- data/lib/resizing/active_storage.rb +7 -0
- data/lib/resizing/carrier_wave/storage/file.rb +68 -24
- data/lib/resizing/carrier_wave/storage/remote.rb +7 -3
- data/lib/resizing/carrier_wave.rb +19 -11
- data/lib/resizing/client.rb +25 -23
- data/lib/resizing/configurable.rb +1 -1
- data/lib/resizing/configuration.rb +6 -16
- data/lib/resizing/http_clientable.rb +3 -3
- data/lib/resizing/mock_client.rb +6 -5
- data/lib/resizing/public_id.rb +5 -4
- data/lib/resizing/version.rb +1 -1
- data/lib/resizing.rb +15 -12
- data/resizing.gemspec +5 -8
- data/test/resizing/active_storage_service_test.rb +98 -0
- data/test/resizing/carrier_wave/storage/file_test.rb +149 -8
- data/test/resizing/carrier_wave/storage/remote_test.rb +75 -0
- data/test/resizing/carrier_wave_test.rb +373 -32
- data/test/resizing/client_test.rb +68 -12
- data/test/resizing/configurable_test.rb +82 -0
- data/test/resizing/configuration_test.rb +118 -2
- data/test/resizing/constants_test.rb +25 -0
- data/test/resizing/error_test.rb +73 -0
- data/test/resizing/http_clientable_test.rb +84 -0
- data/test/resizing/mock_client_test.rb +75 -0
- data/test/resizing/public_id_test.rb +1 -1
- data/test/resizing_module_test.rb +206 -0
- data/test/test_helper.rb +148 -9
- data/test/vcr/carrier_wave_test/update_image.yml +63 -0
- metadata +29 -36
- /data/{exe → bin}/console +0 -0
- /data/{exe → bin}/generate-changelog +0 -0
- /data/{exe → bin}/setup +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97be4b8cf7324441cfa73563ea4f102ac47b947fc95adb9ccbad206fe802f785
|
|
4
|
+
data.tar.gz: ae8df42cb9197bdfc81874d83027e266ba523e3e0c90605ddafc93b310da4368
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56a57d325523e21d22a6e3c77c3907e6ec8860433e6524d8ee89da79381f29f56bb7b79af37805ab4be46c921b4e70c5cceb99039de947231c50f7838c4fa544
|
|
7
|
+
data.tar.gz: 18c995f91897d11813477ea16298c2e3101c352f611ecf84e23fb57954e86b6d2c44d28a48515f3df42548b27b0bbebb2b413af85797ce246e9ef22e52d71639
|
data/.github/workflows/test.yml
CHANGED
|
@@ -7,18 +7,33 @@ on:
|
|
|
7
7
|
- master
|
|
8
8
|
|
|
9
9
|
permissions:
|
|
10
|
-
id-token: write # This is required for
|
|
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: ['
|
|
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/.gitignore
CHANGED
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
|
-
|
|
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
|
-
|
|
3
|
+
[](https://rubygems.org/gems/resizing)
|
|
4
|
+
[](https://github.com/jksy/resizing-gem/actions/workflows/test.yml)
|
|
5
|
+
[](https://codecov.io/gh/jksy/resizing-gem)
|
|
4
6
|
|
|
5
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
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
|
|
58
|
+
# rubocop:enable Metrics/ParameterLists
|
|
55
59
|
end
|
|
56
60
|
end
|
|
57
61
|
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,23 +29,42 @@ module Resizing
|
|
|
28
29
|
@content_type || file.try(:content_type)
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
# rubocop:disable Metrics/AbcSize
|
|
31
33
|
def delete
|
|
32
|
-
|
|
33
|
-
|
|
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
|
+
|
|
47
|
+
return if @public_id.empty?
|
|
34
48
|
|
|
35
49
|
resp = client.delete(@public_id.image_id)
|
|
50
|
+
|
|
51
|
+
# NOTE: 削除時のカラムクリアは以下の理由で必要:
|
|
52
|
+
# - 画像更新時: 古い画像IDと新しい画像IDが異なるため、古い画像削除時に新しいIDを消さないようにする
|
|
53
|
+
# - 明示的なremove!時: カラムをnilにする必要がある
|
|
54
|
+
# - clear_column_if_current_imageは削除される画像IDと現在のカラム値を比較して判断
|
|
36
55
|
if resp['error'] == 'ActiveRecord::RecordNotFound' # 404 not found
|
|
37
|
-
|
|
56
|
+
clear_column_if_current_image
|
|
38
57
|
return
|
|
39
58
|
end
|
|
40
59
|
|
|
41
60
|
if @public_id.image_id == resp['id']
|
|
42
|
-
|
|
61
|
+
clear_column_if_current_image
|
|
43
62
|
return
|
|
44
63
|
end
|
|
45
64
|
|
|
46
65
|
raise APIError, "raise someone error:#{resp.inspect}"
|
|
47
66
|
end
|
|
67
|
+
# rubocop:enable Metrics/AbcSize
|
|
48
68
|
|
|
49
69
|
def extension
|
|
50
70
|
raise NotImplementedError, 'this method is do not used. maybe'
|
|
@@ -79,34 +99,38 @@ module Resizing
|
|
|
79
99
|
end
|
|
80
100
|
|
|
81
101
|
def current_path
|
|
102
|
+
# Return the path from @public_id if set (for retrieve scenarios),
|
|
103
|
+
# otherwise fall back to reading from model
|
|
104
|
+
return @public_id.to_s if @public_id.present?
|
|
105
|
+
|
|
82
106
|
@current_path = model.send :read_attribute, serialization_column
|
|
83
107
|
end
|
|
84
108
|
alias path current_path
|
|
85
109
|
|
|
110
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
111
|
+
# rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
86
112
|
def store(new_file)
|
|
87
113
|
if new_file.is_a?(self.class)
|
|
88
114
|
# new_file.copy_to(path)
|
|
89
115
|
raise NotImplementedError, 'new file is required duplicating'
|
|
90
116
|
end
|
|
91
117
|
|
|
92
|
-
if new_file.respond_to? :content_type
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
118
|
+
@content_type ||= if new_file.respond_to? :content_type
|
|
119
|
+
new_file.content_type
|
|
120
|
+
else
|
|
121
|
+
# guess content-type from extension
|
|
122
|
+
MIME::Types.type_for(new_file.path).first.content_type
|
|
123
|
+
end
|
|
98
124
|
|
|
99
125
|
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
|
|
126
|
+
original_filename = ::File.basename(original_filename) if original_filename.present?
|
|
103
127
|
|
|
104
128
|
content = if new_file.respond_to?(:to_io)
|
|
105
129
|
new_file.to_io.tap(&:rewind)
|
|
106
130
|
elsif new_file.respond_to?(:read) && new_file.respond_to?(:rewind)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
131
|
+
# Pass the IO object itself, not the read result
|
|
132
|
+
new_file.rewind
|
|
133
|
+
new_file
|
|
110
134
|
else
|
|
111
135
|
new_file
|
|
112
136
|
end
|
|
@@ -115,19 +139,24 @@ module Resizing
|
|
|
115
139
|
@public_id = Resizing::PublicId.new(@response['public_id'])
|
|
116
140
|
@content_type = @response['content_type']
|
|
117
141
|
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
|
|
142
|
+
# NOTE: 理想的にはStorage::File内でモデルのカラムをいじらず、CarrierWaveに任せるべきだが、
|
|
143
|
+
# 現在の実装では以下の理由で必要:
|
|
144
|
+
# - CarrierWaveは write_uploader(column, mounter.identifiers.first) でカラムを更新
|
|
145
|
+
# - mounter.identifiers -> uploaders.map(&:identifier) -> storage.identifier -> uploader.filename
|
|
146
|
+
# - resizing-gemの filenameメソッドは read_column を返す(既存のカラム値)
|
|
147
|
+
# - そのため、CarrierWaveに任せると旧い値が書き戻されてしまう
|
|
148
|
+
# TODO: これを修正するには、Remote#identifierをオーバーライドして@public_id.to_sを返すか、
|
|
149
|
+
# uploader.filenameの実装を変更する必要がある
|
|
123
150
|
# save new value to model class
|
|
124
151
|
model.send :write_attribute, serialization_column, @public_id.to_s
|
|
125
152
|
|
|
126
153
|
true
|
|
127
154
|
end
|
|
155
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
156
|
+
# rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
128
157
|
|
|
129
|
-
def name(
|
|
130
|
-
@public_id = PublicId.new(model.send
|
|
158
|
+
def name(_options = {})
|
|
159
|
+
@public_id = PublicId.new(model.send(:read_attribute, serialization_column))
|
|
131
160
|
CGI.unescape(@public_id.filename)
|
|
132
161
|
end
|
|
133
162
|
|
|
@@ -138,6 +167,7 @@ module Resizing
|
|
|
138
167
|
def retrieve(identifier)
|
|
139
168
|
@public_id = Resizing::PublicId.new(identifier)
|
|
140
169
|
end
|
|
170
|
+
|
|
141
171
|
private
|
|
142
172
|
|
|
143
173
|
attr_reader :uploader
|
|
@@ -158,6 +188,20 @@ module Resizing
|
|
|
158
188
|
@serialization_column ||= model.send(:_mounter, uploader.mounted_as).send(:serialization_column)
|
|
159
189
|
end
|
|
160
190
|
|
|
191
|
+
# Only clear the column if the deleted image is the current one
|
|
192
|
+
# (not when deleting an old image during update)
|
|
193
|
+
def clear_column_if_current_image
|
|
194
|
+
return if model.destroyed?
|
|
195
|
+
|
|
196
|
+
current_value = model.send(:read_attribute, serialization_column)
|
|
197
|
+
current_public_id = Resizing::PublicId.new(current_value)
|
|
198
|
+
|
|
199
|
+
# Only clear if the deleted image is the same as the current one
|
|
200
|
+
return unless current_public_id.image_id == @public_id.image_id
|
|
201
|
+
|
|
202
|
+
model.send :write_attribute, serialization_column, nil
|
|
203
|
+
end
|
|
204
|
+
|
|
161
205
|
##
|
|
162
206
|
# client of Resizing
|
|
163
207
|
def client
|
|
@@ -195,7 +239,6 @@ module Resizing
|
|
|
195
239
|
parameters.count == 2 && parameters[1].include?(:options)
|
|
196
240
|
end
|
|
197
241
|
|
|
198
|
-
|
|
199
242
|
# def retrieve_from_cache!(identifier)
|
|
200
243
|
# raise NotImplementedError,
|
|
201
244
|
# "Need to implement #retrieve_from_cache! if you want to use #{self.class.name} as a cache storage."
|
|
@@ -211,6 +254,7 @@ module Resizing
|
|
|
211
254
|
# "Need to implement #clean_cache! if you want to use #{self.class.name} as a cache storage."
|
|
212
255
|
# end
|
|
213
256
|
end
|
|
257
|
+
# rubocop:enable Metrics/ClassLength
|
|
214
258
|
end
|
|
215
259
|
end
|
|
216
260
|
end
|
|
@@ -18,9 +18,13 @@ module Resizing
|
|
|
18
18
|
f
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
@@ -28,15 +29,25 @@ module Resizing
|
|
|
28
29
|
def initialize(*args)
|
|
29
30
|
@requested_format = nil
|
|
30
31
|
@default_format = nil
|
|
32
|
+
@retrieved_identifier = nil
|
|
31
33
|
super
|
|
32
34
|
end
|
|
33
35
|
|
|
36
|
+
# Override to store the identifier and set up @file for later use
|
|
37
|
+
def retrieve_from_store!(identifier)
|
|
38
|
+
@retrieved_identifier = identifier
|
|
39
|
+
super
|
|
40
|
+
# Ensure @file is set up so that remove! can call @file.delete
|
|
41
|
+
file
|
|
42
|
+
end
|
|
43
|
+
|
|
34
44
|
def file
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
file_identifier = @retrieved_identifier || identifier || read_column
|
|
46
|
+
|
|
47
|
+
return nil if file_identifier.blank?
|
|
37
48
|
|
|
38
49
|
@file ||= Resizing::CarrierWave::Storage::File.new(self)
|
|
39
|
-
@file.retrieve(
|
|
50
|
+
@file.retrieve(file_identifier)
|
|
40
51
|
@file
|
|
41
52
|
end
|
|
42
53
|
|
|
@@ -45,7 +56,8 @@ module Resizing
|
|
|
45
56
|
|
|
46
57
|
transforms = args.map do |version|
|
|
47
58
|
version = version.intern
|
|
48
|
-
raise "No version is found: #{version}, #{versions.keys} are exists." unless versions.
|
|
59
|
+
raise "No version is found: #{version}, #{versions.keys} are exists." unless versions.key? version
|
|
60
|
+
|
|
49
61
|
versions[version].transform_string
|
|
50
62
|
end.compact
|
|
51
63
|
|
|
@@ -108,11 +120,6 @@ module Resizing
|
|
|
108
120
|
read_column
|
|
109
121
|
end
|
|
110
122
|
|
|
111
|
-
def store!
|
|
112
|
-
# DO NOTHING
|
|
113
|
-
super
|
|
114
|
-
end
|
|
115
|
-
|
|
116
123
|
def serialization_column
|
|
117
124
|
model.send(:_mounter, mounted_as).send(:serialization_column)
|
|
118
125
|
end
|
|
@@ -150,7 +157,7 @@ module Resizing
|
|
|
150
157
|
|
|
151
158
|
private
|
|
152
159
|
|
|
153
|
-
# rubocop:disable Metrics/AbcSize
|
|
160
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
154
161
|
def transform_string_from(processor)
|
|
155
162
|
action = processor.first
|
|
156
163
|
value = processor.second
|
|
@@ -173,6 +180,7 @@ module Resizing
|
|
|
173
180
|
"#{key}_#{value}"
|
|
174
181
|
end.compact.join(',')
|
|
175
182
|
end
|
|
176
|
-
# rubocop:enable Metrics/AbcSize
|
|
183
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
177
184
|
end
|
|
185
|
+
# rubocop:enable Metrics/ModuleLength
|
|
178
186
|
end
|
data/lib/resizing/client.rb
CHANGED
|
@@ -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
|
|
@@ -53,8 +54,7 @@ module Resizing
|
|
|
53
54
|
end
|
|
54
55
|
end
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
result
|
|
57
|
+
handle_create_response(response)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def put(image_id, filename_or_io, options)
|
|
@@ -73,8 +73,7 @@ module Resizing
|
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
result
|
|
76
|
+
handle_create_response(response)
|
|
78
77
|
end
|
|
79
78
|
|
|
80
79
|
def delete(image_id)
|
|
@@ -86,8 +85,7 @@ module Resizing
|
|
|
86
85
|
end
|
|
87
86
|
end
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
result
|
|
88
|
+
handle_delete_response(response)
|
|
91
89
|
end
|
|
92
90
|
|
|
93
91
|
def metadata(image_id, options = {})
|
|
@@ -99,8 +97,7 @@ module Resizing
|
|
|
99
97
|
end
|
|
100
98
|
end
|
|
101
99
|
|
|
102
|
-
|
|
103
|
-
result
|
|
100
|
+
handle_metadata_response(response, options)
|
|
104
101
|
end
|
|
105
102
|
|
|
106
103
|
private
|
|
@@ -114,8 +111,7 @@ module Resizing
|
|
|
114
111
|
end
|
|
115
112
|
|
|
116
113
|
def gather_filename(filename_or_io, options)
|
|
117
|
-
|
|
118
|
-
filename ||= filename_or_io.respond_to?(:path) ? File.basename(filename_or_io.path) : nil
|
|
114
|
+
options[:filename] || (filename_or_io.respond_to?(:path) ? File.basename(filename_or_io.path) : nil)
|
|
119
115
|
end
|
|
120
116
|
|
|
121
117
|
def build_put_url(image_id)
|
|
@@ -137,17 +133,17 @@ module Resizing
|
|
|
137
133
|
def ensure_filename_or_io(filename_or_io)
|
|
138
134
|
return if filename_or_io.is_a?(File)
|
|
139
135
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return
|
|
143
|
-
end
|
|
144
|
-
end
|
|
136
|
+
# Accept IO-like objects (StringIO, Tempfile, etc.)
|
|
137
|
+
return if filename_or_io.respond_to?(:read) && filename_or_io.respond_to?(:rewind)
|
|
145
138
|
|
|
146
|
-
|
|
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})"
|
|
147
143
|
end
|
|
148
144
|
|
|
149
145
|
def handle_create_response(response)
|
|
150
|
-
raise APIError,
|
|
146
|
+
raise APIError, 'No response is returned' if response.nil?
|
|
151
147
|
|
|
152
148
|
case response.status
|
|
153
149
|
when HTTP_STATUS_OK, HTTP_STATUS_CREATED
|
|
@@ -158,7 +154,7 @@ module Resizing
|
|
|
158
154
|
end
|
|
159
155
|
|
|
160
156
|
def handle_delete_response(response)
|
|
161
|
-
raise APIError,
|
|
157
|
+
raise APIError, 'No response is returned' if response.nil?
|
|
162
158
|
|
|
163
159
|
case response.status
|
|
164
160
|
when HTTP_STATUS_OK, HTTP_STATUS_NOT_FOUND
|
|
@@ -171,24 +167,30 @@ module Resizing
|
|
|
171
167
|
def handle_metadata_response(response, options = {})
|
|
172
168
|
when_not_found = options[:when_not_found] || nil
|
|
173
169
|
|
|
174
|
-
raise APIError,
|
|
170
|
+
raise APIError, 'No response is returned' if response.nil?
|
|
175
171
|
|
|
176
172
|
case response.status
|
|
177
|
-
when HTTP_STATUS_OK
|
|
173
|
+
when HTTP_STATUS_OK
|
|
178
174
|
JSON.parse(response.body)
|
|
179
175
|
when HTTP_STATUS_NOT_FOUND
|
|
180
176
|
raise decode_error_from(response) if when_not_found == :raise
|
|
181
|
-
|
|
177
|
+
|
|
178
|
+
JSON.parse(response.body)
|
|
182
179
|
else
|
|
183
180
|
raise decode_error_from(response)
|
|
184
181
|
end
|
|
185
182
|
end
|
|
186
183
|
|
|
187
|
-
def decode_error_from
|
|
188
|
-
result =
|
|
184
|
+
def decode_error_from(response)
|
|
185
|
+
result = begin
|
|
186
|
+
JSON.parse(response.body)
|
|
187
|
+
rescue StandardError
|
|
188
|
+
{}
|
|
189
|
+
end
|
|
189
190
|
err = APIError.new(result['message'] || "invalid http status code #{response.status}")
|
|
190
191
|
err.decoded_body = result
|
|
191
192
|
err
|
|
192
193
|
end
|
|
193
194
|
end
|
|
195
|
+
# rubocop:enable Metrics/ClassLength
|
|
194
196
|
end
|