imgix 2.1.0 → 4.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 +5 -5
- data/.rubocop.yml +2 -0
- data/.travis.yml +16 -16
- data/.vscode/tasks.json +29 -0
- data/CHANGELOG.md +69 -0
- data/Gemfile +6 -1
- data/README.md +156 -38
- data/Rakefile +2 -0
- data/imgix.gemspec +22 -18
- data/lib/imgix/client.rb +66 -55
- data/lib/imgix/path.rb +197 -45
- data/lib/imgix/version.rb +1 -1
- data/lib/imgix.rb +47 -5
- data/script/bench_path.rb +11 -0
- data/script/bench_to_url.rb +12 -0
- metadata +17 -49
- data/lib/imgix/param_helpers.rb +0 -18
- data/test/test_helper.rb +0 -13
- data/test/units/domains_test.rb +0 -89
- data/test/units/path_test.rb +0 -132
- data/test/units/purge_test.rb +0 -25
- data/test/units/url_test.rb +0 -38
data/lib/imgix/client.rb
CHANGED
@@ -1,95 +1,106 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require 'uri'
|
3
|
+
require "digest"
|
4
|
+
require "net/http"
|
5
|
+
require "uri"
|
6
|
+
require "json"
|
8
7
|
|
9
8
|
module Imgix
|
10
9
|
class Client
|
11
|
-
DEFAULTS = { use_https: true
|
10
|
+
DEFAULTS = { use_https: true }.freeze
|
12
11
|
|
13
12
|
def initialize(options = {})
|
14
13
|
options = DEFAULTS.merge(options)
|
14
|
+
@domain = options[:domain]
|
15
|
+
|
16
|
+
validate_domain!
|
15
17
|
|
16
|
-
deprecate_warning!(options[:host],options[:hosts])
|
17
|
-
@hosts = Array(options[:host]) + Array(options[:hosts]) and validate_hosts!
|
18
18
|
@secure_url_token = options[:secure_url_token]
|
19
19
|
@api_key = options[:api_key]
|
20
20
|
@use_https = options[:use_https]
|
21
|
-
@shard_strategy = options[:shard_strategy] and validate_strategy!
|
22
21
|
@include_library_param = options.fetch(:include_library_param, true)
|
23
22
|
@library = options.fetch(:library_param, "rb")
|
24
23
|
@version = options.fetch(:library_version, Imgix::VERSION)
|
25
24
|
end
|
26
25
|
|
27
26
|
def path(path)
|
28
|
-
p = Path.new(prefix
|
27
|
+
p = Path.new(prefix, @secure_url_token, path)
|
29
28
|
p.ixlib("#{@library}-#{@version}") if @include_library_param
|
30
29
|
p
|
31
30
|
end
|
32
31
|
|
33
32
|
def purge(path)
|
34
|
-
|
35
|
-
|
36
|
-
uri = URI.parse('https://api.imgix.com/v2/image/purger')
|
37
|
-
req = Net::HTTP::Post.new(uri.path, {"User-Agent" => "imgix #{@library}-#{@version}"})
|
38
|
-
req.basic_auth @api_key, ''
|
39
|
-
req.set_form_data({'url' => url})
|
40
|
-
sock = Net::HTTP.new(uri.host, uri.port)
|
41
|
-
sock.use_ssl = true
|
42
|
-
res = sock.start {|http| http.request(req) }
|
43
|
-
res
|
44
|
-
end
|
33
|
+
api_key_error = "A valid API key is required to send purge requests"
|
34
|
+
raise api_key_error if @api_key.nil?
|
45
35
|
|
46
|
-
|
47
|
-
|
48
|
-
|
36
|
+
endpoint = URI.parse("https://api.imgix.com/api/v1/purge")
|
37
|
+
# Ensure the path has been prefixed with '/'.
|
38
|
+
path = path.start_with?("/") ? path : "/#{path}"
|
39
|
+
url = prefix + path
|
49
40
|
|
50
|
-
|
51
|
-
host = host_for_crc(path) if @shard_strategy == :crc
|
52
|
-
host = host_for_cycle if @shard_strategy == :cycle
|
53
|
-
host
|
54
|
-
end
|
41
|
+
req = create_request(endpoint, url, :json_data_from)
|
55
42
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@hosts[index]
|
43
|
+
sock = Net::HTTP.new(endpoint.host, endpoint.port)
|
44
|
+
sock.use_ssl = true
|
45
|
+
sock.start { |http| http.request(req) }
|
60
46
|
end
|
61
47
|
|
62
|
-
def
|
63
|
-
|
64
|
-
@hosts_cycle = @hosts.cycle
|
65
|
-
end
|
66
|
-
@hosts_cycle.next
|
48
|
+
def prefix
|
49
|
+
"#{@use_https ? 'https' : 'http'}://#{@domain}"
|
67
50
|
end
|
68
51
|
|
69
52
|
private
|
70
53
|
|
71
|
-
|
72
|
-
|
73
|
-
|
54
|
+
# Create a request object by specifying it's endpoint, resource, and
|
55
|
+
# an optional data_fmt.
|
56
|
+
#
|
57
|
+
# `endpoint` must be a valid URI object
|
58
|
+
# `resource` must be a valid URL designating the resource to be purged
|
59
|
+
# `data_fmt` must be a valid method or Proc object
|
60
|
+
#
|
61
|
+
# Specify a `data_fmt` method when a resource (URL) requires
|
62
|
+
# additional formatting before being included in the request body.
|
63
|
+
# By default, the data format is specified by the `json_data_from`
|
64
|
+
# method.
|
65
|
+
def create_request(endpoint, resource, data_fmt = :json_data_from)
|
66
|
+
req = Net::HTTP::Post.new(endpoint.path)
|
67
|
+
req["Content-Type"] = "application/vnd.api+json"
|
68
|
+
req["Authorization"] = "Bearer #{@api_key}"
|
69
|
+
req["User-Agent"] = "imgix #{@library}-#{@version}"
|
70
|
+
|
71
|
+
if data_fmt.is_a?(Proc)
|
72
|
+
req.body = data_fmt.call(resource)
|
73
|
+
elsif data_fmt.is_a?(Symbol)
|
74
|
+
req.body = send(data_fmt, resource)
|
75
|
+
else
|
76
|
+
fmt_arg_error = "`fmt' is required to be of class Symbol or " \
|
77
|
+
"Proc but was found to be\n\s\sof class #{data_fmt.class}\n"
|
78
|
+
raise ArgumentError, fmt_arg_error
|
74
79
|
end
|
80
|
+
|
81
|
+
req
|
75
82
|
end
|
76
83
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
84
|
+
def json_data_from(url)
|
85
|
+
{
|
86
|
+
data: {
|
87
|
+
attributes: {
|
88
|
+
url: url
|
89
|
+
},
|
90
|
+
type: "purges"
|
91
|
+
}
|
92
|
+
}.to_json
|
86
93
|
end
|
87
94
|
|
88
|
-
def
|
89
|
-
|
90
|
-
if
|
91
|
-
|
92
|
-
|
95
|
+
def validate_domain!
|
96
|
+
domain_error = "The :domain option must be specified"
|
97
|
+
raise ArgumentError, domain_error if @domain.nil?
|
98
|
+
|
99
|
+
domain_error = "Domains must be passed in as fully-qualified"\
|
100
|
+
"domain names and should not include a protocol"\
|
101
|
+
'or any path element, i.e. "example.imgix.net"'\
|
102
|
+
|
103
|
+
raise ArgumentError, domain_error if @domain.match(DOMAIN_REGEX).nil?
|
93
104
|
end
|
94
105
|
end
|
95
106
|
end
|
data/lib/imgix/path.rb
CHANGED
@@ -1,82 +1,125 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require 'imgix/param_helpers'
|
3
|
+
require "base64"
|
4
|
+
require "cgi/util"
|
5
|
+
require "erb"
|
7
6
|
|
8
7
|
module Imgix
|
9
8
|
class Path
|
10
|
-
include ParamHelpers
|
11
9
|
|
12
|
-
|
13
|
-
width: :w,
|
14
|
-
height: :h,
|
15
|
-
rotation: :rot,
|
16
|
-
noise_reduction: :nr,
|
17
|
-
sharpness: :sharp,
|
18
|
-
exposure: :exp,
|
19
|
-
vibrance: :vib,
|
20
|
-
saturation: :sat,
|
21
|
-
brightness: :bri,
|
22
|
-
contrast: :con,
|
23
|
-
highlight: :high,
|
24
|
-
shadow: :shad,
|
25
|
-
gamma: :gam,
|
26
|
-
pixelate: :px,
|
27
|
-
halftone: :htn,
|
28
|
-
watermark: :mark,
|
29
|
-
text: :txt,
|
30
|
-
format: :fm,
|
31
|
-
quality: :q
|
32
|
-
}
|
33
|
-
|
34
|
-
def initialize(prefix, secure_url_token, path = '/')
|
10
|
+
def initialize(prefix, secure_url_token, path = "/")
|
35
11
|
@prefix = prefix
|
36
12
|
@secure_url_token = secure_url_token
|
37
13
|
@path = path
|
38
14
|
@options = {}
|
39
|
-
|
40
|
-
@path = CGI.escape(@path) if /^https?/ =~ @path
|
41
|
-
@path = "/#{@path}" if @path[0] != '/'
|
42
15
|
end
|
43
16
|
|
44
17
|
def to_url(opts = {})
|
18
|
+
sanitized_path = sanitize_path(@path)
|
45
19
|
prev_options = @options.dup
|
46
20
|
@options.merge!(opts)
|
47
21
|
|
48
|
-
|
22
|
+
current_path_and_params = path_and_params(sanitized_path)
|
23
|
+
url = @prefix + current_path_and_params
|
49
24
|
|
50
25
|
if @secure_url_token
|
51
|
-
url += (has_query? ?
|
26
|
+
url += (has_query? ? "&" : "?") + "s=#{signature(current_path_and_params)}"
|
52
27
|
end
|
53
28
|
|
54
29
|
@options = prev_options
|
55
|
-
|
30
|
+
url
|
56
31
|
end
|
57
32
|
|
58
33
|
def defaults
|
59
34
|
@options = {}
|
60
|
-
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def ixlib(lib_version)
|
39
|
+
@options[:ixlib] = lib_version
|
61
40
|
end
|
62
41
|
|
42
|
+
def ixlib=(lib_version)
|
43
|
+
@options[:ixlib] = lib_version
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_srcset(options: {}, **params)
|
47
|
+
prev_options = @options.dup
|
48
|
+
@options.merge!(params)
|
49
|
+
|
50
|
+
width = @options[:w]
|
51
|
+
height = @options[:h]
|
52
|
+
aspect_ratio = @options[:ar]
|
53
|
+
|
54
|
+
srcset = if width || height
|
55
|
+
build_dpr_srcset(options: options, params: @options)
|
56
|
+
else
|
57
|
+
build_srcset_pairs(options: options, params: @options)
|
58
|
+
end
|
59
|
+
|
60
|
+
@options = prev_options
|
61
|
+
srcset
|
62
|
+
end
|
63
|
+
|
64
|
+
ALIASES = {
|
65
|
+
width: :w,
|
66
|
+
height: :h,
|
67
|
+
rotation: :rot,
|
68
|
+
noise_reduction: :nr,
|
69
|
+
sharpness: :sharp,
|
70
|
+
exposure: :exp,
|
71
|
+
vibrance: :vib,
|
72
|
+
saturation: :sat,
|
73
|
+
brightness: :bri,
|
74
|
+
contrast: :con,
|
75
|
+
highlight: :high,
|
76
|
+
shadow: :shad,
|
77
|
+
gamma: :gam,
|
78
|
+
pixelate: :px,
|
79
|
+
halftone: :htn,
|
80
|
+
watermark: :mark,
|
81
|
+
text: :txt,
|
82
|
+
format: :fm,
|
83
|
+
quality: :q,
|
84
|
+
fill_color: :fillcolor
|
85
|
+
}.freeze
|
86
|
+
|
87
|
+
# Define query parameters on a Path (via method_missing).
|
88
|
+
# Normally, when overriding method_missing, it is a best practice
|
89
|
+
# to fall back to super, but this method works differently.
|
90
|
+
#
|
91
|
+
# method_missing intercepts messages sent to objects of this class
|
92
|
+
# and acts as a getter, setter, and deleter. If there are no args,
|
93
|
+
# e.g. `path.width`, then this method acts like a getter.
|
94
|
+
#
|
95
|
+
# Likewise, if the first argument is nil and the method name exists
|
96
|
+
# as a key in @options, e.g. `path.param_name = nil`, then this
|
97
|
+
# method acts like a deleter and the `param_name` is removed from
|
98
|
+
# the list of @options.
|
99
|
+
#
|
100
|
+
# Finally, in _all_ other cases, the `method` name is used as the
|
101
|
+
# `key` and the `*args` are used as the value.
|
63
102
|
def method_missing(method, *args, &block)
|
64
103
|
key = method.to_s.gsub('=', '')
|
65
|
-
|
104
|
+
|
105
|
+
if args.length == 0 # Get, or
|
66
106
|
return @options[key]
|
67
|
-
elsif args.first.nil? && @options.has_key?(key)
|
107
|
+
elsif args.first.nil? && @options.has_key?(key) # Delete, or
|
68
108
|
@options.delete(key) and return self
|
69
109
|
end
|
70
110
|
|
71
|
-
@options[key] = args.join(',')
|
72
|
-
|
111
|
+
@options[key] = args.join(',') # Set the option.
|
112
|
+
self
|
73
113
|
end
|
74
114
|
|
115
|
+
# Use ALIASES to define setters for a subset of imgix parameters.
|
116
|
+
# E.g. `path.width(100)` would result in `send(:w, [100])`.
|
75
117
|
ALIASES.each do |from, to|
|
76
118
|
define_method from do |*args|
|
77
119
|
self.send(to, *args)
|
78
120
|
end
|
79
121
|
|
122
|
+
# E.g. `path.width = 100` would result in `send(":w=", [100])`.
|
80
123
|
define_method "#{from}=" do |*args|
|
81
124
|
self.send("#{to}=", *args)
|
82
125
|
return self
|
@@ -85,12 +128,46 @@ module Imgix
|
|
85
128
|
|
86
129
|
private
|
87
130
|
|
88
|
-
|
89
|
-
|
131
|
+
# Escape and encode any characters in path that are reserved and not utf8 encoded.
|
132
|
+
# This includes " +?:#" characters. If a path is being used as a proxy, utf8
|
133
|
+
# encode everything. If it is not being used as proxy, leave certain chars, like
|
134
|
+
# "/", alone. Method assumes path is not already encoded.
|
135
|
+
def sanitize_path(path)
|
136
|
+
# remove the leading "/", we'll add it back after encoding
|
137
|
+
path = path.slice(1, path.length) if Regexp.new('^/') =~ path
|
138
|
+
# if path is being used as a proxy, encode the entire thing
|
139
|
+
if /^https?/ =~ path
|
140
|
+
return encode_URI_Component(path)
|
141
|
+
else
|
142
|
+
# otherwise, encode only specific characters
|
143
|
+
return encode_URI(path)
|
144
|
+
end
|
90
145
|
end
|
91
146
|
|
92
|
-
|
93
|
-
|
147
|
+
# URL encode the entire path
|
148
|
+
def encode_URI_Component(path)
|
149
|
+
return "/" + ERB::Util.url_encode(path)
|
150
|
+
end
|
151
|
+
|
152
|
+
# URL encode every character in the path, including
|
153
|
+
# " +?:#" characters.
|
154
|
+
def encode_URI(path)
|
155
|
+
# For each component in the path, URL encode it and add it
|
156
|
+
# to the array path component.
|
157
|
+
path_components = []
|
158
|
+
path.split("/").each do |str|
|
159
|
+
path_components << ERB::Util.url_encode(str)
|
160
|
+
end
|
161
|
+
# Prefix and join the encoded path components.
|
162
|
+
"/#{path_components.join('/')}"
|
163
|
+
end
|
164
|
+
|
165
|
+
def signature(rest)
|
166
|
+
Digest::MD5.hexdigest(@secure_url_token + rest)
|
167
|
+
end
|
168
|
+
|
169
|
+
def path_and_params(path)
|
170
|
+
has_query? ? "#{path}?#{query}" : path
|
94
171
|
end
|
95
172
|
|
96
173
|
def query
|
@@ -102,11 +179,86 @@ module Imgix
|
|
102
179
|
else
|
103
180
|
escaped_key << "=" << ERB::Util.url_encode(val.to_s)
|
104
181
|
end
|
105
|
-
end.join(
|
182
|
+
end.join("&")
|
106
183
|
end
|
107
184
|
|
108
185
|
def has_query?
|
109
|
-
query.
|
186
|
+
!query.empty?
|
187
|
+
end
|
188
|
+
|
189
|
+
def build_srcset_pairs(options:, params:)
|
190
|
+
srcset = ""
|
191
|
+
|
192
|
+
widths = options[:widths] || []
|
193
|
+
width_tolerance = options[:width_tolerance] || DEFAULT_WIDTH_TOLERANCE
|
194
|
+
min_width = options[:min_width] || MIN_WIDTH
|
195
|
+
max_width = options[:max_width] || MAX_WIDTH
|
196
|
+
|
197
|
+
if !widths.empty?
|
198
|
+
validate_widths!(widths)
|
199
|
+
srcset_widths = widths
|
200
|
+
elsif width_tolerance != DEFAULT_WIDTH_TOLERANCE || min_width != MIN_WIDTH || max_width != MAX_WIDTH
|
201
|
+
validate_range!(min_width, max_width)
|
202
|
+
validate_width_tolerance!(width_tolerance)
|
203
|
+
srcset_widths = TARGET_WIDTHS.call(width_tolerance, min_width, max_width)
|
204
|
+
else
|
205
|
+
srcset_widths = DEFAULT_TARGET_WIDTHS
|
206
|
+
end
|
207
|
+
|
208
|
+
srcset_widths.each do |width|
|
209
|
+
params[:w] = width
|
210
|
+
srcset += "#{to_url(params)} #{width}w,\n"
|
211
|
+
end
|
212
|
+
|
213
|
+
srcset[0..-3]
|
214
|
+
end
|
215
|
+
|
216
|
+
def build_dpr_srcset(options:, params:)
|
217
|
+
srcset = ""
|
218
|
+
|
219
|
+
disable_variable_quality = options[:disable_variable_quality] || false
|
220
|
+
validate_variable_qualities!(disable_variable_quality)
|
221
|
+
|
222
|
+
target_ratios = [1, 2, 3, 4, 5]
|
223
|
+
quality = params[:q]
|
224
|
+
|
225
|
+
target_ratios.each do |ratio|
|
226
|
+
params[:dpr] = ratio
|
227
|
+
|
228
|
+
params[:q] = quality || DPR_QUALITY[ratio] unless disable_variable_quality
|
229
|
+
|
230
|
+
srcset += "#{to_url(params)} #{ratio}x,\n"
|
231
|
+
end
|
232
|
+
|
233
|
+
srcset[0..-3]
|
234
|
+
end
|
235
|
+
|
236
|
+
def validate_width_tolerance!(width_tolerance)
|
237
|
+
width_increment_error = "error: `width_tolerance` must be a positive `Numeric` value"
|
238
|
+
|
239
|
+
raise ArgumentError, width_increment_error if !width_tolerance.is_a?(Numeric) || width_tolerance <= 0
|
240
|
+
end
|
241
|
+
|
242
|
+
def validate_widths!(widths)
|
243
|
+
widths_error = "error: `widths` must be an array of positive `Numeric` values"
|
244
|
+
raise ArgumentError, widths_error unless widths.is_a?(Array)
|
245
|
+
|
246
|
+
all_positive_integers = widths.all? { |i| i.is_a?(Integer) && i > 0 }
|
247
|
+
raise ArgumentError, widths_error unless all_positive_integers
|
248
|
+
end
|
249
|
+
|
250
|
+
def validate_range!(min_width, max_width)
|
251
|
+
range_numeric_error = "error: `min_width` and `max_width` must be positive `Numeric` values"
|
252
|
+
raise ArgumentError, range_numeric_error unless min_width.is_a?(Numeric) && max_width.is_a?(Numeric)
|
253
|
+
|
254
|
+
raise ArgumentError, range_numeric_error unless min_width > 0 && max_width > 0
|
255
|
+
end
|
256
|
+
|
257
|
+
def validate_variable_qualities!(disable_quality)
|
258
|
+
disable_quality_error = "error: `disable_quality` must be a Boolean value"
|
259
|
+
unless disable_quality.is_a?(TrueClass) || disable_quality.is_a?(FalseClass)
|
260
|
+
raise ArgumentError, disable_quality_error
|
261
|
+
end
|
110
262
|
end
|
111
263
|
end
|
112
264
|
end
|
data/lib/imgix/version.rb
CHANGED
data/lib/imgix.rb
CHANGED
@@ -1,10 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "imgix/version"
|
4
|
+
require "imgix/client"
|
5
|
+
require "imgix/path"
|
6
6
|
|
7
7
|
module Imgix
|
8
|
-
|
9
|
-
DOMAIN_REGEX = /^(?:[a-z\d\-_]{1,62}\.){0,125}(?:[a-z\d](?:\-(?=\-*[a-z\d])|[a-z]|\d){0,62}\.)[a-z\d]{1,63}$/i
|
8
|
+
# regex pattern used to determine if a domain is valid
|
9
|
+
DOMAIN_REGEX = /^(?:[a-z\d\-_]{1,62}\.){0,125}(?:[a-z\d](?:\-(?=\-*[a-z\d])|[a-z]|\d){0,62}\.)[a-z\d]{1,63}$/i.freeze
|
10
|
+
|
11
|
+
# determines the growth rate when building out srcset pair widths
|
12
|
+
DEFAULT_WIDTH_TOLERANCE = 0.08
|
13
|
+
|
14
|
+
# the default minimum srcset width
|
15
|
+
MIN_WIDTH = 100
|
16
|
+
|
17
|
+
# the default maximum srcset width, also the max width supported by imgix
|
18
|
+
MAX_WIDTH = 8192
|
19
|
+
|
20
|
+
# returns an array of width values used during scrset generation
|
21
|
+
TARGET_WIDTHS = lambda { |tolerance, min, max|
|
22
|
+
increment_percentage = tolerance || DEFAULT_WIDTH_TOLERANCE
|
23
|
+
|
24
|
+
unless increment_percentage.is_a?(Numeric) && increment_percentage > 0
|
25
|
+
width_increment_error = "error: `width_tolerance` must be a positive `Numeric` value"
|
26
|
+
raise ArgumentError, width_increment_error
|
27
|
+
end
|
28
|
+
|
29
|
+
max_size = max || MAX_WIDTH
|
30
|
+
resolutions = []
|
31
|
+
prev = min || MIN_WIDTH
|
32
|
+
|
33
|
+
while prev < max_size
|
34
|
+
# ensures that each width is even
|
35
|
+
resolutions.push(prev.round)
|
36
|
+
prev *= 1 + (increment_percentage * 2)
|
37
|
+
end
|
38
|
+
|
39
|
+
resolutions.push(max_size)
|
40
|
+
return resolutions
|
41
|
+
}
|
42
|
+
DEFAULT_TARGET_WIDTHS = TARGET_WIDTHS.call(DEFAULT_WIDTH_TOLERANCE, MIN_WIDTH, MAX_WIDTH).freeze
|
43
|
+
|
44
|
+
# hash of default quality parameter values mapped by each dpr srcset entry
|
45
|
+
DPR_QUALITY = {
|
46
|
+
1 => 75,
|
47
|
+
2 => 50,
|
48
|
+
3 => 35,
|
49
|
+
4 => 23,
|
50
|
+
5 => 20
|
51
|
+
}.freeze
|
10
52
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH << 'lib'
|
2
|
+
require 'imgix'
|
3
|
+
require 'benchmark/ips'
|
4
|
+
|
5
|
+
client = Imgix::Client.new(domain: 'domain.com', secure_url_token: 'token')
|
6
|
+
path = client.path("/img.jpg")
|
7
|
+
|
8
|
+
Benchmark.ips do |x|
|
9
|
+
x.report('Imgix::Path#to_url') do
|
10
|
+
path.to_url({ auto: 'compress,format', fit: 'crop', crop: 'top', w: 590, h: 332 })
|
11
|
+
end
|
12
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imgix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kelly Sutton
|
@@ -10,39 +10,11 @@ authors:
|
|
10
10
|
- Antony Denyer
|
11
11
|
- Paul Straw
|
12
12
|
- Sherwin Heydarbeygi
|
13
|
-
autorequire:
|
13
|
+
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
17
|
-
dependencies:
|
18
|
-
- !ruby/object:Gem::Dependency
|
19
|
-
name: addressable
|
20
|
-
requirement: !ruby/object:Gem::Requirement
|
21
|
-
requirements:
|
22
|
-
- - ">="
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: '0'
|
25
|
-
type: :runtime
|
26
|
-
prerelease: false
|
27
|
-
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
requirements:
|
29
|
-
- - ">="
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version: '0'
|
32
|
-
- !ruby/object:Gem::Dependency
|
33
|
-
name: webmock
|
34
|
-
requirement: !ruby/object:Gem::Requirement
|
35
|
-
requirements:
|
36
|
-
- - ">="
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
version: '0'
|
39
|
-
type: :development
|
40
|
-
prerelease: false
|
41
|
-
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
requirements:
|
43
|
-
- - ">="
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
16
|
+
date: 2021-05-05 00:00:00.000000000 Z
|
17
|
+
dependencies: []
|
46
18
|
description: Easily create and sign imgix URLs.
|
47
19
|
email:
|
48
20
|
- kelly@imgix.com
|
@@ -56,7 +28,9 @@ extensions: []
|
|
56
28
|
extra_rdoc_files: []
|
57
29
|
files:
|
58
30
|
- ".gitignore"
|
31
|
+
- ".rubocop.yml"
|
59
32
|
- ".travis.yml"
|
33
|
+
- ".vscode/tasks.json"
|
60
34
|
- CHANGELOG.md
|
61
35
|
- Contributing.markdown
|
62
36
|
- Gemfile
|
@@ -66,19 +40,19 @@ files:
|
|
66
40
|
- imgix.gemspec
|
67
41
|
- lib/imgix.rb
|
68
42
|
- lib/imgix/client.rb
|
69
|
-
- lib/imgix/param_helpers.rb
|
70
43
|
- lib/imgix/path.rb
|
71
44
|
- lib/imgix/version.rb
|
72
|
-
-
|
73
|
-
-
|
74
|
-
- test/units/path_test.rb
|
75
|
-
- test/units/purge_test.rb
|
76
|
-
- test/units/url_test.rb
|
45
|
+
- script/bench_path.rb
|
46
|
+
- script/bench_to_url.rb
|
77
47
|
homepage: https://github.com/imgix/imgix-rb
|
78
48
|
licenses:
|
79
49
|
- MIT
|
80
|
-
metadata:
|
81
|
-
|
50
|
+
metadata:
|
51
|
+
bug_tracker_uri: https://github.com/imgix/imgix-rb/issues
|
52
|
+
changelog_uri: https://github.com/imgix/imgix-rb/blob/main/CHANGELOG.md
|
53
|
+
documentation_uri: https://www.rubydoc.info/gems/imgix/4.0.3
|
54
|
+
source_code_uri: https://github.com/imgix/imgix-rb/tree/4.0.3
|
55
|
+
post_install_message:
|
82
56
|
rdoc_options: []
|
83
57
|
require_paths:
|
84
58
|
- lib
|
@@ -93,14 +67,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
67
|
- !ruby/object:Gem::Version
|
94
68
|
version: '0'
|
95
69
|
requirements: []
|
96
|
-
|
97
|
-
|
98
|
-
signing_key:
|
70
|
+
rubygems_version: 3.1.4
|
71
|
+
signing_key:
|
99
72
|
specification_version: 4
|
100
73
|
summary: Official Ruby Gem for easily creating and signing imgix URLs.
|
101
|
-
test_files:
|
102
|
-
- test/test_helper.rb
|
103
|
-
- test/units/domains_test.rb
|
104
|
-
- test/units/path_test.rb
|
105
|
-
- test/units/purge_test.rb
|
106
|
-
- test/units/url_test.rb
|
74
|
+
test_files: []
|
data/lib/imgix/param_helpers.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Imgix
|
4
|
-
module ParamHelpers
|
5
|
-
def rect(position)
|
6
|
-
@options[:rect] = position and return self if position.is_a?(String)
|
7
|
-
|
8
|
-
@options[:rect] = [
|
9
|
-
position[:x] || position[:left],
|
10
|
-
position[:y] || position[:top],
|
11
|
-
position[:width] || (position[:right] - position[:left]),
|
12
|
-
position[:height] || (position[:bottom] - position[:top])
|
13
|
-
].join(',')
|
14
|
-
|
15
|
-
return self
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|