resizing 1.0.0.pre → 1.0.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 +61 -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 +35 -16
- data/lib/resizing/carrier_wave/storage/remote.rb +7 -3
- data/lib/resizing/carrier_wave.rb +10 -11
- data/lib/resizing/client.rb +39 -41
- 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 +16 -12
- data/resizing.gemspec +6 -5
- 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 +99 -37
- data/test/resizing/client_test.rb +96 -11
- 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 +106 -8
- metadata +75 -27
- data/.circleci/config.yml +0 -73
- data/lib/resizing/video/client.rb +0 -116
- data/lib/resizing/video.rb +0 -8
- data/test/resizing/video/client_test.rb +0 -158
- data/test/vcr/video/metadata/success.yml +0 -47
- data/test/vcr/video/prepare/success.yml +0 -47
- data/test/vcr/video/upload_completed/success.yml +0 -47
- /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: 5da346f4f6420f1f586bc20af1e983e7dfa3d2c12a452a8a3493efff172b2cb6
|
|
4
|
+
data.tar.gz: 5e37eb4217eb0b71562fa49f8e4c5bcb9392b84d589bf0e88b6507a437208778
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: becfa5580edcf664eef716cb15e2e511872ef1360e81b8218e296ac14f031b05cb3bc2b70d6876247baaedc8cf03571cd8987c8149af15bd7e3e8441ca17040c
|
|
7
|
+
data.tar.gz: fb7c57ece63ce14d5fe33f8a8e0e479e68becea5edd9e23b17a4a28cbe618183bc6a4d9c442dfdbd8da5cb04e570adb8c25362c6e24ad83e22487d1ba5cacecb
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- master
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
id-token: write # This is required for codecov/codecov-action
|
|
11
|
+
contents: read # This is required for actions/checkout
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
name: Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }}
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
ruby: ['3.1']
|
|
20
|
+
rails: ['6.1', '7.0']
|
|
21
|
+
|
|
22
|
+
runs-on: ubuntu-22.04
|
|
23
|
+
|
|
24
|
+
env:
|
|
25
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- uses: mirromutth/mysql-action@v1.1
|
|
31
|
+
with:
|
|
32
|
+
host port: 3306
|
|
33
|
+
container port: 3306
|
|
34
|
+
character set server: 'utf8mb4'
|
|
35
|
+
collation server: 'utf8mb4_general_ci'
|
|
36
|
+
mysql version: '5.7'
|
|
37
|
+
mysql database: 'resizing_gem_test'
|
|
38
|
+
mysql root password: secret
|
|
39
|
+
|
|
40
|
+
- name: "Install ruby dependencies"
|
|
41
|
+
run: |
|
|
42
|
+
sudo apt update
|
|
43
|
+
sudo apt install -y libyaml-dev curl libmysqlclient-dev
|
|
44
|
+
|
|
45
|
+
- uses: ruby/setup-ruby@v1
|
|
46
|
+
with:
|
|
47
|
+
ruby-version: ${{ matrix.ruby }}
|
|
48
|
+
bundler-cache: false
|
|
49
|
+
|
|
50
|
+
- name: bundle install
|
|
51
|
+
run: |
|
|
52
|
+
bundle install
|
|
53
|
+
|
|
54
|
+
- name: Run test
|
|
55
|
+
run: |
|
|
56
|
+
bundle exec rake test
|
|
57
|
+
|
|
58
|
+
- name: Upload coverage reports to Codecov
|
|
59
|
+
uses: codecov/codecov-action@v3
|
|
60
|
+
env:
|
|
61
|
+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
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,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
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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(
|
|
130
|
-
@public_id = PublicId.new(model.send
|
|
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
|
-
|
|
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
|
|
@@ -32,11 +33,12 @@ module Resizing
|
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def file
|
|
35
|
-
|
|
36
|
-
|
|
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(
|
|
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.
|
|
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
|
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
|
|
@@ -37,16 +38,14 @@ module Resizing
|
|
|
37
38
|
raise NotImplementedError
|
|
38
39
|
end
|
|
39
40
|
|
|
40
|
-
def post(
|
|
41
|
+
def post(filename_or_io, options = {})
|
|
41
42
|
ensure_content_type(options)
|
|
43
|
+
ensure_filename_or_io(filename_or_io)
|
|
44
|
+
filename = gather_filename filename_or_io, options
|
|
42
45
|
|
|
43
46
|
url = build_post_url
|
|
44
|
-
|
|
45
|
-
filename = gather_filename file_or_binary, options
|
|
46
|
-
|
|
47
|
-
body = to_io(file_or_binary)
|
|
48
47
|
params = {
|
|
49
|
-
image: Faraday::
|
|
48
|
+
image: Faraday::Multipart::FilePart.new(filename_or_io, options[:content_type], filename)
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
response = handle_faraday_error do
|
|
@@ -55,20 +54,17 @@ module Resizing
|
|
|
55
54
|
end
|
|
56
55
|
end
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
result
|
|
57
|
+
handle_create_response(response)
|
|
60
58
|
end
|
|
61
59
|
|
|
62
|
-
def put(image_id,
|
|
60
|
+
def put(image_id, filename_or_io, options)
|
|
63
61
|
ensure_content_type(options)
|
|
62
|
+
ensure_filename_or_io(filename_or_io)
|
|
63
|
+
filename = gather_filename filename_or_io, options
|
|
64
64
|
|
|
65
65
|
url = build_put_url(image_id)
|
|
66
|
-
|
|
67
|
-
filename = gather_filename file_or_binary, options
|
|
68
|
-
|
|
69
|
-
body = to_io(file_or_binary)
|
|
70
66
|
params = {
|
|
71
|
-
image: Faraday::
|
|
67
|
+
image: Faraday::Multipart::FilePart.new(filename_or_io, options[:content_type], filename)
|
|
72
68
|
}
|
|
73
69
|
|
|
74
70
|
response = handle_faraday_error do
|
|
@@ -77,8 +73,7 @@ module Resizing
|
|
|
77
73
|
end
|
|
78
74
|
end
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
result
|
|
76
|
+
handle_create_response(response)
|
|
82
77
|
end
|
|
83
78
|
|
|
84
79
|
def delete(image_id)
|
|
@@ -90,8 +85,7 @@ module Resizing
|
|
|
90
85
|
end
|
|
91
86
|
end
|
|
92
87
|
|
|
93
|
-
|
|
94
|
-
result
|
|
88
|
+
handle_delete_response(response)
|
|
95
89
|
end
|
|
96
90
|
|
|
97
91
|
def metadata(image_id, options = {})
|
|
@@ -103,8 +97,7 @@ module Resizing
|
|
|
103
97
|
end
|
|
104
98
|
end
|
|
105
99
|
|
|
106
|
-
|
|
107
|
-
result
|
|
100
|
+
handle_metadata_response(response, options)
|
|
108
101
|
end
|
|
109
102
|
|
|
110
103
|
private
|
|
@@ -117,9 +110,8 @@ module Resizing
|
|
|
117
110
|
"#{config.image_host}/projects/#{config.project_id}/upload/images/"
|
|
118
111
|
end
|
|
119
112
|
|
|
120
|
-
def gather_filename
|
|
121
|
-
|
|
122
|
-
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)
|
|
123
115
|
end
|
|
124
116
|
|
|
125
117
|
def build_put_url(image_id)
|
|
@@ -134,24 +126,24 @@ module Resizing
|
|
|
134
126
|
"#{config.image_host}/projects/#{config.project_id}/upload/images/#{image_id}/metadata"
|
|
135
127
|
end
|
|
136
128
|
|
|
129
|
+
def ensure_content_type(options)
|
|
130
|
+
raise ArgumentError, "need options[:content_type] for #{options.inspect}" unless options[:content_type]
|
|
131
|
+
end
|
|
137
132
|
|
|
138
|
-
def
|
|
139
|
-
return
|
|
133
|
+
def ensure_filename_or_io(filename_or_io)
|
|
134
|
+
return if filename_or_io.is_a?(File)
|
|
140
135
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
StringIO.new(data)
|
|
144
|
-
else
|
|
145
|
-
raise ArgumentError, "file_or_binary is required IO class or String:#{data.class}"
|
|
146
|
-
end
|
|
147
|
-
end
|
|
136
|
+
# Accept IO-like objects (StringIO, Tempfile, etc.)
|
|
137
|
+
return if filename_or_io.respond_to?(:read) && filename_or_io.respond_to?(:rewind)
|
|
148
138
|
|
|
149
|
-
|
|
150
|
-
|
|
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})"
|
|
151
143
|
end
|
|
152
144
|
|
|
153
145
|
def handle_create_response(response)
|
|
154
|
-
raise APIError,
|
|
146
|
+
raise APIError, 'No response is returned' if response.nil?
|
|
155
147
|
|
|
156
148
|
case response.status
|
|
157
149
|
when HTTP_STATUS_OK, HTTP_STATUS_CREATED
|
|
@@ -162,7 +154,7 @@ module Resizing
|
|
|
162
154
|
end
|
|
163
155
|
|
|
164
156
|
def handle_delete_response(response)
|
|
165
|
-
raise APIError,
|
|
157
|
+
raise APIError, 'No response is returned' if response.nil?
|
|
166
158
|
|
|
167
159
|
case response.status
|
|
168
160
|
when HTTP_STATUS_OK, HTTP_STATUS_NOT_FOUND
|
|
@@ -175,24 +167,30 @@ module Resizing
|
|
|
175
167
|
def handle_metadata_response(response, options = {})
|
|
176
168
|
when_not_found = options[:when_not_found] || nil
|
|
177
169
|
|
|
178
|
-
raise APIError,
|
|
170
|
+
raise APIError, 'No response is returned' if response.nil?
|
|
179
171
|
|
|
180
172
|
case response.status
|
|
181
|
-
when HTTP_STATUS_OK
|
|
173
|
+
when HTTP_STATUS_OK
|
|
182
174
|
JSON.parse(response.body)
|
|
183
175
|
when HTTP_STATUS_NOT_FOUND
|
|
184
176
|
raise decode_error_from(response) if when_not_found == :raise
|
|
185
|
-
|
|
177
|
+
|
|
178
|
+
JSON.parse(response.body)
|
|
186
179
|
else
|
|
187
180
|
raise decode_error_from(response)
|
|
188
181
|
end
|
|
189
182
|
end
|
|
190
183
|
|
|
191
|
-
def decode_error_from
|
|
192
|
-
result =
|
|
184
|
+
def decode_error_from(response)
|
|
185
|
+
result = begin
|
|
186
|
+
JSON.parse(response.body)
|
|
187
|
+
rescue StandardError
|
|
188
|
+
{}
|
|
189
|
+
end
|
|
193
190
|
err = APIError.new(result['message'] || "invalid http status code #{response.status}")
|
|
194
191
|
err.decoded_body = result
|
|
195
192
|
err
|
|
196
193
|
end
|
|
197
194
|
end
|
|
195
|
+
# rubocop:enable Metrics/ClassLength
|
|
198
196
|
end
|