imgproxy 0.0.2 → 0.0.3
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/README.md +86 -1
- data/lib/imgproxy/builder.rb +17 -15
- data/lib/imgproxy/config.rb +20 -3
- data/lib/imgproxy/extensions/active_storage.rb +17 -0
- data/lib/imgproxy/extensions/shrine.rb +17 -0
- data/lib/imgproxy/options.rb +37 -55
- data/lib/imgproxy/url_adapters/active_storage.rb +22 -0
- data/lib/imgproxy/url_adapters/active_storage_gcs.rb +31 -0
- data/lib/imgproxy/url_adapters/active_storage_s3.rb +23 -0
- data/lib/imgproxy/url_adapters/shrine.rb +20 -0
- data/lib/imgproxy/url_adapters/shrine_s3.rb +20 -0
- data/lib/imgproxy/url_adapters.rb +58 -0
- data/lib/imgproxy/version.rb +1 -1
- data/lib/imgproxy.rb +41 -4
- metadata +150 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d8d21bfc06b321d89874525a7177c4c9e31e1bcca9823c19b6e121e727d6fb3
|
4
|
+
data.tar.gz: aa451c75c7a5df5ab49e7d9b52cb8c9deeb46c858b576eb3cb6526b51c61145e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a627220618a4797014aa867e483d9e57000d37c4576a14d5691de52ed63d0d4b66bccfad51b471da6eb987578e6beaf285717ba3bf74edcbc15ec238718f4825
|
7
|
+
data.tar.gz: 25d2aa9d5075a57b37109c2cfade3b48e72f9d63774adf90964e7e099f4ef8ca2f0fb327da77bdaa2018358fae51e65fc55b6b6ba63f053af14c81ca493dfd1e
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# imgproxy.rb
|
2
2
|
|
3
|
-
[](https://rubygems.org/gems/imgproxy) [](https://www.rubydoc.info/gems/imgproxy/)
|
3
|
+
[](https://circleci.com/gh/imgproxy/imgproxy.rb) [](https://rubygems.org/gems/imgproxy) [](https://www.rubydoc.info/gems/imgproxy/)
|
4
4
|
|
5
5
|
Gem for [imgproxy](https://github.com/DarthSim/imgproxy) URLs generation.
|
6
6
|
|
@@ -92,6 +92,91 @@ Available options are:
|
|
92
92
|
|
93
93
|
_See [imgproxy URL format guide](https://github.com/DarthSim/imgproxy/blob/master/docs/generating_the_url_advanced.md) for more info_
|
94
94
|
|
95
|
+
### Using with ActiveStorage
|
96
|
+
|
97
|
+
If you use [ActiveStorage](https://guides.rubyonrails.org/active_storage_overview.html), you can configure imgproxy gem to work with ActiveStorage attachments:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
Imgproxy.extend_active_storage
|
101
|
+
|
102
|
+
# Now you can use ActiveStorage attachment as a source URL
|
103
|
+
Imgproxy.url_for(user.avatar, width: 250, height: 250)
|
104
|
+
# or you can use #imgproxy_url method of an attachment
|
105
|
+
user.avatar.imgproxy_url(width: 250, height: 250)
|
106
|
+
```
|
107
|
+
|
108
|
+
If you configured both your imgproxy server and ActiveStorage for working with Amazon S3, you may want to use short and beautiful `s3://...` source URLs instead of long ones generated by Rails:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
Imgproxy.extend_active_storage(use_s3: true)
|
112
|
+
```
|
113
|
+
|
114
|
+
You can do the same for Google Cloud Storage:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
# ActiveStorage hides GCS config in private, so we have to provide GCS bucket name
|
118
|
+
Imgproxy.extend_active_storage(use_gcs: true, gcs_bucket: "my_bucket")
|
119
|
+
```
|
120
|
+
|
121
|
+
### Using with Shrine
|
122
|
+
|
123
|
+
If you use [Shrine](https://shrinerb.com/), you can configure imgproxy gem to work with `Shrine::UploadedFile`:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
Imgproxy.extend_shrine
|
127
|
+
|
128
|
+
# Now you can use Shrine::UploadedFile as a source URL
|
129
|
+
Imgproxy.url_for(user.avatar, width: 250, height: 250)
|
130
|
+
# or you can use #imgproxy_url method of an Shrine::UploadedFile
|
131
|
+
user.avatar.imgproxy_url(width: 250, height: 250)
|
132
|
+
```
|
133
|
+
|
134
|
+
**Note:** If you use `Shrine::Storage::FileSystem` as a storage, uploaded file URLs won't include host and imgproxy server won't have access to them. To fix this, initialize `Shrine::Storage::FileSystem` with `host` option:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
Shrine.storages = {
|
138
|
+
store: Shrine::Storage::FileSystem.new("public", host: "http://your-host.test")
|
139
|
+
}
|
140
|
+
```
|
141
|
+
|
142
|
+
Or you can launch your imgproxy server with `IMGPROXY_BASE_URL` setting:
|
143
|
+
|
144
|
+
```
|
145
|
+
IMGPROXY_BASE_URL="http://your-host.test" imgproxy
|
146
|
+
```
|
147
|
+
|
148
|
+
If you configured both your imgproxy server and Shrine for working with Amazon S3, you may want to use short and beautiful `s3://...` source URLs:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
Imgproxy.extend_shrine(use_s3: true)
|
152
|
+
```
|
153
|
+
|
154
|
+
### URL adapters
|
155
|
+
|
156
|
+
By default, `Imgproxy.url_for` accepts only `String` or `URI` as source URL, but you can extend this by using URL adapters. URL adapter is a simple class that implements `applicable?` and `url` methods. See the example below:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
class MyItemAdapter
|
160
|
+
# `applicable?` checks if the adapter can extract source URL from the provided object
|
161
|
+
def applicable?(item)
|
162
|
+
item.is_a? MyItem
|
163
|
+
end
|
164
|
+
|
165
|
+
# `url` extracts source URL from the provided object
|
166
|
+
def url(item)
|
167
|
+
item.image_url
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
Imgproxy.configure do |config|
|
172
|
+
config.url_adapters.add MyItemAdapter.new
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
**Note:** `Imgproxy` will use the first applicable URL adapter. If you need to add your adapter to the beginning of the list, use `prepend` method instead of `add`.
|
177
|
+
|
178
|
+
imgproxy gem provides adapters for ActiveStorage and Shrine that are automatically added by `Imgproxy.extend_active_storage` and `Imgproxy.extend_shrine`.
|
179
|
+
|
95
180
|
## Contributing
|
96
181
|
|
97
182
|
Bug reports and pull requests are welcome on GitHub at https://github.com/imgproxy/imgproxy.rb.
|
data/lib/imgproxy/builder.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "openssl"
|
2
|
+
require "base64"
|
3
3
|
|
4
|
-
require
|
4
|
+
require "imgproxy/options"
|
5
5
|
|
6
6
|
module Imgproxy
|
7
7
|
# Builds imgproxy URL
|
@@ -28,11 +28,12 @@ module Imgproxy
|
|
28
28
|
# Genrates imgproxy URL
|
29
29
|
#
|
30
30
|
# @return [String] imgproxy URL
|
31
|
-
# @param [String] image Source image URL
|
31
|
+
# @param [String,URI, Object] image Source image URL or object applicable for
|
32
|
+
# the configured URL adapters
|
32
33
|
# @see Imgproxy.url_for
|
33
34
|
def url_for(image)
|
34
|
-
path = [*processing_options,
|
35
|
-
path = "#{path}@#{options[:format]}" if @options[:format]
|
35
|
+
path = [*processing_options, "plain", url(image)].join("/")
|
36
|
+
path = "#{path}@#{@options[:format]}" if @options[:format]
|
36
37
|
|
37
38
|
signature = sign_path(path)
|
38
39
|
|
@@ -56,14 +57,14 @@ module Imgproxy
|
|
56
57
|
sharpen: :sh,
|
57
58
|
watermark: :wm,
|
58
59
|
preset: :pr,
|
59
|
-
cachebuster: :cb
|
60
|
+
cachebuster: :cb,
|
60
61
|
}.freeze
|
61
62
|
|
62
|
-
NEED_ESCAPE_RE =
|
63
|
+
NEED_ESCAPE_RE = /[@?%]/.freeze
|
63
64
|
|
64
65
|
def processing_options
|
65
66
|
@processing_options ||=
|
66
|
-
@options.
|
67
|
+
@options.reject { |k, _| k == :format }.map do |key, value|
|
67
68
|
"#{option_alias(key)}:#{wrap_array(value).join(':')}"
|
68
69
|
end
|
69
70
|
end
|
@@ -78,20 +79,21 @@ module Imgproxy
|
|
78
79
|
value.is_a?(Array) ? value : [value]
|
79
80
|
end
|
80
81
|
|
81
|
-
def
|
82
|
-
url
|
82
|
+
def url(image)
|
83
|
+
url = config.url_adapters.url_of(image)
|
84
|
+
url.match?(NEED_ESCAPE_RE) ? CGI.escape(url) : url
|
83
85
|
end
|
84
86
|
|
85
87
|
def sign_path(path)
|
86
|
-
return
|
88
|
+
return "unsafe" if signature_key.nil? || signature_salt.nil?
|
87
89
|
|
88
90
|
digest = OpenSSL::HMAC.digest(
|
89
|
-
OpenSSL::Digest.new(
|
91
|
+
OpenSSL::Digest.new("sha256"),
|
90
92
|
signature_key,
|
91
|
-
"#{signature_salt}/#{path}"
|
93
|
+
"#{signature_salt}/#{path}",
|
92
94
|
)[0, signature_size]
|
93
95
|
|
94
|
-
Base64.urlsafe_encode64(digest).tr(
|
96
|
+
Base64.urlsafe_encode64(digest).tr("=", "")
|
95
97
|
end
|
96
98
|
|
97
99
|
def signature_key
|
data/lib/imgproxy/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "imgproxy/url_adapters"
|
2
|
+
|
1
3
|
module Imgproxy
|
2
4
|
# Imgproxy config
|
3
5
|
# @see Imgproxy.configure
|
@@ -24,18 +26,33 @@ module Imgproxy
|
|
24
26
|
#
|
25
27
|
# @param value [String] hex-encoded signature key
|
26
28
|
def hex_key=(value)
|
27
|
-
self.key = [value].pack(
|
29
|
+
self.key = [value].pack("H*")
|
28
30
|
end
|
29
31
|
|
30
32
|
# Decodes hex-encoded salt and sets it to {#salt}
|
31
33
|
#
|
32
34
|
# @param value [String] hex-encoded signature salt
|
33
35
|
def hex_salt=(value)
|
34
|
-
self.salt = [value].pack(
|
36
|
+
self.salt = [value].pack("H*")
|
35
37
|
end
|
36
38
|
|
37
39
|
def endpoint=(value)
|
38
|
-
|
40
|
+
value = value.to_s
|
41
|
+
@endpoint = value.end_with?("/") ? value[0..-2] : value
|
42
|
+
end
|
43
|
+
|
44
|
+
# URL adapters config. Allows to use this gem with ActiveStorage, Shrine, etc.
|
45
|
+
#
|
46
|
+
# Imgproxy.configure do |config|
|
47
|
+
# config.url_adapters.add Imgproxy::UrlAdapters::ActiveStorage.new
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# Imgproxy.url_for(user.avatar)
|
51
|
+
#
|
52
|
+
# @return [Imgproxy::UrlAdapters]
|
53
|
+
# @see Imgproxy::UrlAdapters
|
54
|
+
def url_adapters
|
55
|
+
@url_adapters ||= Imgproxy::UrlAdapters.new
|
39
56
|
end
|
40
57
|
end
|
41
58
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Imgproxy
|
2
|
+
module Extensions
|
3
|
+
# Extension for ActiveStorage
|
4
|
+
# @see Imgproxy.extend_active_storage
|
5
|
+
module ActiveStorage
|
6
|
+
# Returns imgproxy URL for an attachment
|
7
|
+
#
|
8
|
+
# @return [String]
|
9
|
+
# @param options [Hash, Imgproxy::Builder]
|
10
|
+
# @see Imgproxy.url_for
|
11
|
+
def imgproxy_url(options = {})
|
12
|
+
return options.url_for(self) if options.is_a?(Imgproxy::Builder)
|
13
|
+
Imgproxy.url_for(self, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Imgproxy
|
2
|
+
module Extensions
|
3
|
+
# Extension for Shrine::UploadedFile
|
4
|
+
# @see Imgproxy.extend_shrine
|
5
|
+
module Shrine
|
6
|
+
# Returns imgproxy URL for a Shrine::UploadedFile instance
|
7
|
+
#
|
8
|
+
# @return [String]
|
9
|
+
# @param options [Hash, Imgproxy::Builder]
|
10
|
+
# @see Imgproxy.url_for
|
11
|
+
def imgproxy_url(options = {})
|
12
|
+
return options.url_for(self) if options.is_a?(Imgproxy::Builder)
|
13
|
+
Imgproxy.url_for(self, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/imgproxy/options.rb
CHANGED
@@ -1,43 +1,31 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
1
|
module Imgproxy
|
4
2
|
# Formats and regroups processing options
|
5
3
|
class Options < Hash
|
6
|
-
STRING_OPTS = %i[resizing_type gravity watermark_position style cachebuster
|
7
|
-
|
8
|
-
|
9
|
-
INT_OPTS = %i[width height quality watermark_x_offset
|
10
|
-
watermark_y_offset].freeze
|
11
|
-
|
12
|
-
FLOAT_OPTS = %i[dpr gravity_x gravity_y blur sharpen watermark_opacity
|
13
|
-
watermark_scale].freeze
|
14
|
-
|
4
|
+
STRING_OPTS = %i[resizing_type gravity watermark_position style cachebuster format].freeze
|
5
|
+
INT_OPTS = %i[width height quality watermark_x_offset watermark_y_offset].freeze
|
6
|
+
FLOAT_OPTS = %i[dpr gravity_x gravity_y blur sharpen watermark_opacity watermark_scale].freeze
|
15
7
|
BOOL_OPTS = %i[enlarge extend].freeze
|
16
|
-
|
17
8
|
ARRAY_OPTS = %i[background preset].freeze
|
9
|
+
ALL_OPTS = (STRING_OPTS + INT_OPTS + FLOAT_OPTS + BOOL_OPTS + ARRAY_OPTS).freeze
|
18
10
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
OPTS_PRIORITY = { resize: 1, size: 2 }.freeze
|
11
|
+
OPTS_PRIORITY = %i[ resize size resizing_type width height dpr enlarge extend gravity quality
|
12
|
+
background blur sharpen watermark preset cachebuster ].freeze
|
23
13
|
|
24
14
|
# @param options [Hash] raw processing options
|
25
15
|
def initialize(options)
|
26
16
|
merge!(options.slice(*ALL_OPTS))
|
17
|
+
|
27
18
|
typecast
|
28
|
-
freeze
|
29
|
-
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
group_resizing_opts
|
21
|
+
group_gravity_opts
|
22
|
+
group_watermark_opts
|
34
23
|
|
35
|
-
|
36
|
-
group_gravity_opts(opts)
|
37
|
-
group_watermark_opts(opts)
|
38
|
-
encode_style(opts)
|
24
|
+
encode_style
|
39
25
|
|
40
|
-
Hash[
|
26
|
+
replace(Hash[sort_by { |k, _| OPTS_PRIORITY.index(k) || 99 }])
|
27
|
+
|
28
|
+
freeze
|
41
29
|
end
|
42
30
|
|
43
31
|
private
|
@@ -56,58 +44,52 @@ module Imgproxy
|
|
56
44
|
end
|
57
45
|
|
58
46
|
def bool(value)
|
59
|
-
value && value != 0 && value !=
|
47
|
+
value && value != 0 && value != "0" ? 1 : 0
|
60
48
|
end
|
61
49
|
|
62
50
|
def wrap_array(value)
|
63
51
|
value.is_a?(Array) ? value : [value]
|
64
52
|
end
|
65
53
|
|
66
|
-
def group_resizing_opts
|
67
|
-
return
|
54
|
+
def group_resizing_opts
|
55
|
+
return unless self[:width] && self[:height]
|
68
56
|
|
69
|
-
|
70
|
-
[
|
71
|
-
opts.delete(:enlarge), opts.delete(:extend)]
|
57
|
+
self[:size] = trim_nils(
|
58
|
+
[delete(:width), delete(:height), delete(:enlarge), delete(:extend)],
|
72
59
|
)
|
73
60
|
|
74
|
-
if
|
75
|
-
opts[:resize] = [opts.delete(:resizing_type), *opts.delete(:size)]
|
76
|
-
end
|
77
|
-
|
78
|
-
opts
|
61
|
+
self[:resize] = [delete(:resizing_type), *delete(:size)] if self[:resizing_type]
|
79
62
|
end
|
80
63
|
|
81
|
-
def group_gravity_opts
|
64
|
+
def group_gravity_opts
|
82
65
|
gravity = trim_nils(
|
83
66
|
[
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
]
|
67
|
+
delete(:gravity),
|
68
|
+
delete(:gravity_x),
|
69
|
+
delete(:gravity_y),
|
70
|
+
],
|
88
71
|
)
|
89
72
|
|
90
|
-
|
73
|
+
self[:gravity] = gravity unless gravity[0].nil?
|
91
74
|
end
|
92
75
|
|
93
|
-
def group_watermark_opts
|
76
|
+
def group_watermark_opts
|
94
77
|
watermark = trim_nils(
|
95
78
|
[
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
]
|
79
|
+
delete(:watermark_opacity),
|
80
|
+
delete(:watermark_position),
|
81
|
+
delete(:watermark_x_offset),
|
82
|
+
delete(:watermark_y_offset),
|
83
|
+
delete(:watermark_scale),
|
84
|
+
],
|
102
85
|
)
|
103
86
|
|
104
|
-
|
87
|
+
self[:watermark] = watermark unless watermark[0].nil?
|
105
88
|
end
|
106
89
|
|
107
|
-
def encode_style
|
108
|
-
return if
|
109
|
-
|
110
|
-
opts[:style] = Base64.urlsafe_encode64(opts[:style]).tr('=', '')
|
90
|
+
def encode_style
|
91
|
+
return if self[:style].nil?
|
92
|
+
self[:style] = Base64.urlsafe_encode64(self[:style]).tr("=", "")
|
111
93
|
end
|
112
94
|
|
113
95
|
def trim_nils(value)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Imgproxy
|
2
|
+
class UrlAdapters
|
3
|
+
# Adapter for ActiveStorage
|
4
|
+
#
|
5
|
+
# Imgproxy.configure do |config|
|
6
|
+
# config.url_adapters.add Imgproxy::UrlAdapters::ActiveStorage.new
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# Imgproxy.url_for(user.avatar)
|
10
|
+
class ActiveStorage
|
11
|
+
def applicable?(image)
|
12
|
+
image.is_a?(::ActiveStorage::Attached::One) ||
|
13
|
+
image.is_a?(::ActiveStorage::Attachment) ||
|
14
|
+
image.is_a?(::ActiveStorage::Blob)
|
15
|
+
end
|
16
|
+
|
17
|
+
def url(image)
|
18
|
+
Rails.application.routes.url_helpers.url_for(image)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "imgproxy/url_adapters/active_storage"
|
2
|
+
|
3
|
+
module Imgproxy
|
4
|
+
class UrlAdapters
|
5
|
+
# Adapter for ActiveStorage with S3 service
|
6
|
+
#
|
7
|
+
# Imgproxy.configure do |config|
|
8
|
+
# config.url_adapters.add Imgproxy::UrlAdapters::ActiveStorageGCS.new("bucket_name")
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# Imgproxy.url_for(user.avatar)
|
12
|
+
class ActiveStorageGCS < Imgproxy::UrlAdapters::ActiveStorage
|
13
|
+
# @param [String] bucket_name Google Cloud Storage bucket name
|
14
|
+
def initialize(bucket_name)
|
15
|
+
@bucket_name = bucket_name
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String] Google Cloud Storage bucket name
|
19
|
+
attr_reader :bucket_name
|
20
|
+
|
21
|
+
def applicable?(image)
|
22
|
+
super &&
|
23
|
+
::ActiveStorage::Blob.service.is_a?(::ActiveStorage::Service::GCSService)
|
24
|
+
end
|
25
|
+
|
26
|
+
def url(image)
|
27
|
+
"gs://#{bucket_name}/#{image.key}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "imgproxy/url_adapters/active_storage"
|
2
|
+
|
3
|
+
module Imgproxy
|
4
|
+
class UrlAdapters
|
5
|
+
# Adapter for ActiveStorage with S3 service
|
6
|
+
#
|
7
|
+
# Imgproxy.configure do |config|
|
8
|
+
# config.url_adapters.add Imgproxy::UrlAdapters::ActiveStorageS3.new
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# Imgproxy.url_for(user.avatar)
|
12
|
+
class ActiveStorageS3 < Imgproxy::UrlAdapters::ActiveStorage
|
13
|
+
def applicable?(image)
|
14
|
+
super &&
|
15
|
+
::ActiveStorage::Blob.service.is_a?(::ActiveStorage::Service::S3Service)
|
16
|
+
end
|
17
|
+
|
18
|
+
def url(image)
|
19
|
+
"s3://#{image.service.bucket.name}/#{image.key}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Imgproxy
|
2
|
+
class UrlAdapters
|
3
|
+
# Adapter for Shrine
|
4
|
+
#
|
5
|
+
# Imgproxy.configure do |config|
|
6
|
+
# config.url_adapters.add Imgproxy::UrlAdapters::Shrine.new
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# Imgproxy.url_for(user.avatar)
|
10
|
+
class Shrine
|
11
|
+
def applicable?(image)
|
12
|
+
image.is_a?(::Shrine::UploadedFile)
|
13
|
+
end
|
14
|
+
|
15
|
+
def url(image)
|
16
|
+
image.url
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Imgproxy
|
2
|
+
class UrlAdapters
|
3
|
+
# Adapter for Shrine with S3 storage
|
4
|
+
#
|
5
|
+
# Imgproxy.configure do |config|
|
6
|
+
# config.url_adapters.add Imgproxy::UrlAdapters::ShrineS3.new
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# Imgproxy.url_for(user.avatar)
|
10
|
+
class ShrineS3 < Imgproxy::UrlAdapters::Shrine
|
11
|
+
def applicable?(image)
|
12
|
+
super && image.storage.is_a?(::Shrine::Storage::S3)
|
13
|
+
end
|
14
|
+
|
15
|
+
def url(image)
|
16
|
+
"s3://#{image.storage.bucket.name}/#{image.id}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "imgproxy/url_adapters/active_storage"
|
2
|
+
require "imgproxy/url_adapters/active_storage_s3"
|
3
|
+
require "imgproxy/url_adapters/active_storage_gcs"
|
4
|
+
|
5
|
+
require "imgproxy/url_adapters/shrine"
|
6
|
+
require "imgproxy/url_adapters/shrine_s3"
|
7
|
+
|
8
|
+
module Imgproxy
|
9
|
+
# URL adapters config. Allows to use this gem with ActiveStorage, Shrine, etc.
|
10
|
+
#
|
11
|
+
# Imgproxy.configure do |config|
|
12
|
+
# config.url_adapters.add Imgproxy::UrlAdapters::ActiveStorage.new
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Imgproxy.url_for(user.avatar)
|
16
|
+
class UrlAdapters
|
17
|
+
class NotFound < StandardError; end
|
18
|
+
class NotConfigured < StandardError; end
|
19
|
+
|
20
|
+
# @return [Array] Currently added adapters
|
21
|
+
attr_reader :adapters
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@adapters = []
|
25
|
+
end
|
26
|
+
|
27
|
+
# Add adapter to the end of the list
|
28
|
+
# @return [Array]
|
29
|
+
def add(adapter)
|
30
|
+
adapters << adapter
|
31
|
+
end
|
32
|
+
|
33
|
+
# Add adapter to the beginning of the list
|
34
|
+
# @return [Array]
|
35
|
+
def prepend
|
36
|
+
adapters.unshift(adapter)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Remove all adapters from the list
|
40
|
+
# @return [Array]
|
41
|
+
def clear!
|
42
|
+
@adapters = []
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get URL for the provided image
|
46
|
+
# @return [String]
|
47
|
+
def url_of(image)
|
48
|
+
return image if image.is_a? String
|
49
|
+
return image.to_s if image.is_a? URI
|
50
|
+
|
51
|
+
adapter = adapters.find { |a| a.applicable?(image) }
|
52
|
+
|
53
|
+
return adapter.url(image) if adapter
|
54
|
+
|
55
|
+
raise NotFound, "Can't found URL adapter for #{image.inspect}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/imgproxy/version.rb
CHANGED
data/lib/imgproxy.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "imgproxy/version"
|
2
|
+
require "imgproxy/config"
|
3
|
+
require "imgproxy/builder"
|
4
|
+
|
5
|
+
require "imgproxy/extensions/active_storage"
|
6
|
+
require "imgproxy/extensions/shrine"
|
4
7
|
|
5
8
|
# @see Imgproxy::ClassMethods
|
6
9
|
module Imgproxy
|
@@ -39,7 +42,8 @@ module Imgproxy
|
|
39
42
|
# )
|
40
43
|
#
|
41
44
|
# @return [String] imgproxy URL
|
42
|
-
# @param [String] image Source image URL
|
45
|
+
# @param [String,URI, Object] image Source image URL or object applicable for
|
46
|
+
# the configured URL adapters
|
43
47
|
# @param [Hash] options Processing options
|
44
48
|
# @option options [String] :resizing_type
|
45
49
|
# @option options [Integer] :width
|
@@ -68,5 +72,38 @@ module Imgproxy
|
|
68
72
|
def url_for(image, options = {})
|
69
73
|
Imgproxy::Builder.new(options).url_for(image)
|
70
74
|
end
|
75
|
+
|
76
|
+
# Extends ActiveStorage::Blob with {Imgproxy::Extensions::ActiveStorage.imgproxy_url} method
|
77
|
+
# and adds URL adapters for ActiveStorage
|
78
|
+
#
|
79
|
+
# @return [void]
|
80
|
+
# @param use_s3 [Boolean] enable Amazon S3 source URLs
|
81
|
+
# @param use_gcs [Boolean] enable Google Cloud Storage source URLs
|
82
|
+
# @param gcs_bucket [String] Google Cloud Storage bucket name
|
83
|
+
def extend_active_storage(use_s3: false, use_gcs: false, gcs_bucket: nil)
|
84
|
+
ActiveSupport.on_load(:active_storage_blob) do
|
85
|
+
::ActiveStorage::Blob.include Imgproxy::Extensions::ActiveStorage
|
86
|
+
|
87
|
+
url_adapters = Imgproxy.config.url_adapters
|
88
|
+
|
89
|
+
url_adapters.add(Imgproxy::UrlAdapters::ActiveStorageS3.new) if use_s3
|
90
|
+
url_adapters.add(Imgproxy::UrlAdapters::ActiveStorageGCS.new(gcs_bucket)) if use_gcs
|
91
|
+
url_adapters.add(Imgproxy::UrlAdapters::ActiveStorage.new)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Extends Shrine::UploadedFile with {Imgproxy::Extensions::Shrine.imgproxy_url} method
|
96
|
+
# and adds URL adapters for Shrine
|
97
|
+
#
|
98
|
+
# @return [void]
|
99
|
+
# @param use_s3 [Boolean] enable Amazon S3 source URLs
|
100
|
+
def extend_shrine(use_s3: false)
|
101
|
+
::Shrine::UploadedFile.include Imgproxy::Extensions::Shrine
|
102
|
+
|
103
|
+
url_adapters = Imgproxy.config.url_adapters
|
104
|
+
|
105
|
+
url_adapters.add(Imgproxy::UrlAdapters::ShrineS3.new) if use_s3
|
106
|
+
url_adapters.add(Imgproxy::UrlAdapters::Shrine.new)
|
107
|
+
end
|
71
108
|
end
|
72
109
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imgproxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Alexandrovich
|
@@ -9,7 +9,147 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2019-03-25 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry-byebug
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.8.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.8.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec_junit_formatter
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.66.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.66.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.32.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.32.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: aws-sdk-s3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.35.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.35.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: google-cloud-storage
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.11'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.11'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rails
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '5.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '5.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: shrine
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.16'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.16'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sqlite3
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 1.3.6
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 1.3.6
|
13
153
|
description: A gem that easily generates imgproxy URLs for your images
|
14
154
|
email: darthsim@gmail.com
|
15
155
|
executables: []
|
@@ -21,7 +161,15 @@ files:
|
|
21
161
|
- lib/imgproxy.rb
|
22
162
|
- lib/imgproxy/builder.rb
|
23
163
|
- lib/imgproxy/config.rb
|
164
|
+
- lib/imgproxy/extensions/active_storage.rb
|
165
|
+
- lib/imgproxy/extensions/shrine.rb
|
24
166
|
- lib/imgproxy/options.rb
|
167
|
+
- lib/imgproxy/url_adapters.rb
|
168
|
+
- lib/imgproxy/url_adapters/active_storage.rb
|
169
|
+
- lib/imgproxy/url_adapters/active_storage_gcs.rb
|
170
|
+
- lib/imgproxy/url_adapters/active_storage_s3.rb
|
171
|
+
- lib/imgproxy/url_adapters/shrine.rb
|
172
|
+
- lib/imgproxy/url_adapters/shrine_s3.rb
|
25
173
|
- lib/imgproxy/version.rb
|
26
174
|
homepage: https://github.com/imgproxy/imgproxy.rb
|
27
175
|
licenses:
|