shrine 3.1.0 → 3.4.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/CHANGELOG.md +82 -0
- data/README.md +11 -4
- data/doc/advantages.md +4 -4
- data/doc/attacher.md +2 -2
- data/doc/carrierwave.md +24 -12
- data/doc/changing_derivatives.md +1 -1
- data/doc/changing_location.md +6 -5
- data/doc/design.md +134 -85
- data/doc/direct_s3.md +26 -0
- data/doc/external/articles.md +57 -45
- data/doc/external/extensions.md +41 -35
- data/doc/external/misc.md +23 -8
- data/doc/getting_started.md +156 -85
- data/doc/metadata.md +80 -44
- data/doc/multiple_files.md +1 -1
- data/doc/paperclip.md +28 -9
- data/doc/plugins/add_metadata.md +112 -35
- data/doc/plugins/atomic_helpers.md +41 -3
- data/doc/plugins/backgrounding.md +12 -2
- data/doc/plugins/column.md +36 -7
- data/doc/plugins/default_url.md +6 -3
- data/doc/plugins/derivatives.md +83 -44
- data/doc/plugins/download_endpoint.md +5 -5
- data/doc/plugins/dynamic_storage.md +1 -1
- data/doc/plugins/entity.md +12 -4
- data/doc/plugins/form_assign.md +5 -5
- data/doc/plugins/included.md +25 -5
- data/doc/plugins/infer_extension.md +9 -0
- data/doc/plugins/instrumentation.md +1 -1
- data/doc/plugins/metadata_attributes.md +1 -0
- data/doc/plugins/mirroring.md +1 -1
- data/doc/plugins/model.md +8 -3
- data/doc/plugins/persistence.md +10 -1
- data/doc/plugins/remote_url.md +6 -1
- data/doc/plugins/remove_invalid.md +9 -1
- data/doc/plugins/sequel.md +1 -1
- data/doc/plugins/store_dimensions.md +10 -0
- data/doc/plugins/type_predicates.md +96 -0
- data/doc/plugins/upload_endpoint.md +1 -1
- data/doc/plugins/upload_options.md +1 -1
- data/doc/plugins/url_options.md +4 -4
- data/doc/plugins/validation.md +14 -4
- data/doc/plugins/versions.md +7 -7
- data/doc/processing.md +287 -123
- data/doc/refile.md +9 -9
- data/doc/release_notes/2.8.0.md +1 -1
- data/doc/release_notes/3.0.0.md +1 -1
- data/doc/release_notes/3.2.0.md +96 -0
- data/doc/release_notes/3.2.1.md +31 -0
- data/doc/release_notes/3.2.2.md +14 -0
- data/doc/release_notes/3.3.0.md +105 -0
- data/doc/release_notes/3.4.0.md +35 -0
- data/doc/securing_uploads.md +2 -2
- data/doc/storage/memory.md +19 -0
- data/doc/storage/s3.md +104 -77
- data/doc/testing.md +12 -2
- data/doc/upgrading_to_3.md +99 -53
- data/lib/shrine.rb +9 -8
- data/lib/shrine/attacher.rb +20 -10
- data/lib/shrine/attachment.rb +2 -2
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/plugins/activerecord.rb +3 -3
- data/lib/shrine/plugins/add_metadata.rb +20 -5
- data/lib/shrine/plugins/backgrounding.rb +2 -2
- data/lib/shrine/plugins/default_url.rb +1 -1
- data/lib/shrine/plugins/derivation_endpoint.rb +13 -8
- data/lib/shrine/plugins/derivatives.rb +59 -30
- data/lib/shrine/plugins/determine_mime_type.rb +5 -3
- data/lib/shrine/plugins/entity.rb +12 -11
- data/lib/shrine/plugins/instrumentation.rb +12 -18
- data/lib/shrine/plugins/mirroring.rb +8 -8
- data/lib/shrine/plugins/model.rb +3 -3
- data/lib/shrine/plugins/presign_endpoint.rb +16 -4
- data/lib/shrine/plugins/pretty_location.rb +1 -1
- data/lib/shrine/plugins/processing.rb +1 -1
- data/lib/shrine/plugins/refresh_metadata.rb +2 -2
- data/lib/shrine/plugins/remote_url.rb +3 -3
- data/lib/shrine/plugins/remove_attachment.rb +5 -0
- data/lib/shrine/plugins/remove_invalid.rb +10 -5
- data/lib/shrine/plugins/sequel.rb +1 -1
- data/lib/shrine/plugins/store_dimensions.rb +4 -2
- data/lib/shrine/plugins/type_predicates.rb +113 -0
- data/lib/shrine/plugins/upload_endpoint.rb +10 -5
- data/lib/shrine/plugins/upload_options.rb +2 -2
- data/lib/shrine/plugins/url_options.rb +2 -2
- data/lib/shrine/plugins/validation.rb +9 -7
- data/lib/shrine/storage/linter.rb +4 -4
- data/lib/shrine/storage/memory.rb +5 -3
- data/lib/shrine/storage/s3.rb +117 -38
- data/lib/shrine/version.rb +1 -1
- data/shrine.gemspec +8 -8
- metadata +42 -34
@@ -9,11 +9,11 @@ class Shrine
|
|
9
9
|
module Plugins
|
10
10
|
# Documentation can be found on https://shrinerb.com/docs/plugins/upload_endpoint
|
11
11
|
module UploadEndpoint
|
12
|
-
def self.load_dependencies(uploader,
|
12
|
+
def self.load_dependencies(uploader, **)
|
13
13
|
uploader.plugin :rack_file
|
14
14
|
end
|
15
15
|
|
16
|
-
def self.configure(uploader, opts
|
16
|
+
def self.configure(uploader, **opts)
|
17
17
|
uploader.opts[:upload_endpoint] ||= {}
|
18
18
|
uploader.opts[:upload_endpoint].merge!(opts)
|
19
19
|
end
|
@@ -135,9 +135,14 @@ class Shrine
|
|
135
135
|
end
|
136
136
|
|
137
137
|
error!(400, "Upload Not Found") if value.nil?
|
138
|
-
error!(400, "Upload Not Valid") unless value.is_a?(Hash) && value[:tempfile]
|
139
138
|
|
140
|
-
|
139
|
+
if value.is_a?(Hash) && value[:tempfile]
|
140
|
+
@shrine_class.rack_file(value)
|
141
|
+
elsif %i[read rewind eof? close].all? { |m| value.respond_to?(m) }
|
142
|
+
value
|
143
|
+
else
|
144
|
+
error!(400, "Upload Not Valid")
|
145
|
+
end
|
141
146
|
end
|
142
147
|
|
143
148
|
# Returns a hash of information containing `:action` and `:request`
|
@@ -156,7 +161,7 @@ class Shrine
|
|
156
161
|
if @upload
|
157
162
|
@upload.call(io, context, request)
|
158
163
|
else
|
159
|
-
uploader.upload(io, context)
|
164
|
+
uploader.upload(io, **context)
|
160
165
|
end
|
161
166
|
end
|
162
167
|
|
@@ -4,9 +4,9 @@ class Shrine
|
|
4
4
|
module Plugins
|
5
5
|
# Documentation can be found on https://shrinerb.com/docs/plugins/upload_options
|
6
6
|
module UploadOptions
|
7
|
-
def self.configure(uploader,
|
7
|
+
def self.configure(uploader, **opts)
|
8
8
|
uploader.opts[:upload_options] ||= {}
|
9
|
-
uploader.opts[:upload_options].merge!(
|
9
|
+
uploader.opts[:upload_options].merge!(opts)
|
10
10
|
end
|
11
11
|
|
12
12
|
module InstanceMethods
|
@@ -4,9 +4,9 @@ class Shrine
|
|
4
4
|
module Plugins
|
5
5
|
# Documentation can be found on https://shrinerb.com/docs/plugins/url_options
|
6
6
|
module UrlOptions
|
7
|
-
def self.configure(uploader, **
|
7
|
+
def self.configure(uploader, **opts)
|
8
8
|
uploader.opts[:url_options] ||= {}
|
9
|
-
uploader.opts[:url_options].merge!(
|
9
|
+
uploader.opts[:url_options].merge!(opts)
|
10
10
|
end
|
11
11
|
|
12
12
|
module FileMethods
|
@@ -29,14 +29,16 @@ class Shrine
|
|
29
29
|
@errors = []
|
30
30
|
end
|
31
31
|
|
32
|
-
#
|
33
|
-
def
|
34
|
-
super(
|
32
|
+
# Performs validations after attaching cached file.
|
33
|
+
def attach_cached(value, validate: nil, **options)
|
34
|
+
result = super(value, validate: false, **options)
|
35
|
+
validation(validate)
|
36
|
+
result
|
35
37
|
end
|
36
38
|
|
37
|
-
# Performs validations after
|
38
|
-
def
|
39
|
-
result = super
|
39
|
+
# Performs validations after attaching file.
|
40
|
+
def attach(io, validate: nil, **options)
|
41
|
+
result = super(io, **options)
|
40
42
|
validation(validate)
|
41
43
|
result
|
42
44
|
end
|
@@ -52,7 +54,7 @@ class Shrine
|
|
52
54
|
# Calls validation appropriately based on the :validate value.
|
53
55
|
def validation(argument)
|
54
56
|
case argument
|
55
|
-
when Hash then validate(argument)
|
57
|
+
when Hash then validate(**argument)
|
56
58
|
when false then errors.clear # skip validation
|
57
59
|
else validate
|
58
60
|
end
|
@@ -35,7 +35,7 @@ class Shrine
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def call(io_factory = default_io_factory)
|
38
|
-
storage.upload(io_factory.call, id = "foo", {})
|
38
|
+
storage.upload(io_factory.call, id = "foo", shrine_metadata: { "foo" => "bar" })
|
39
39
|
|
40
40
|
lint_open(id)
|
41
41
|
lint_exists(id)
|
@@ -67,13 +67,13 @@ class Shrine
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def lint_open(id)
|
70
|
-
opened = storage.open(id
|
70
|
+
opened = storage.open(id)
|
71
71
|
error :open, "doesn't return a valid IO object" if !io?(opened)
|
72
72
|
error :open, "returns an empty IO object" if opened.read.empty?
|
73
73
|
opened.close
|
74
74
|
|
75
75
|
begin
|
76
|
-
storage.open(@nonexisting
|
76
|
+
storage.open(@nonexisting)
|
77
77
|
error :open, "should raise an exception on nonexisting file"
|
78
78
|
rescue Shrine::FileNotFound
|
79
79
|
rescue => exception
|
@@ -107,7 +107,7 @@ class Shrine
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def lint_presign(id)
|
110
|
-
data = storage.presign(id
|
110
|
+
data = storage.presign(id)
|
111
111
|
error :presign, "result should be a Hash" unless data.respond_to?(:to_h)
|
112
112
|
error :presign, "result should include :method key" unless data.to_h.key?(:method)
|
113
113
|
error :presign, "result should include :url key" unless data.to_h.key?(:url)
|
@@ -12,12 +12,14 @@ class Shrine
|
|
12
12
|
@store = store
|
13
13
|
end
|
14
14
|
|
15
|
-
def upload(io, id,
|
15
|
+
def upload(io, id, **)
|
16
16
|
store[id] = io.read
|
17
17
|
end
|
18
18
|
|
19
|
-
def open(id,
|
20
|
-
StringIO.new(store.fetch(id))
|
19
|
+
def open(id, **)
|
20
|
+
io = StringIO.new(store.fetch(id))
|
21
|
+
io.set_encoding(io.string.encoding) # Ruby 2.7.0 – https://bugs.ruby-lang.org/issues/16497
|
22
|
+
io
|
21
23
|
rescue KeyError
|
22
24
|
raise Shrine::FileNotFound, "file #{id.inspect} not found on storage"
|
23
25
|
end
|
data/lib/shrine/storage/s3.rb
CHANGED
@@ -9,6 +9,7 @@ require "down/chunked_io"
|
|
9
9
|
require "content_disposition"
|
10
10
|
|
11
11
|
require "uri"
|
12
|
+
require "tempfile"
|
12
13
|
|
13
14
|
class Shrine
|
14
15
|
module Storage
|
@@ -103,7 +104,7 @@ class Shrine
|
|
103
104
|
#
|
104
105
|
# [`Aws::S3::Object#get`]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#get-instance_method
|
105
106
|
def open(id, rewindable: true, **options)
|
106
|
-
chunks, length =
|
107
|
+
chunks, length = get(id, **options)
|
107
108
|
|
108
109
|
Down::ChunkedIO.new(chunks: chunks, rewindable: rewindable, size: length)
|
109
110
|
rescue Aws::S3::Errors::NoSuchKey
|
@@ -179,25 +180,7 @@ class Shrine
|
|
179
180
|
options.merge!(@upload_options)
|
180
181
|
options.merge!(presign_options)
|
181
182
|
|
182
|
-
|
183
|
-
presigned_post = object(id).presigned_post(options)
|
184
|
-
|
185
|
-
{ method: method, url: presigned_post.url, fields: presigned_post.fields }
|
186
|
-
else
|
187
|
-
url = object(id).presigned_url(method, options)
|
188
|
-
|
189
|
-
# When any of these options are specified, the corresponding request
|
190
|
-
# headers must be included in the upload request.
|
191
|
-
headers = {}
|
192
|
-
headers["Content-Length"] = options[:content_length] if options[:content_length]
|
193
|
-
headers["Content-Type"] = options[:content_type] if options[:content_type]
|
194
|
-
headers["Content-Disposition"] = options[:content_disposition] if options[:content_disposition]
|
195
|
-
headers["Content-Encoding"] = options[:content_encoding] if options[:content_encoding]
|
196
|
-
headers["Content-Language"] = options[:content_language] if options[:content_language]
|
197
|
-
headers["Content-MD5"] = options[:content_md5] if options[:content_md5]
|
198
|
-
|
199
|
-
{ method: method, url: url, headers: headers }
|
200
|
-
end
|
183
|
+
send(:"presign_#{method}", id, options)
|
201
184
|
end
|
202
185
|
|
203
186
|
# Deletes the file from the storage.
|
@@ -230,11 +213,22 @@ class Shrine
|
|
230
213
|
|
231
214
|
# Returns an `Aws::S3::Object` for the given id.
|
232
215
|
def object(id)
|
233
|
-
bucket.object(
|
216
|
+
bucket.object(object_key(id))
|
234
217
|
end
|
235
218
|
|
236
219
|
private
|
237
220
|
|
221
|
+
# Uploads the file to S3. Uses multipart upload for large files.
|
222
|
+
def put(io, id, **options)
|
223
|
+
if io.respond_to?(:size) && io.size && io.size <= @multipart_threshold[:upload]
|
224
|
+
object(id).put(body: io, **options)
|
225
|
+
else # multipart upload
|
226
|
+
object(id).upload_stream(part_size: part_size(io), **options) do |write_stream|
|
227
|
+
IO.copy_stream(io, write_stream)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
238
232
|
# Copies an existing S3 object to a new location. Uses multipart copy for
|
239
233
|
# large files.
|
240
234
|
def copy(io, id, **copy_options)
|
@@ -250,15 +244,28 @@ class Shrine
|
|
250
244
|
object(id).copy_from(io.storage.object(io.id), **options)
|
251
245
|
end
|
252
246
|
|
253
|
-
#
|
254
|
-
def
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
247
|
+
# Generates parameters for a POST upload request.
|
248
|
+
def presign_post(id, options)
|
249
|
+
presigned_post = object(id).presigned_post(options)
|
250
|
+
|
251
|
+
{ method: :post, url: presigned_post.url, fields: presigned_post.fields }
|
252
|
+
end
|
253
|
+
|
254
|
+
# Generates parameters for a PUT upload request.
|
255
|
+
def presign_put(id, options)
|
256
|
+
url = object(id).presigned_url(:put, options)
|
257
|
+
|
258
|
+
# When any of these options are specified, the corresponding request
|
259
|
+
# headers must be included in the upload request.
|
260
|
+
headers = {}
|
261
|
+
headers["Content-Length"] = options[:content_length] if options[:content_length]
|
262
|
+
headers["Content-Type"] = options[:content_type] if options[:content_type]
|
263
|
+
headers["Content-Disposition"] = options[:content_disposition] if options[:content_disposition]
|
264
|
+
headers["Content-Encoding"] = options[:content_encoding] if options[:content_encoding]
|
265
|
+
headers["Content-Language"] = options[:content_language] if options[:content_language]
|
266
|
+
headers["Content-MD5"] = options[:content_md5] if options[:content_md5]
|
267
|
+
|
268
|
+
{ method: :put, url: url, headers: headers }
|
262
269
|
end
|
263
270
|
|
264
271
|
# Determins the part size that should be used when uploading the given IO
|
@@ -274,17 +281,38 @@ class Shrine
|
|
274
281
|
end
|
275
282
|
|
276
283
|
# Aws::S3::Object#get doesn't allow us to get the content length of the
|
277
|
-
# object before
|
278
|
-
|
279
|
-
|
284
|
+
# object before all content is downloaded, so we hack our way around it.
|
285
|
+
# This way get the content length without an additional HEAD request.
|
286
|
+
if Gem::Version.new(Aws::CORE_GEM_VERSION) >= Gem::Version.new("3.104.0")
|
287
|
+
def get(id, **params)
|
288
|
+
enum = object(id).enum_for(:get, **params)
|
289
|
+
|
290
|
+
begin
|
291
|
+
content_length = Integer(enum.peek.last["content-length"])
|
292
|
+
rescue StopIteration
|
293
|
+
content_length = 0
|
294
|
+
end
|
280
295
|
|
281
|
-
|
282
|
-
|
296
|
+
chunks = Enumerator.new { |y| loop { y << enum.next.first } }
|
297
|
+
|
298
|
+
[chunks, content_length]
|
299
|
+
end
|
300
|
+
else
|
301
|
+
def get(id, **params)
|
302
|
+
req = client.build_request(:get_object, bucket: bucket.name, key: object_key(id), **params)
|
303
|
+
|
304
|
+
body = req.enum_for(:send_request)
|
305
|
+
begin
|
306
|
+
body.peek # start the request
|
307
|
+
rescue StopIteration
|
308
|
+
# the S3 object is empty
|
309
|
+
end
|
283
310
|
|
284
|
-
|
285
|
-
|
311
|
+
content_length = Integer(req.context.http_response.headers["Content-Length"])
|
312
|
+
chunks = Enumerator.new { |y| loop { y << body.next } }
|
286
313
|
|
287
|
-
|
314
|
+
[chunks, content_length]
|
315
|
+
end
|
288
316
|
end
|
289
317
|
|
290
318
|
# The file is copyable if it's on S3 and on the same Amazon account.
|
@@ -302,6 +330,57 @@ class Shrine
|
|
302
330
|
bucket.delete_objects(delete: delete_params)
|
303
331
|
end
|
304
332
|
end
|
333
|
+
|
334
|
+
# Returns object key with potential prefix.
|
335
|
+
def object_key(id)
|
336
|
+
[*prefix, id].join("/")
|
337
|
+
end
|
338
|
+
|
339
|
+
# Adds support for Aws::S3::Encryption::Client.
|
340
|
+
module ClientSideEncryption
|
341
|
+
attr_reader :encryption_client
|
342
|
+
|
343
|
+
# Save the encryption client and continue initialization with normal
|
344
|
+
# client.
|
345
|
+
def initialize(client: nil, **options)
|
346
|
+
return super unless client.class.name.start_with?("Aws::S3::Encryption")
|
347
|
+
|
348
|
+
super(client: client.client, **options)
|
349
|
+
@encryption_client = client
|
350
|
+
end
|
351
|
+
|
352
|
+
private
|
353
|
+
|
354
|
+
# Encryption client doesn't support multipart uploads, so we always use
|
355
|
+
# #put_object.
|
356
|
+
def put(io, id, **options)
|
357
|
+
return super unless encryption_client
|
358
|
+
|
359
|
+
encryption_client.put_object(body: io, bucket: bucket.name, key: object_key(id), **options)
|
360
|
+
end
|
361
|
+
|
362
|
+
def get(id, **options)
|
363
|
+
return super unless encryption_client
|
364
|
+
|
365
|
+
# Encryption client v2 warns against streaming download, so we first
|
366
|
+
# download all content into a file.
|
367
|
+
tempfile = Tempfile.new("shrine-s3", binmode: true)
|
368
|
+
response = encryption_client.get_object(response_target: tempfile, bucket: bucket.name, key: object_key(id), **options)
|
369
|
+
tempfile.rewind
|
370
|
+
|
371
|
+
chunks = Enumerator.new do |yielder|
|
372
|
+
begin
|
373
|
+
yielder << tempfile.read(16*1024) until tempfile.eof?
|
374
|
+
ensure
|
375
|
+
tempfile.close!
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
[chunks, tempfile.size]
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
prepend ClientSideEncryption
|
305
384
|
end
|
306
385
|
end
|
307
386
|
end
|
data/lib/shrine/version.rb
CHANGED
data/shrine.gemspec
CHANGED
@@ -33,18 +33,17 @@ direct uploads for fully asynchronous user experience.
|
|
33
33
|
gem.files = Dir["README.md", "LICENSE.txt", "CHANGELOG.md", "lib/**/*.rb", "shrine.gemspec", "doc/**/*.md"]
|
34
34
|
gem.require_path = "lib"
|
35
35
|
|
36
|
-
gem.add_dependency "down", "~> 5.
|
36
|
+
gem.add_dependency "down", "~> 5.1"
|
37
37
|
gem.add_dependency "content_disposition", "~> 1.0"
|
38
38
|
|
39
39
|
# general testing helpers
|
40
40
|
gem.add_development_dependency "rake", ">= 11.1"
|
41
41
|
gem.add_development_dependency "minitest", "~> 5.8"
|
42
|
-
gem.add_development_dependency "mocha", "~> 1.
|
43
|
-
gem.add_development_dependency "dry-initializer"
|
42
|
+
gem.add_development_dependency "mocha", "~> 1.11"
|
44
43
|
|
45
44
|
# for endpoint plugins
|
46
45
|
gem.add_development_dependency "rack", "~> 2.0"
|
47
|
-
gem.add_development_dependency "http-form_data", "~> 2.
|
46
|
+
gem.add_development_dependency "http-form_data", "~> 2.2"
|
48
47
|
gem.add_development_dependency "rack-test_app"
|
49
48
|
|
50
49
|
# for determine_mime_type plugin
|
@@ -62,15 +61,16 @@ direct uploads for fully asynchronous user experience.
|
|
62
61
|
gem.add_development_dependency "ruby-vips", "~> 2.0" unless ENV["CI"]
|
63
62
|
|
64
63
|
# for S3 storage
|
65
|
-
gem.add_development_dependency "aws-sdk-s3", "~> 1.
|
64
|
+
gem.add_development_dependency "aws-sdk-s3", "~> 1.69"
|
66
65
|
gem.add_development_dependency "aws-sdk-core", "~> 3.23"
|
66
|
+
gem.add_development_dependency "rexml"
|
67
67
|
|
68
68
|
# for instrumentation plugin
|
69
69
|
gem.add_development_dependency "dry-monitor"
|
70
|
-
gem.add_development_dependency "activesupport", "~> 5.2
|
70
|
+
gem.add_development_dependency "activesupport", RUBY_VERSION >= "2.5" ? "~> 6.0" : "~> 5.2"
|
71
71
|
|
72
72
|
# for ORM plugins
|
73
73
|
gem.add_development_dependency "sequel"
|
74
|
-
gem.add_development_dependency "activerecord", "~> 5.2
|
75
|
-
gem.add_development_dependency "sqlite3", "~> 1.
|
74
|
+
gem.add_development_dependency "activerecord", RUBY_VERSION >= "2.5" ? "~> 6.0" : "~> 5.2"
|
75
|
+
gem.add_development_dependency "sqlite3", "~> 1.4" unless RUBY_ENGINE == "jruby"
|
76
76
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shrine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janko Marohnić
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: down
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
19
|
+
version: '5.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '5.
|
26
|
+
version: '5.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: content_disposition
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,28 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '1.
|
75
|
+
version: '1.11'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '1.
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: dry-initializer
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
82
|
+
version: '1.11'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rack
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,14 +100,14 @@ dependencies:
|
|
114
100
|
requirements:
|
115
101
|
- - "~>"
|
116
102
|
- !ruby/object:Gem::Version
|
117
|
-
version: '2.
|
103
|
+
version: '2.2'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
108
|
- - "~>"
|
123
109
|
- !ruby/object:Gem::Version
|
124
|
-
version: '2.
|
110
|
+
version: '2.2'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: rack-test_app
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -254,14 +240,14 @@ dependencies:
|
|
254
240
|
requirements:
|
255
241
|
- - "~>"
|
256
242
|
- !ruby/object:Gem::Version
|
257
|
-
version: '1.
|
243
|
+
version: '1.69'
|
258
244
|
type: :development
|
259
245
|
prerelease: false
|
260
246
|
version_requirements: !ruby/object:Gem::Requirement
|
261
247
|
requirements:
|
262
248
|
- - "~>"
|
263
249
|
- !ruby/object:Gem::Version
|
264
|
-
version: '1.
|
250
|
+
version: '1.69'
|
265
251
|
- !ruby/object:Gem::Dependency
|
266
252
|
name: aws-sdk-core
|
267
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -276,6 +262,20 @@ dependencies:
|
|
276
262
|
- - "~>"
|
277
263
|
- !ruby/object:Gem::Version
|
278
264
|
version: '3.23'
|
265
|
+
- !ruby/object:Gem::Dependency
|
266
|
+
name: rexml
|
267
|
+
requirement: !ruby/object:Gem::Requirement
|
268
|
+
requirements:
|
269
|
+
- - ">="
|
270
|
+
- !ruby/object:Gem::Version
|
271
|
+
version: '0'
|
272
|
+
type: :development
|
273
|
+
prerelease: false
|
274
|
+
version_requirements: !ruby/object:Gem::Requirement
|
275
|
+
requirements:
|
276
|
+
- - ">="
|
277
|
+
- !ruby/object:Gem::Version
|
278
|
+
version: '0'
|
279
279
|
- !ruby/object:Gem::Dependency
|
280
280
|
name: dry-monitor
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
@@ -296,14 +296,14 @@ dependencies:
|
|
296
296
|
requirements:
|
297
297
|
- - "~>"
|
298
298
|
- !ruby/object:Gem::Version
|
299
|
-
version:
|
299
|
+
version: '6.0'
|
300
300
|
type: :development
|
301
301
|
prerelease: false
|
302
302
|
version_requirements: !ruby/object:Gem::Requirement
|
303
303
|
requirements:
|
304
304
|
- - "~>"
|
305
305
|
- !ruby/object:Gem::Version
|
306
|
-
version:
|
306
|
+
version: '6.0'
|
307
307
|
- !ruby/object:Gem::Dependency
|
308
308
|
name: sequel
|
309
309
|
requirement: !ruby/object:Gem::Requirement
|
@@ -324,28 +324,28 @@ dependencies:
|
|
324
324
|
requirements:
|
325
325
|
- - "~>"
|
326
326
|
- !ruby/object:Gem::Version
|
327
|
-
version:
|
327
|
+
version: '6.0'
|
328
328
|
type: :development
|
329
329
|
prerelease: false
|
330
330
|
version_requirements: !ruby/object:Gem::Requirement
|
331
331
|
requirements:
|
332
332
|
- - "~>"
|
333
333
|
- !ruby/object:Gem::Version
|
334
|
-
version:
|
334
|
+
version: '6.0'
|
335
335
|
- !ruby/object:Gem::Dependency
|
336
336
|
name: sqlite3
|
337
337
|
requirement: !ruby/object:Gem::Requirement
|
338
338
|
requirements:
|
339
339
|
- - "~>"
|
340
340
|
- !ruby/object:Gem::Version
|
341
|
-
version: 1.
|
341
|
+
version: '1.4'
|
342
342
|
type: :development
|
343
343
|
prerelease: false
|
344
344
|
version_requirements: !ruby/object:Gem::Requirement
|
345
345
|
requirements:
|
346
346
|
- - "~>"
|
347
347
|
- !ruby/object:Gem::Version
|
348
|
-
version: 1.
|
348
|
+
version: '1.4'
|
349
349
|
description: |
|
350
350
|
Shrine is a toolkit for file attachments in Ruby applications. It supports
|
351
351
|
uploading, downloading, processing and deleting IO objects, backed by various
|
@@ -424,6 +424,7 @@ files:
|
|
424
424
|
- doc/plugins/signature.md
|
425
425
|
- doc/plugins/store_dimensions.md
|
426
426
|
- doc/plugins/tempfile.md
|
427
|
+
- doc/plugins/type_predicates.md
|
427
428
|
- doc/plugins/upload_endpoint.md
|
428
429
|
- doc/plugins/upload_options.md
|
429
430
|
- doc/plugins/url_options.md
|
@@ -468,9 +469,15 @@ files:
|
|
468
469
|
- doc/release_notes/3.0.0.md
|
469
470
|
- doc/release_notes/3.0.1.md
|
470
471
|
- doc/release_notes/3.1.0.md
|
472
|
+
- doc/release_notes/3.2.0.md
|
473
|
+
- doc/release_notes/3.2.1.md
|
474
|
+
- doc/release_notes/3.2.2.md
|
475
|
+
- doc/release_notes/3.3.0.md
|
476
|
+
- doc/release_notes/3.4.0.md
|
471
477
|
- doc/retrieving_uploads.md
|
472
478
|
- doc/securing_uploads.md
|
473
479
|
- doc/storage/file_system.md
|
480
|
+
- doc/storage/memory.md
|
474
481
|
- doc/storage/s3.md
|
475
482
|
- doc/testing.md
|
476
483
|
- doc/upgrading_to_3.md
|
@@ -523,6 +530,7 @@ files:
|
|
523
530
|
- lib/shrine/plugins/signature.rb
|
524
531
|
- lib/shrine/plugins/store_dimensions.rb
|
525
532
|
- lib/shrine/plugins/tempfile.rb
|
533
|
+
- lib/shrine/plugins/type_predicates.rb
|
526
534
|
- lib/shrine/plugins/upload_endpoint.rb
|
527
535
|
- lib/shrine/plugins/upload_options.rb
|
528
536
|
- lib/shrine/plugins/url_options.rb
|
@@ -545,7 +553,7 @@ metadata:
|
|
545
553
|
documentation_uri: https://shrinerb.com
|
546
554
|
mailing_list_uri: https://discourse.shrinerb.com
|
547
555
|
source_code_uri: https://github.com/shrinerb/shrine
|
548
|
-
post_install_message:
|
556
|
+
post_install_message:
|
549
557
|
rdoc_options: []
|
550
558
|
require_paths:
|
551
559
|
- lib
|
@@ -560,8 +568,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
560
568
|
- !ruby/object:Gem::Version
|
561
569
|
version: '0'
|
562
570
|
requirements: []
|
563
|
-
rubygems_version: 3.
|
564
|
-
signing_key:
|
571
|
+
rubygems_version: 3.2.15
|
572
|
+
signing_key:
|
565
573
|
specification_version: 4
|
566
574
|
summary: Toolkit for file attachments in Ruby applications
|
567
575
|
test_files: []
|