imgproxy 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +8 -0
- data/CHANGELOG.md +74 -0
- data/README.md +176 -135
- data/UPGRADE.md +136 -0
- data/docs/info_options.md +223 -0
- data/docs/processing_options.md +724 -0
- data/docs/yard/fix_pictures.rb +25 -0
- data/docs/yard/github_alerts.rb +16 -0
- data/docs/yard/relative_markdown_links.rb +31 -0
- data/lib/imgproxy/config.rb +96 -41
- data/lib/imgproxy/extensions/active_storage.rb +6 -4
- data/lib/imgproxy/extensions/shrine.rb +6 -4
- data/lib/imgproxy/option_aliases/info.rb +33 -0
- data/lib/imgproxy/option_aliases/processing.rb +74 -0
- data/lib/imgproxy/options_builders/base.rb +54 -0
- data/lib/imgproxy/options_builders/info.rb +52 -0
- data/lib/imgproxy/options_builders/processing.rb +150 -0
- data/lib/imgproxy/options_casters/adjust.rb +3 -1
- data/lib/imgproxy/options_casters/alpha.rb +27 -0
- data/lib/imgproxy/options_casters/array.rb +3 -1
- data/lib/imgproxy/options_casters/autoquality.rb +28 -0
- data/lib/imgproxy/options_casters/average.rb +27 -0
- data/lib/imgproxy/options_casters/background.rb +27 -0
- data/lib/imgproxy/options_casters/base64.rb +2 -0
- data/lib/imgproxy/options_casters/blur_detections.rb +28 -0
- data/lib/imgproxy/options_casters/blurhash.rb +21 -0
- data/lib/imgproxy/options_casters/bool.rb +3 -1
- data/lib/imgproxy/options_casters/crop.rb +3 -1
- data/lib/imgproxy/options_casters/dominant_colors.rb +27 -0
- data/lib/imgproxy/options_casters/draw_detections.rb +28 -0
- data/lib/imgproxy/options_casters/extend.rb +3 -1
- data/lib/imgproxy/options_casters/filename.rb +31 -0
- data/lib/imgproxy/options_casters/float.rb +3 -1
- data/lib/imgproxy/options_casters/format_quality.rb +19 -0
- data/lib/imgproxy/options_casters/gradient.rb +31 -0
- data/lib/imgproxy/options_casters/gravity.rb +20 -6
- data/lib/imgproxy/options_casters/group.rb +2 -0
- data/lib/imgproxy/options_casters/hashsum.rb +24 -0
- data/lib/imgproxy/options_casters/integer.rb +2 -0
- data/lib/imgproxy/options_casters/jpeg_options.rb +3 -1
- data/lib/imgproxy/options_casters/padding.rb +41 -0
- data/lib/imgproxy/options_casters/png_options.rb +3 -1
- data/lib/imgproxy/options_casters/resize.rb +3 -1
- data/lib/imgproxy/options_casters/size.rb +3 -1
- data/lib/imgproxy/options_casters/string.rb +2 -0
- data/lib/imgproxy/options_casters/trim.rb +3 -1
- data/lib/imgproxy/options_casters/unsharp_masking.rb +25 -0
- data/lib/imgproxy/options_casters/video_thumbnail_tile.rb +34 -0
- data/lib/imgproxy/options_casters/watermark.rb +5 -4
- data/lib/imgproxy/options_casters/watermark_size.rb +21 -0
- data/lib/imgproxy/options_casters/{gif_options.rb → webp_options.rb} +6 -5
- data/lib/imgproxy/options_casters/zoom.rb +27 -0
- data/lib/imgproxy/service_config.rb +111 -0
- data/lib/imgproxy/trim_array.rb +2 -0
- data/lib/imgproxy/url_adapters/active_storage.rb +2 -0
- data/lib/imgproxy/url_adapters/shrine.rb +8 -2
- data/lib/imgproxy/url_adapters.rb +3 -0
- data/lib/imgproxy/url_builders/base.rb +184 -0
- data/lib/imgproxy/url_builders/info.rb +44 -0
- data/lib/imgproxy/url_builders/processing.rb +59 -0
- data/lib/imgproxy/version.rb +3 -1
- data/lib/imgproxy.rb +19 -57
- data/logo/logo-dark.svg +22 -0
- data/logo/logo-light.svg +31 -0
- metadata +70 -32
- data/lib/imgproxy/builder.rb +0 -140
- data/lib/imgproxy/options.rb +0 -119
- data/lib/imgproxy/options_aliases.rb +0 -45
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "imgproxy/options_casters/integer"
|
4
|
+
require "imgproxy/options_casters/bool"
|
5
|
+
require "imgproxy/options_casters/extend"
|
6
|
+
|
7
|
+
module Imgproxy
|
8
|
+
module OptionsCasters
|
9
|
+
# Casts `watermark_size` processing option
|
10
|
+
module WatermarkSize
|
11
|
+
def self.cast(raw)
|
12
|
+
return raw unless raw.is_a?(Hash)
|
13
|
+
|
14
|
+
[
|
15
|
+
Imgproxy::OptionsCasters::Integer.cast(raw[:width]) || 0,
|
16
|
+
Imgproxy::OptionsCasters::Integer.cast(raw[:height]) || 0,
|
17
|
+
]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "imgproxy/options_casters/group"
|
2
|
-
require "imgproxy/options_casters/
|
4
|
+
require "imgproxy/options_casters/string"
|
3
5
|
|
4
6
|
module Imgproxy
|
5
7
|
module OptionsCasters
|
6
|
-
# Casts
|
7
|
-
module
|
8
|
+
# Casts `webp_options` processing option
|
9
|
+
module WebpOptions
|
8
10
|
CASTER = Imgproxy::OptionsCasters::Group.new(
|
9
|
-
|
10
|
-
optimize_transparency: Imgproxy::OptionsCasters::Bool,
|
11
|
+
compression: Imgproxy::OptionsCasters::String,
|
11
12
|
).freeze
|
12
13
|
|
13
14
|
def self.cast(raw)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "imgproxy/trim_array"
|
4
|
+
require "imgproxy/options_casters/float"
|
5
|
+
|
6
|
+
module Imgproxy
|
7
|
+
module OptionsCasters
|
8
|
+
# Casts `zoom` info option
|
9
|
+
module Zoom
|
10
|
+
using TrimArray
|
11
|
+
|
12
|
+
def self.cast(raw)
|
13
|
+
# Allow zoom to be just a float
|
14
|
+
return Imgproxy::OptionsCasters::Float.cast(raw) if raw.is_a?(Numeric)
|
15
|
+
|
16
|
+
return raw unless raw.is_a?(Hash)
|
17
|
+
|
18
|
+
return Imgproxy::OptionsCasters::Float.cast(raw[:zoom_x_y]) if raw.key?(:zoom_x_y)
|
19
|
+
|
20
|
+
[
|
21
|
+
Imgproxy::OptionsCasters::Float.cast(raw[:zoom_x]) || 1,
|
22
|
+
Imgproxy::OptionsCasters::Float.cast(raw[:zoom_y]) || 1,
|
23
|
+
].trim!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "anyway_config"
|
4
|
+
|
5
|
+
module Imgproxy
|
6
|
+
# Imgproxy custom config for services
|
7
|
+
#
|
8
|
+
# @!attribute endpoint
|
9
|
+
# imgproxy endpoint
|
10
|
+
# @return [String]
|
11
|
+
# @!attribute key
|
12
|
+
# imgproxy hex-encoded signature key
|
13
|
+
# @return [String]
|
14
|
+
# @!attribute salt
|
15
|
+
# imgproxy hex-encoded signature salt
|
16
|
+
# @return [String]
|
17
|
+
# @!attribute raw_key
|
18
|
+
# Decoded signature key
|
19
|
+
# @return [String]
|
20
|
+
# @!attribute raw_salt
|
21
|
+
# Decoded signature salt
|
22
|
+
# @return [String]
|
23
|
+
# @!attribute signature_size
|
24
|
+
# imgproxy signature size. Defaults to 32
|
25
|
+
# @return [String]
|
26
|
+
# @!attribute source_url_encryption_key
|
27
|
+
# imgproxy hex-encoded source URL encryption key
|
28
|
+
# @return [String]
|
29
|
+
# @!attribute raw_source_url_encryption_key
|
30
|
+
# Decoded source URL encryption key
|
31
|
+
# @return [String]
|
32
|
+
# @!attribute always_encrypt_source_urls
|
33
|
+
# Always encrypt source URLs. Defaults to false
|
34
|
+
# @return [String]
|
35
|
+
#
|
36
|
+
# @see Imgproxy::Config
|
37
|
+
class ServiceConfig < Anyway::Config
|
38
|
+
# Inherit global config values
|
39
|
+
config_name :imgproxy
|
40
|
+
|
41
|
+
attr_config(
|
42
|
+
:endpoint,
|
43
|
+
:key,
|
44
|
+
:salt,
|
45
|
+
:raw_key,
|
46
|
+
:raw_salt,
|
47
|
+
:source_url_encryption_key,
|
48
|
+
:raw_source_url_encryption_key,
|
49
|
+
signature_size: 32,
|
50
|
+
always_encrypt_source_urls: false,
|
51
|
+
)
|
52
|
+
|
53
|
+
coerce_types(
|
54
|
+
endpoint: :string,
|
55
|
+
key: :string,
|
56
|
+
salt: :string,
|
57
|
+
raw_key: :string,
|
58
|
+
raw_salt: :string,
|
59
|
+
signature_size: :integer,
|
60
|
+
source_url_encryption_key: :string,
|
61
|
+
raw_source_url_encryption_key: :string,
|
62
|
+
always_encrypt_source_urls: :boolean,
|
63
|
+
)
|
64
|
+
|
65
|
+
alias_method :set_key, :key=
|
66
|
+
alias_method :set_raw_key, :raw_key=
|
67
|
+
alias_method :set_salt, :salt=
|
68
|
+
alias_method :set_raw_salt, :raw_salt=
|
69
|
+
alias_method :set_source_url_encryption_key, :source_url_encryption_key=
|
70
|
+
alias_method :set_raw_source_url_encryption_key, :raw_source_url_encryption_key=
|
71
|
+
|
72
|
+
private :set_key, :set_raw_key, :set_salt, :set_raw_salt,
|
73
|
+
:set_source_url_encryption_key, :set_raw_source_url_encryption_key
|
74
|
+
|
75
|
+
def key=(value)
|
76
|
+
value = value&.to_s
|
77
|
+
super(value)
|
78
|
+
set_raw_key(value && [value].pack("H*"))
|
79
|
+
end
|
80
|
+
|
81
|
+
def raw_key=(value)
|
82
|
+
value = value&.to_s
|
83
|
+
super(value)
|
84
|
+
set_key(value&.unpack!("H*"))
|
85
|
+
end
|
86
|
+
|
87
|
+
def salt=(value)
|
88
|
+
value = value&.to_s
|
89
|
+
super(value)
|
90
|
+
set_raw_salt(value && [value].pack("H*"))
|
91
|
+
end
|
92
|
+
|
93
|
+
def raw_salt=(value)
|
94
|
+
value = value&.to_s
|
95
|
+
super(value)
|
96
|
+
set_salt(value&.unpack1("H*"))
|
97
|
+
end
|
98
|
+
|
99
|
+
def source_url_encryption_key=(value)
|
100
|
+
value = value&.to_s
|
101
|
+
super(value)
|
102
|
+
set_raw_source_url_encryption_key(value && [value].pack("H*"))
|
103
|
+
end
|
104
|
+
|
105
|
+
def raw_source_url_encryption_key=(value)
|
106
|
+
value = value&.to_s
|
107
|
+
super(value)
|
108
|
+
set_source_url_encryption_key(value&.unpack1("H*"))
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/imgproxy/trim_array.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Imgproxy
|
2
4
|
class UrlAdapters
|
3
5
|
# Adapter for Shrine
|
@@ -16,7 +18,7 @@ module Imgproxy
|
|
16
18
|
return s3_url(image) if use_s3_url(image)
|
17
19
|
|
18
20
|
opts = {}
|
19
|
-
opts[:host] =
|
21
|
+
opts[:host] = config.shrine_host if config.shrine_host
|
20
22
|
image.url(**opts)
|
21
23
|
end
|
22
24
|
|
@@ -28,9 +30,13 @@ module Imgproxy
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def use_s3_url(image)
|
31
|
-
|
33
|
+
config.use_s3_urls &&
|
32
34
|
image.storage.is_a?(::Shrine::Storage::S3)
|
33
35
|
end
|
36
|
+
|
37
|
+
def config
|
38
|
+
Imgproxy.config
|
39
|
+
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "imgproxy/url_adapters/active_storage"
|
2
4
|
require "imgproxy/url_adapters/shrine"
|
3
5
|
|
@@ -11,6 +13,7 @@ module Imgproxy
|
|
11
13
|
# Imgproxy.url_for(user.avatar)
|
12
14
|
class UrlAdapters
|
13
15
|
class NotFound < StandardError; end
|
16
|
+
|
14
17
|
class NotConfigured < StandardError; end
|
15
18
|
|
16
19
|
# @return [Array] Currently added adapters
|
@@ -0,0 +1,184 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openssl"
|
4
|
+
require "base64"
|
5
|
+
require "erb"
|
6
|
+
|
7
|
+
require "imgproxy/options_builders/base"
|
8
|
+
|
9
|
+
module Imgproxy
|
10
|
+
module UrlBuilders
|
11
|
+
class UnknownServiceError < StandardError; end
|
12
|
+
|
13
|
+
class InvalidEncryptionKeyError < StandardError; end
|
14
|
+
|
15
|
+
# Builds imgproxy URL
|
16
|
+
#
|
17
|
+
# builder = Imgproxy::UrlBuilders::Base.new(
|
18
|
+
# width: 500,
|
19
|
+
# height: 400,
|
20
|
+
# resizing_type: :fill,
|
21
|
+
# sharpen: 0.5
|
22
|
+
# )
|
23
|
+
#
|
24
|
+
# builder.url_for("http://images.example.com/images/image1.jpg")
|
25
|
+
# builder.url_for("http://images.example.com/images/image2.jpg")
|
26
|
+
class Base
|
27
|
+
OPTIONS_BUILDER = OptionsBuilders::Base
|
28
|
+
OPTION_ALIASES = {}.freeze
|
29
|
+
|
30
|
+
# @param [Hash] options imgproxy URL options
|
31
|
+
# @see Imgproxy.url_for
|
32
|
+
# @see Imgproxy.info_url_for
|
33
|
+
def initialize(options = {})
|
34
|
+
options = options.dup
|
35
|
+
|
36
|
+
extract_builder_options(options)
|
37
|
+
|
38
|
+
@options = self.class::OPTIONS_BUILDER.new(options)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Genrates imgproxy URL
|
42
|
+
#
|
43
|
+
# @return [String] imgproxy URL
|
44
|
+
# @param [String,URI, Object] _image Source image URL or object applicable for
|
45
|
+
# the configured URL adapters
|
46
|
+
# @see Imgproxy.url_for
|
47
|
+
# @see Imgproxy.info_url_for
|
48
|
+
def url_for(_image)
|
49
|
+
raise NotImplementedError
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_reader :service
|
55
|
+
|
56
|
+
NEED_ESCAPE_RE = /[@?% ]|[^\p{Ascii}]/.freeze
|
57
|
+
AES_SIZES = {32 => 256, 24 => 196, 16 => 128}.freeze
|
58
|
+
|
59
|
+
def extract_builder_options(options)
|
60
|
+
@service = options.delete(:service)&.to_sym || :default
|
61
|
+
|
62
|
+
@use_short_options =
|
63
|
+
not_nil_or(options.delete(:use_short_options), config.use_short_options)
|
64
|
+
@base64_encode_url =
|
65
|
+
not_nil_or(options.delete(:base64_encode_url), config.base64_encode_urls)
|
66
|
+
@escape_plain_url =
|
67
|
+
not_nil_or(options.delete(:escape_plain_url), config.always_escape_plain_urls)
|
68
|
+
@encrypt_source_url =
|
69
|
+
not_nil_or(options.delete(:encrypt_source_url), service_config.always_encrypt_source_urls)
|
70
|
+
@source_url_encryption_iv = options.delete(:source_url_encryption_iv)
|
71
|
+
end
|
72
|
+
|
73
|
+
def option_strings
|
74
|
+
@option_strings ||= @options.map do |key, value|
|
75
|
+
[option_alias(key), value].join(":")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def sourcce_url(image, ext: nil)
|
80
|
+
url = config.url_adapters.url_of(image)
|
81
|
+
|
82
|
+
return encrypted_sourcce_url_for(url, ext: ext) if @encrypt_source_url
|
83
|
+
return base64_sourcce_url_for(url, ext: ext) if @base64_encode_url
|
84
|
+
plain_url_for(url, ext: ext)
|
85
|
+
end
|
86
|
+
|
87
|
+
def plain_url_for(url, ext: nil)
|
88
|
+
escaped_url = need_escape_url?(url) ? ERB::Util.url_encode(url) : url
|
89
|
+
|
90
|
+
ext ? "plain/#{escaped_url}@#{ext}" : "plain/#{escaped_url}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def base64_sourcce_url_for(url, ext: nil)
|
94
|
+
encoded_url = Base64.urlsafe_encode64(url).tr("=", "").scan(/.{1,16}/).join("/")
|
95
|
+
|
96
|
+
ext ? "#{encoded_url}.#{ext}" : encoded_url
|
97
|
+
end
|
98
|
+
|
99
|
+
def encrypted_sourcce_url_for(url, ext: nil)
|
100
|
+
cipher = build_cipher
|
101
|
+
|
102
|
+
iv = @source_url_encryption_iv || cipher.random_iv
|
103
|
+
cipher.iv = iv
|
104
|
+
|
105
|
+
"enc/#{base64_sourcce_url_for(iv + cipher.update(url) + cipher.final, ext: ext)}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def need_escape_url?(url)
|
109
|
+
@escape_plain_url || url.match?(NEED_ESCAPE_RE)
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_cipher
|
113
|
+
key = encryption_key.to_s
|
114
|
+
|
115
|
+
aes_size = AES_SIZES.fetch(key.length) do
|
116
|
+
raise Imgproxy::UrlBuilders::InvalidEncryptionKeyError,
|
117
|
+
"Encryption key should be 16/24/32 bytes long, now - #{key.length}"
|
118
|
+
end
|
119
|
+
|
120
|
+
OpenSSL::Cipher::AES.new(aes_size, :CBC).tap do |cipher|
|
121
|
+
cipher.encrypt
|
122
|
+
cipher.key = key
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def option_alias(name)
|
127
|
+
return name unless @use_short_options
|
128
|
+
|
129
|
+
self.class::OPTION_ALIASES.fetch(name, name)
|
130
|
+
end
|
131
|
+
|
132
|
+
def sign_path(path)
|
133
|
+
return "unsafe" unless ready_to_sign?
|
134
|
+
|
135
|
+
digest = OpenSSL::HMAC.digest(
|
136
|
+
OpenSSL::Digest.new("sha256"),
|
137
|
+
signature_key,
|
138
|
+
"#{signature_salt}/#{path}",
|
139
|
+
)[0, signature_size]
|
140
|
+
|
141
|
+
Base64.urlsafe_encode64(digest).tr("=", "")
|
142
|
+
end
|
143
|
+
|
144
|
+
def ready_to_sign?
|
145
|
+
!(signature_key.nil? || signature_salt.nil? ||
|
146
|
+
signature_key.empty? || signature_salt.empty?)
|
147
|
+
end
|
148
|
+
|
149
|
+
def signature_key
|
150
|
+
service_config.raw_key
|
151
|
+
end
|
152
|
+
|
153
|
+
def signature_salt
|
154
|
+
service_config.raw_salt
|
155
|
+
end
|
156
|
+
|
157
|
+
def signature_size
|
158
|
+
service_config.signature_size
|
159
|
+
end
|
160
|
+
|
161
|
+
def encryption_key
|
162
|
+
service_config.raw_source_url_encryption_key
|
163
|
+
end
|
164
|
+
|
165
|
+
def not_nil_or(value, fallback)
|
166
|
+
value.nil? ? fallback : value
|
167
|
+
end
|
168
|
+
|
169
|
+
def endpoint
|
170
|
+
service_config.endpoint
|
171
|
+
end
|
172
|
+
|
173
|
+
def service_config
|
174
|
+
@service_config ||= config.services[service].tap do |c|
|
175
|
+
raise Imgproxy::UrlBuilders::UnknownServiceError, service unless c
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def config
|
180
|
+
Imgproxy.config
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "imgproxy/option_aliases/info"
|
4
|
+
require "imgproxy/options_builders/info"
|
5
|
+
require "imgproxy/url_builders/base"
|
6
|
+
|
7
|
+
module Imgproxy
|
8
|
+
module UrlBuilders
|
9
|
+
# Builds imgproxy info URL
|
10
|
+
#
|
11
|
+
# builder = Imgproxy::UrlBuilders::Info.new(
|
12
|
+
# width: 500,
|
13
|
+
# height: 400,
|
14
|
+
# resizing_type: :fill,
|
15
|
+
# sharpen: 0.5
|
16
|
+
# )
|
17
|
+
#
|
18
|
+
# builder.url_for("http://images.example.com/images/image1.jpg")
|
19
|
+
# builder.url_for("http://images.example.com/images/image2.jpg")
|
20
|
+
class Info < Base
|
21
|
+
OPTIONS_BUILDER = OptionsBuilders::Info
|
22
|
+
OPTION_ALIASES = Imgproxy::OptionAliases::INFO
|
23
|
+
|
24
|
+
# @param [Hash] options Info options
|
25
|
+
# @see Imgproxy.info_url_for
|
26
|
+
def initialize(options = {})
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
# Genrates imgproxy info URL
|
31
|
+
#
|
32
|
+
# @return [String] imgproxy info URL
|
33
|
+
# @param [String,URI, Object] image Source image URL or object applicable for
|
34
|
+
# the configured URL adapters
|
35
|
+
# @see Imgproxy.info_url_for
|
36
|
+
def url_for(image)
|
37
|
+
path = [*option_strings, sourcce_url(image)].join("/")
|
38
|
+
signature = sign_path(path)
|
39
|
+
|
40
|
+
File.join(endpoint.to_s, "info", signature, path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "imgproxy/option_aliases/processing"
|
4
|
+
require "imgproxy/options_builders/processing"
|
5
|
+
require "imgproxy/url_builders/base"
|
6
|
+
|
7
|
+
module Imgproxy
|
8
|
+
module UrlBuilders
|
9
|
+
# Builds imgproxy URL
|
10
|
+
#
|
11
|
+
# builder = Imgproxy::UrlBuilders::Processing.new(
|
12
|
+
# width: 500,
|
13
|
+
# height: 400,
|
14
|
+
# resizing_type: :fill,
|
15
|
+
# sharpen: 0.5
|
16
|
+
# )
|
17
|
+
#
|
18
|
+
# builder.url_for("http://images.example.com/images/image1.jpg")
|
19
|
+
# builder.url_for("http://images.example.com/images/image2.jpg")
|
20
|
+
class Processing < Base
|
21
|
+
OPTIONS_BUILDER = OptionsBuilders::Processing
|
22
|
+
OPTION_ALIASES = Imgproxy::OptionAliases::PROCESSING
|
23
|
+
|
24
|
+
# @param [Hash] options Processing options
|
25
|
+
# @see Imgproxy.url_for
|
26
|
+
def initialize(options = {})
|
27
|
+
super(options)
|
28
|
+
|
29
|
+
@format = @options.delete(:format)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Genrates imgproxy URL
|
33
|
+
#
|
34
|
+
# @return [String] imgproxy URL
|
35
|
+
# @param [String,URI, Object] image Source image URL or object applicable for
|
36
|
+
# the configured URL adapters
|
37
|
+
# @see Imgproxy.url_for
|
38
|
+
def url_for(image)
|
39
|
+
path = [*option_strings, sourcce_url(image, ext: @format)].join("/")
|
40
|
+
signature = sign_path(path)
|
41
|
+
|
42
|
+
File.join(endpoint.to_s, signature, path)
|
43
|
+
end
|
44
|
+
|
45
|
+
# # Genrates imgproxy info URL
|
46
|
+
# #
|
47
|
+
# # @return [String] imgproxy info URL
|
48
|
+
# # @param [String,URI, Object] image Source image URL or object applicable for
|
49
|
+
# # the configured URL adapters
|
50
|
+
# # @see Imgproxy.info_url_for
|
51
|
+
# def info_url_for(image)
|
52
|
+
# path = url(image)
|
53
|
+
# signature = sign_path(path)
|
54
|
+
|
55
|
+
# File.join(endpoint.to_s, "info", signature, path)
|
56
|
+
# end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/imgproxy/version.rb
CHANGED
data/lib/imgproxy.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "imgproxy/version"
|
2
4
|
require "imgproxy/config"
|
3
|
-
require "imgproxy/
|
5
|
+
require "imgproxy/url_builders/processing"
|
6
|
+
require "imgproxy/url_builders/info"
|
4
7
|
|
5
8
|
require "imgproxy/extensions/active_storage"
|
6
9
|
require "imgproxy/extensions/shrine"
|
@@ -58,71 +61,30 @@ module Imgproxy
|
|
58
61
|
# @return [String] imgproxy URL
|
59
62
|
# @param [String,URI, Object] image Source image URL or object applicable for
|
60
63
|
# the configured URL adapters
|
61
|
-
# @param [Hash] options Processing options
|
62
|
-
#
|
63
|
-
# @option options [Hash|Array|String] :size
|
64
|
-
# @option options [String] :resizing_type
|
65
|
-
# @option options [String] :resizing_algorithm supported only by imgproxy pro
|
66
|
-
# @option options [Integer] :width
|
67
|
-
# @option options [Integer] :height
|
68
|
-
# @option options [Float] :dpr
|
69
|
-
# @option options [Boolean] :enlarge
|
70
|
-
# @option options [Hash|Array|Boolean|String] :extend
|
71
|
-
# @option options [Hash|Array|String] :gravity
|
72
|
-
# @option options [Hash|Array|String] :crop
|
73
|
-
# @option options [Array] :padding
|
74
|
-
# @option options [Hash|Array|String] :trim
|
75
|
-
# @option options [Integer] :rotate
|
76
|
-
# @option options [Integer] :quality
|
77
|
-
# @option options [Integer] :max_bytes
|
78
|
-
# @option options [Array|String] :background
|
79
|
-
# @option options [Float] :background_alpha supported only by imgproxy pro
|
80
|
-
# @option options [Hash|Array|String] :adjust
|
81
|
-
# @option options [Integer] :brightness supported only by imgproxy pro
|
82
|
-
# @option options [Float] :contrast supported only by imgproxy pro
|
83
|
-
# @option options [Float] :saturation supported only by imgproxy pro
|
84
|
-
# @option options [Float] :blur
|
85
|
-
# @option options [Float] :sharpen
|
86
|
-
# @option options [Integer] :pixelate supported only by imgproxy pro
|
87
|
-
# @option options [String] :unsharpening supported only by imgproxy pro
|
88
|
-
# @option options [Hash|Array|Float|String] :watermark
|
89
|
-
# @option options [String] :watermark_url supported only by imgproxy pro
|
90
|
-
# @option options [String] :style supported only by imgproxy pro
|
91
|
-
# @option options [Hash|Array|String] :jpeg_options supported only by imgproxy pro
|
92
|
-
# @option options [Hash|Array|String] :png_options supported only by imgproxy pro
|
93
|
-
# @option options [Hash|Array|String] :gif_options supported only by imgproxy pro
|
94
|
-
# @option options [Integer] :page supported only by imgproxy pro
|
95
|
-
# @option options [Integer] :video_thumbnail_second supported only by imgproxy pro
|
96
|
-
# @option options [Array] :preset
|
97
|
-
# @option options [String] :cachebuster
|
98
|
-
# @option options [Boolean] :strip_metadata
|
99
|
-
# @option options [Boolean] :strip_color_profile
|
100
|
-
# @option options [Boolean] :auto_rotate
|
101
|
-
# @option options [String] :filename
|
102
|
-
# @option options [String] :format
|
103
|
-
# @option options [Boolean] :return_attachment
|
104
|
-
# @option options [Integer] :expires
|
105
|
-
# @option options [Boolean] :use_short_options
|
106
|
-
# @option options [Boolean] :base64_encode_urls
|
107
|
-
# @option options [Boolean] :escape_plain_url
|
108
|
-
# @see https://docs.imgproxy.net/#/generating_the_url_advanced?id=processing-options
|
109
|
-
# Available imgproxy URL processing options and their arguments
|
64
|
+
# @param [Hash] options Processing options.
|
65
|
+
# See: {file:docs/processing_options.md Supported processing options}
|
110
66
|
def url_for(image, options = {})
|
111
|
-
Imgproxy::
|
67
|
+
Imgproxy::UrlBuilders::Processing.new(options).url_for(image)
|
112
68
|
end
|
113
69
|
|
114
|
-
# Genrates imgproxy info URL. Supported only by imgproxy
|
70
|
+
# Genrates imgproxy info URL. Supported only by imgproxy Pro
|
115
71
|
#
|
116
|
-
# Imgproxy.info_url_for(
|
72
|
+
# Imgproxy.info_url_for(
|
73
|
+
# "http://images.example.com/images/image.jpg",
|
74
|
+
# alpha: {
|
75
|
+
# alpha: true,
|
76
|
+
# check_transparency: true
|
77
|
+
# },
|
78
|
+
# palette: 128,
|
79
|
+
# )
|
117
80
|
#
|
118
81
|
# @return [String] imgproxy info URL
|
119
82
|
# @param [String,URI, Object] image Source image URL or object applicable for
|
120
83
|
# the configured URL adapters
|
121
|
-
# @param [Hash] options
|
122
|
-
#
|
123
|
-
# @option options [Boolean] :escape_plain_url
|
84
|
+
# @param [Hash] options Info options.
|
85
|
+
# See: {file:docs/info_options.md Supported info options}
|
124
86
|
def info_url_for(image, options = {})
|
125
|
-
Imgproxy::
|
87
|
+
Imgproxy::UrlBuilders::Info.new(options).url_for(image)
|
126
88
|
end
|
127
89
|
|
128
90
|
# Extends +ActiveStorage::Blob+ with {Imgproxy::Extensions::ActiveStorage.imgproxy_url} method
|
data/logo/logo-dark.svg
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="266" height="100" fill="none">
|
2
|
+
<g clip-path="url(#a)">
|
3
|
+
<path fill="#fff" d="M94.056 42.55v2.915h5.803v11.648h-5.803v2.915h14.733v-2.915h-5.69V42.549h-9.043Zm4.916-4.367c0 1.423.83 2.423 2.451 2.423 1.619 0 2.45-1 2.45-2.423 0-1.422-.831-2.422-2.45-2.422-1.62 0-2.451 1-2.451 2.422Zm14.479 4.366v17.465h3.239V48.746c0-2.507.859-3.633 2.775-3.633 1.915 0 2.774 1.14 2.774 3.633v11.268h3.24V48.746c0-2.535.859-3.633 2.775-3.633 1.915 0 2.774 1.112 2.774 3.633v11.268h3.24V47.845c0-3.465-2.099-5.76-5.24-5.76-1.648 0-3.155.732-4.014 1.915h-.591c-.86-1.225-2.155-1.916-3.747-1.916-1.648 0-2.887.578-3.563 1.634h-.409V42.55h-3.253Zm42.704 16.902V42.549h-3.24v1.578h-.887c-.831-1.226-2.676-2.043-4.662-2.043-4.662 0-7.774 3.437-7.774 8.62 0 5.099 3.126 8.507 7.774 8.507 1.916 0 3.775-.76 4.662-1.915h.887v1.859c0 2.676-1.887 4.253-5.07 4.253-2.535 0-4.422-1.042-5.07-2.788h-3.183c.183 3.436 3.478 5.704 8.253 5.704 5.155-.014 8.31-2.746 8.31-6.873Zm-13.324-8.747c0-3.465 1.944-5.591 5.127-5.591s5.127 2.126 5.127 5.591c0 3.465-1.944 5.592-5.127 5.592s-5.127-2.127-5.127-5.592Zm28.648-8.62c-2.127 0-4.071.874-4.887 2.212h-.888v-1.747h-3.239v23.296h3.239v-7.577h.888c.816 1.338 2.774 2.21 4.887 2.21 4.775 0 7.958-3.675 7.958-9.196s-3.183-9.197-7.958-9.197Zm-5.887 9.212c0-3.817 2-6.17 5.309-6.17 3.296 0 5.31 2.353 5.31 6.17 0 3.817-2 6.169-5.31 6.169-3.309 0-5.309-2.366-5.309-6.17Zm18.845-8.747v2.916h4.14v11.648h-4.14v2.915h13.746v-2.915h-6.366v-6.409c0-3.704 1.155-5.591 3.422-5.591 1.831 0 2.775 1.07 2.775 3.14v2.057h3.352v-2.521c0-3.55-1.915-5.705-5.07-5.705-1.676 0-3.071.634-3.831 1.803h-.888V42.55h-7.14Zm30.042 17.944c5.211 0 8.69-3.676 8.69-9.197 0-5.521-3.479-9.197-8.69-9.197-5.211 0-8.69 3.676-8.69 9.197 0 5.52 3.465 9.197 8.69 9.197Zm-5.451-9.197c0-3.817 2.071-6.17 5.451-6.17 3.394 0 5.451 2.353 5.451 6.17 0 3.817-2.057 6.169-5.451 6.169-3.394 0-5.451-2.366-5.451-6.17ZM227 60.028h3.718l4.127-6.056.324-.845h.296l.324.845 4.07 6.056h3.944l-5.747-8.591 6.099-8.888h-3.62l-4.62 6.705-.323.845h-.296l-.324-.845-4.423-6.705h-3.887l6.042 9.17-5.704 8.31Zm20.69-17.479 6.338 16.014h2.648l-1.056 2.972c-.535 1.31-1.057 1.86-2.028 1.86-1.057 0-1.62-.55-2.184-1.86h-2.943c.239 3.056 2.155 4.775 5.31 4.775 2.126 0 3.859-1.395 4.718-3.789l7.127-19.972h-3.296l-4.62 13.099h-1.267l-5.155-13.099h-3.592Z"/>
|
4
|
+
<mask id="b" width="94" height="79" x="0" y="22" maskUnits="userSpaceOnUse" style="mask-type:luminance">
|
5
|
+
<path fill="#fff" d="M.394 22.535h92.817v78.169H.394V22.535Z"/>
|
6
|
+
</mask>
|
7
|
+
<g mask="url(#b)">
|
8
|
+
<path fill="url(#c)" d="M78.493 32.732V22.535H68.31v2.831H44.535v-2.83H34.352v2.83H10.577v-2.83H.394v10.196h2.831v12.465H.395v10.197h2.83V67.86H.395v10.197h10.182v-2.845h23.775v2.831h10.183v-2.83H68.31v2.83h10.183V67.845h-2.831V55.38h2.83V45.183h-2.83V32.718h2.83v.014Zm-41.873-7.93h5.662v5.663H36.62v-5.662ZM2.662 30.466v-5.662h5.662v5.662H2.662Zm0 22.662v-5.662h5.662v5.662H2.662Zm5.662 22.648H2.662v-5.662h5.662v5.662Zm33.958 0H36.62v-5.662h5.662v5.662Zm26.028-5.099H44.535v-2.83H34.352v2.83H10.577v-2.83h-2.83V55.38h2.83V45.183h-2.83V32.718h2.83v-2.83h23.775v2.83h10.183v-2.83H68.31v2.83h2.83v12.465h-2.83V55.38h2.83v12.465h-2.83v2.831Zm7.93-.563v5.662h-5.663v-5.662h5.662Zm0-22.648v5.662h-5.663v-5.662h5.662Zm-5.663-17v-5.662h5.662v5.662h-5.662Z"/>
|
9
|
+
<path fill="#1960C4" d="M22.55 45.192v.864h.592a1.98 1.98 0 0 1 .8-.848 2.36 2.36 0 0 1 1.2-.304c.778 0 1.37.293 1.776.88.405.587.608 1.445.608 2.576v1.552h-2.544V48.68c0-.459-.086-.8-.256-1.024-.17-.235-.432-.352-.784-.352-.438 0-.763.197-.976.592-.203.395-.304.997-.304 1.808v3.072h2.8V55h-6.88v-2.224h1.664v-5.36h-1.872v-2.224h4.176ZM35.545 55v-9.808h2.496V55h-2.496Zm-3.44-4.192c0 .715.144 1.253.432 1.616.288.363.715.544 1.28.544.576 0 1.008-.181 1.296-.544.288-.363.432-.901.432-1.616h.368v3.312h-.96a2.293 2.293 0 0 1-.896.88c-.384.203-.827.304-1.328.304-.65 0-1.21-.155-1.68-.464-.459-.31-.816-.752-1.072-1.328-.245-.587-.368-1.28-.368-2.08v-6.24h2.496v5.616Zm14.019 4.448c-.49 0-.933-.107-1.328-.32a2.085 2.085 0 0 1-.88-.864h-.592V55h-2.496V41.432h2.496v4.672h.592c.192-.352.485-.635.88-.848.395-.213.837-.32 1.328-.32.79 0 1.477.213 2.064.64.597.416 1.056 1.013 1.376 1.792.32.768.48 1.68.48 2.736 0 1.045-.16 1.957-.48 2.736-.32.768-.779 1.365-1.376 1.792-.587.416-1.275.624-2.064.624Zm-2.944-5.168c0 .928.192 1.653.576 2.176.395.512.944.768 1.648.768s1.248-.256 1.632-.768c.395-.523.592-1.248.592-2.176 0-.928-.197-1.648-.592-2.16-.384-.512-.928-.768-1.632-.768-.704 0-1.253.261-1.648.784-.384.512-.576 1.227-.576 2.144Zm10.835-4.896 2.256 7.072h1.376L57.12 54.2h-2.704l-2.96-9.008h2.56Zm4.144 10.864c-.245.8-.624 1.408-1.136 1.824-.501.416-1.125.624-1.872.624-.928 0-1.659-.256-2.192-.768-.523-.512-.832-1.259-.928-2.24h2.192c.117.32.245.544.384.672a.715.715 0 0 0 .528.208.623.623 0 0 0 .496-.224c.139-.139.261-.373.368-.704l2.848-10.256h2.368L58.16 56.056Z"/>
|
10
|
+
<path fill="#fff" fill-rule="evenodd" d="M81.437 91.746h10.957L73.606 72.945l7.83 18.802Zm-7.831-18.802v26.62l7.817-7.832" clip-rule="evenodd"/>
|
11
|
+
</g>
|
12
|
+
</g>
|
13
|
+
<defs>
|
14
|
+
<linearGradient id="c" x1="39.445" x2="39.445" y1="78.046" y2="22.535" gradientUnits="userSpaceOnUse">
|
15
|
+
<stop stop-color="#1D40B2"/>
|
16
|
+
<stop offset="1" stop-color="#1680D6"/>
|
17
|
+
</linearGradient>
|
18
|
+
<clipPath id="a">
|
19
|
+
<path fill="#fff" d="M0 0h266v100H0z"/>
|
20
|
+
</clipPath>
|
21
|
+
</defs>
|
22
|
+
</svg>
|