shrine 3.6.0 → 3.7.1
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 +24 -0
- data/doc/changing_derivatives.md +2 -1
- data/doc/changing_location.md +17 -5
- data/doc/getting_started.md +4 -2
- data/doc/plugins/derivation_endpoint.md +15 -1
- data/doc/plugins/derivatives.md +2 -1
- data/doc/plugins/download_endpoint.md +16 -4
- data/doc/plugins/rack_response.md +9 -0
- data/doc/plugins/refresh_metadata.md +20 -0
- data/doc/plugins/signature.md +8 -6
- data/doc/processing.md +5 -3
- data/doc/release_notes/3.7.0.md +75 -0
- data/doc/release_notes/3.7.1.md +13 -0
- data/lib/shrine/attacher.rb +21 -21
- data/lib/shrine/attachment.rb +2 -2
- data/lib/shrine/plugins/_persistence.rb +1 -1
- data/lib/shrine/plugins/_urlsafe_serialization.rb +4 -4
- data/lib/shrine/plugins/add_metadata.rb +2 -4
- data/lib/shrine/plugins/atomic_helpers.rb +7 -7
- data/lib/shrine/plugins/backgrounding.rb +9 -9
- data/lib/shrine/plugins/column.rb +6 -4
- data/lib/shrine/plugins/data_uri.rb +1 -1
- data/lib/shrine/plugins/default_url.rb +4 -4
- data/lib/shrine/plugins/delete_raw.rb +2 -2
- data/lib/shrine/plugins/derivation_endpoint.rb +29 -27
- data/lib/shrine/plugins/derivatives.rb +5 -1
- data/lib/shrine/plugins/download_endpoint.rb +62 -10
- data/lib/shrine/plugins/entity.rb +7 -7
- data/lib/shrine/plugins/infer_extension.rb +1 -1
- data/lib/shrine/plugins/instrumentation.rb +8 -8
- data/lib/shrine/plugins/metadata_attributes.rb +1 -1
- data/lib/shrine/plugins/mirroring.rb +10 -10
- data/lib/shrine/plugins/model.rb +9 -9
- data/lib/shrine/plugins/presign_endpoint.rb +4 -4
- data/lib/shrine/plugins/pretty_location.rb +2 -2
- data/lib/shrine/plugins/processing.rb +3 -3
- data/lib/shrine/plugins/rack_file.rb +2 -2
- data/lib/shrine/plugins/rack_response.rb +6 -6
- data/lib/shrine/plugins/refresh_metadata.rb +6 -6
- data/lib/shrine/plugins/remote_url.rb +4 -4
- data/lib/shrine/plugins/restore_cached_data.rb +3 -3
- data/lib/shrine/plugins/signature.rb +2 -2
- data/lib/shrine/plugins/store_dimensions.rb +2 -2
- data/lib/shrine/plugins/upload_endpoint.rb +4 -4
- data/lib/shrine/plugins/upload_options.rb +1 -1
- data/lib/shrine/plugins/validation.rb +8 -8
- data/lib/shrine/plugins/validation_helpers.rb +1 -1
- data/lib/shrine/plugins/versions.rb +10 -10
- data/lib/shrine/plugins.rb +6 -14
- data/lib/shrine/storage/file_system.rb +4 -17
- data/lib/shrine/storage/linter.rb +8 -8
- data/lib/shrine/storage/memory.rb +1 -3
- data/lib/shrine/storage/s3.rb +45 -37
- data/lib/shrine/uploaded_file.rb +20 -18
- data/lib/shrine/version.rb +2 -2
- data/lib/shrine.rb +18 -18
- data/shrine.gemspec +6 -6
- metadata +16 -17
data/lib/shrine/storage/s3.rb
CHANGED
|
@@ -68,10 +68,11 @@ class Shrine
|
|
|
68
68
|
# [`Aws::S3::Bucket#presigned_post`]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_post-instance_method
|
|
69
69
|
# [`Aws::S3::Client#initialize`]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#initialize-instance_method
|
|
70
70
|
# [configuring AWS SDK]: https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html
|
|
71
|
-
def initialize(bucket:, client: nil, prefix: nil, upload_options: {}, multipart_threshold: {}, max_multipart_parts: nil, signer: nil, public: nil, copy_options: COPY_OPTIONS, **
|
|
71
|
+
def initialize(bucket:, client: nil, prefix: nil, upload_options: {}, multipart_threshold: {}, max_multipart_parts: nil, signer: nil, public: nil, copy_options: COPY_OPTIONS, **)
|
|
72
72
|
raise ArgumentError, "the :bucket option is nil" unless bucket
|
|
73
73
|
|
|
74
|
-
@client = client || Aws::S3::Client.new(**
|
|
74
|
+
@client = client || Aws::S3::Client.new(**)
|
|
75
|
+
@transfer_manager = Aws::S3::TransferManager.new(client: @client) if defined?(Aws::S3::TransferManager)
|
|
75
76
|
@bucket = Aws::S3::Bucket.new(name: bucket, client: @client)
|
|
76
77
|
@prefix = prefix
|
|
77
78
|
@upload_options = upload_options
|
|
@@ -97,8 +98,7 @@ class Shrine
|
|
|
97
98
|
options[:content_disposition] = ContentDisposition.inline(filename) if filename
|
|
98
99
|
options[:acl] = "public-read" if public
|
|
99
100
|
|
|
100
|
-
options.merge!(@upload_options)
|
|
101
|
-
options.merge!(upload_options)
|
|
101
|
+
options.merge!(@upload_options, upload_options)
|
|
102
102
|
|
|
103
103
|
if copyable?(io)
|
|
104
104
|
copy(io, id, **options)
|
|
@@ -116,8 +116,8 @@ class Shrine
|
|
|
116
116
|
# Any additional options are forwarded to [`Aws::S3::Object#get`].
|
|
117
117
|
#
|
|
118
118
|
# [`Aws::S3::Object#get`]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#get-instance_method
|
|
119
|
-
def open(id, rewindable: true, encoding: nil, **
|
|
120
|
-
chunks, length = get(id, **
|
|
119
|
+
def open(id, rewindable: true, encoding: nil, **)
|
|
120
|
+
chunks, length = get(id, **)
|
|
121
121
|
|
|
122
122
|
Down::ChunkedIO.new(chunks: chunks, rewindable: rewindable, size: length, encoding: encoding)
|
|
123
123
|
rescue Aws::S3::Errors::NoSuchKey
|
|
@@ -145,11 +145,11 @@ class Shrine
|
|
|
145
145
|
#
|
|
146
146
|
# [`Aws::S3::Object#presigned_url`]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_url-instance_method
|
|
147
147
|
# [`Aws::S3::Object#public_url`]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#public_url-instance_method
|
|
148
|
-
def url(id, public: self.public, host: nil, **
|
|
148
|
+
def url(id, public: self.public, host: nil, **)
|
|
149
149
|
if public || signer
|
|
150
|
-
url = object(id).public_url(**
|
|
150
|
+
url = object(id).public_url(**)
|
|
151
151
|
else
|
|
152
|
-
url = object(id).presigned_url(:get, **
|
|
152
|
+
url = object(id).presigned_url(:get, **)
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
if host
|
|
@@ -159,7 +159,7 @@ class Shrine
|
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
if signer
|
|
162
|
-
url = signer.call(url, **
|
|
162
|
+
url = signer.call(url, **)
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
url
|
|
@@ -190,8 +190,7 @@ class Shrine
|
|
|
190
190
|
options = {}
|
|
191
191
|
options[:acl] = "public-read" if public
|
|
192
192
|
|
|
193
|
-
options.merge!(@upload_options)
|
|
194
|
-
options.merge!(presign_options)
|
|
193
|
+
options.merge!(@upload_options, presign_options)
|
|
195
194
|
|
|
196
195
|
send(:"presign_#{method}", id, options)
|
|
197
196
|
end
|
|
@@ -231,12 +230,21 @@ class Shrine
|
|
|
231
230
|
|
|
232
231
|
private
|
|
233
232
|
|
|
234
|
-
#
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
233
|
+
# Upload the file to S3.
|
|
234
|
+
# Uses @transfer_manager, if defined, for any size upload.
|
|
235
|
+
# Falls back to the original code using the older, now depricated
|
|
236
|
+
# AWS APIs for users of older version of the AWS Gem.
|
|
237
|
+
# for multipart uploads of large files.
|
|
238
|
+
def put(io, id, **)
|
|
239
|
+
if @transfer_manager
|
|
240
|
+
@transfer_manager.upload_stream(bucket: bucket.name, key: object_key(id), part_size: part_size(io), **) do |write_stream|
|
|
241
|
+
IO.copy_stream(io, write_stream)
|
|
242
|
+
end
|
|
243
|
+
elsif io.respond_to?(:size) && io.size && io.size <= @multipart_threshold[:upload]
|
|
244
|
+
object(id).put(body: io, **)
|
|
245
|
+
else
|
|
246
|
+
# multipart upload old API
|
|
247
|
+
object(id).upload_stream(part_size: part_size(io), **) do |write_stream|
|
|
240
248
|
IO.copy_stream(io, write_stream)
|
|
241
249
|
end
|
|
242
250
|
end
|
|
@@ -255,8 +263,7 @@ class Shrine
|
|
|
255
263
|
options.merge!(multipart_copy: true, content_length: io.size)
|
|
256
264
|
end
|
|
257
265
|
|
|
258
|
-
options.merge!(@copy_options)
|
|
259
|
-
options.merge!(copy_options)
|
|
266
|
+
options.merge!(@copy_options, copy_options)
|
|
260
267
|
|
|
261
268
|
object(id).copy_from(io.storage.object(io.id), **options)
|
|
262
269
|
end
|
|
@@ -274,13 +281,14 @@ class Shrine
|
|
|
274
281
|
|
|
275
282
|
# When any of these options are specified, the corresponding request
|
|
276
283
|
# headers must be included in the upload request.
|
|
277
|
-
headers = {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
+
headers = {
|
|
285
|
+
"Content-Length" => options[:content_length],
|
|
286
|
+
"Content-Type" => options[:content_type],
|
|
287
|
+
"Content-Disposition" => options[:content_disposition],
|
|
288
|
+
"Content-Encoding" => options[:content_encoding],
|
|
289
|
+
"Content-Language" => options[:content_language],
|
|
290
|
+
"Content-MD5" => options[:content_md5],
|
|
291
|
+
}.compact
|
|
284
292
|
|
|
285
293
|
{ method: :put, url: url, headers: headers }
|
|
286
294
|
end
|
|
@@ -301,8 +309,8 @@ class Shrine
|
|
|
301
309
|
# object before all content is downloaded, so we hack our way around it.
|
|
302
310
|
# This way get the content length without an additional HEAD request.
|
|
303
311
|
if Gem::Version.new(Aws::CORE_GEM_VERSION) >= Gem::Version.new("3.104.0")
|
|
304
|
-
def get(id, **
|
|
305
|
-
enum = object(id).enum_for(:get, **
|
|
312
|
+
def get(id, **)
|
|
313
|
+
enum = object(id).enum_for(:get, **)
|
|
306
314
|
|
|
307
315
|
begin
|
|
308
316
|
content_length = Integer(enum.peek.last["content-length"])
|
|
@@ -315,8 +323,8 @@ class Shrine
|
|
|
315
323
|
[chunks, content_length]
|
|
316
324
|
end
|
|
317
325
|
else
|
|
318
|
-
def get(id, **
|
|
319
|
-
req = client.build_request(:get_object, bucket: bucket.name, key: object_key(id), **
|
|
326
|
+
def get(id, **)
|
|
327
|
+
req = client.build_request(:get_object, bucket: bucket.name, key: object_key(id), **)
|
|
320
328
|
|
|
321
329
|
body = req.enum_for(:send_request)
|
|
322
330
|
begin
|
|
@@ -359,10 +367,10 @@ class Shrine
|
|
|
359
367
|
|
|
360
368
|
# Save the encryption client and continue initialization with normal
|
|
361
369
|
# client.
|
|
362
|
-
def initialize(client: nil, **
|
|
370
|
+
def initialize(client: nil, **)
|
|
363
371
|
return super unless client.class.name.start_with?("Aws::S3::Encryption")
|
|
364
372
|
|
|
365
|
-
super(client: client.client, **
|
|
373
|
+
super(client: client.client, **)
|
|
366
374
|
@encryption_client = client
|
|
367
375
|
end
|
|
368
376
|
|
|
@@ -370,19 +378,19 @@ class Shrine
|
|
|
370
378
|
|
|
371
379
|
# Encryption client doesn't support multipart uploads, so we always use
|
|
372
380
|
# #put_object.
|
|
373
|
-
def put(io, id, **
|
|
381
|
+
def put(io, id, **)
|
|
374
382
|
return super unless encryption_client
|
|
375
383
|
|
|
376
|
-
encryption_client.put_object(body: io, bucket: bucket.name, key: object_key(id), **
|
|
384
|
+
encryption_client.put_object(body: io, bucket: bucket.name, key: object_key(id), **)
|
|
377
385
|
end
|
|
378
386
|
|
|
379
|
-
def get(id, **
|
|
387
|
+
def get(id, **)
|
|
380
388
|
return super unless encryption_client
|
|
381
389
|
|
|
382
390
|
# Encryption client v2 warns against streaming download, so we first
|
|
383
391
|
# download all content into a file.
|
|
384
392
|
tempfile = Tempfile.new("shrine-s3", binmode: true)
|
|
385
|
-
response = encryption_client.get_object(response_target: tempfile, bucket: bucket.name, key: object_key(id), **
|
|
393
|
+
response = encryption_client.get_object(response_target: tempfile, bucket: bucket.name, key: object_key(id), **)
|
|
386
394
|
tempfile.rewind
|
|
387
395
|
|
|
388
396
|
chunks = Enumerator.new do |yielder|
|
data/lib/shrine/uploaded_file.rb
CHANGED
|
@@ -22,6 +22,8 @@ class Shrine
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
module InstanceMethods
|
|
25
|
+
RFC2396_PARSER = URI::RFC2396_Parser.new
|
|
26
|
+
|
|
25
27
|
# The location where the file was uploaded to the storage.
|
|
26
28
|
attr_reader :id
|
|
27
29
|
|
|
@@ -50,7 +52,7 @@ class Shrine
|
|
|
50
52
|
# The extension derived from #id if present, otherwise it's derived
|
|
51
53
|
# from #original_filename.
|
|
52
54
|
def extension
|
|
53
|
-
identifier = id =~
|
|
55
|
+
identifier = id =~ RFC2396_PARSER.make_regexp ? id.sub(/\?.+$/, "") : id # strip query params for shrine-url
|
|
54
56
|
result = File.extname(identifier)[1..-1]
|
|
55
57
|
result ||= File.extname(original_filename.to_s)[1..-1]
|
|
56
58
|
result.downcase if result
|
|
@@ -89,9 +91,9 @@ class Shrine
|
|
|
89
91
|
# # or
|
|
90
92
|
#
|
|
91
93
|
# uploaded_file.open { |io| io.read } # the IO is automatically closed
|
|
92
|
-
def open(**
|
|
94
|
+
def open(**)
|
|
93
95
|
@io.close if @io
|
|
94
|
-
@io = _open(**
|
|
96
|
+
@io = _open(**)
|
|
95
97
|
|
|
96
98
|
return @io unless block_given?
|
|
97
99
|
|
|
@@ -118,9 +120,9 @@ class Shrine
|
|
|
118
120
|
# # or
|
|
119
121
|
#
|
|
120
122
|
# uploaded_file.download { |tempfile| tempfile.read } # tempfile is deleted
|
|
121
|
-
def download(**
|
|
123
|
+
def download(**)
|
|
122
124
|
tempfile = Tempfile.new(["shrine", ".#{extension}"], binmode: true)
|
|
123
|
-
stream(tempfile, **
|
|
125
|
+
stream(tempfile, **)
|
|
124
126
|
tempfile.open
|
|
125
127
|
|
|
126
128
|
block_given? ? yield(tempfile) : tempfile
|
|
@@ -139,19 +141,19 @@ class Shrine
|
|
|
139
141
|
# uploaded_file.stream(StringIO.new)
|
|
140
142
|
# # or
|
|
141
143
|
# uploaded_file.stream("/path/to/destination")
|
|
142
|
-
def stream(destination, **
|
|
144
|
+
def stream(destination, **)
|
|
143
145
|
if opened?
|
|
144
146
|
IO.copy_stream(io, destination)
|
|
145
147
|
io.rewind
|
|
146
148
|
else
|
|
147
|
-
open(**
|
|
149
|
+
open(**) { |io| IO.copy_stream(io, destination) }
|
|
148
150
|
end
|
|
149
151
|
end
|
|
150
152
|
|
|
151
153
|
# Part of complying to the IO interface. It delegates to the internally
|
|
152
154
|
# opened IO object.
|
|
153
|
-
def read(*
|
|
154
|
-
io.read(*
|
|
155
|
+
def read(*)
|
|
156
|
+
io.read(*)
|
|
155
157
|
end
|
|
156
158
|
|
|
157
159
|
# Part of complying to the IO interface. It delegates to the internally
|
|
@@ -179,8 +181,8 @@ class Shrine
|
|
|
179
181
|
end
|
|
180
182
|
|
|
181
183
|
# Calls `#url` on the storage, forwarding any given URL options.
|
|
182
|
-
def url(**
|
|
183
|
-
storage.url(id, **
|
|
184
|
+
def url(**)
|
|
185
|
+
storage.url(id, **)
|
|
184
186
|
end
|
|
185
187
|
|
|
186
188
|
# Calls `#exists?` on the storage, which checks whether the file exists
|
|
@@ -190,8 +192,8 @@ class Shrine
|
|
|
190
192
|
end
|
|
191
193
|
|
|
192
194
|
# Uploads a new file to this file's location and returns it.
|
|
193
|
-
def replace(io, **
|
|
194
|
-
uploader.upload(io,
|
|
195
|
+
def replace(io, **)
|
|
196
|
+
uploader.upload(io, **, location: id)
|
|
195
197
|
end
|
|
196
198
|
|
|
197
199
|
# Calls `#delete` on the storage, which deletes the file from the
|
|
@@ -207,12 +209,12 @@ class Shrine
|
|
|
207
209
|
|
|
208
210
|
# Returns the data hash in the JSON format. Suitable for storing in a
|
|
209
211
|
# database column or passing to a background job.
|
|
210
|
-
def to_json(*
|
|
211
|
-
data.to_json(*
|
|
212
|
+
def to_json(*)
|
|
213
|
+
data.to_json(*)
|
|
212
214
|
end
|
|
213
215
|
|
|
214
216
|
# Conform to ActiveSupport's JSON interface.
|
|
215
|
-
def as_json(*
|
|
217
|
+
def as_json(*)
|
|
216
218
|
data
|
|
217
219
|
end
|
|
218
220
|
|
|
@@ -263,8 +265,8 @@ class Shrine
|
|
|
263
265
|
@io ||= _open
|
|
264
266
|
end
|
|
265
267
|
|
|
266
|
-
def _open(**
|
|
267
|
-
storage.open(id, **
|
|
268
|
+
def _open(**)
|
|
269
|
+
storage.open(id, **)
|
|
268
270
|
end
|
|
269
271
|
end
|
|
270
272
|
|
data/lib/shrine/version.rb
CHANGED
data/lib/shrine.rb
CHANGED
|
@@ -68,9 +68,9 @@ class Shrine
|
|
|
68
68
|
#
|
|
69
69
|
# Shrine.plugin MyPlugin
|
|
70
70
|
# Shrine.plugin :my_plugin
|
|
71
|
-
def plugin(plugin,
|
|
71
|
+
def plugin(plugin, ...)
|
|
72
72
|
plugin = Plugins.load_plugin(plugin) if plugin.is_a?(Symbol)
|
|
73
|
-
Plugins.load_dependencies(plugin, self,
|
|
73
|
+
Plugins.load_dependencies(plugin, self, ...)
|
|
74
74
|
self.include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
|
|
75
75
|
self.extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
|
|
76
76
|
self::UploadedFile.include(plugin::FileMethods) if defined?(plugin::FileMethods)
|
|
@@ -79,7 +79,7 @@ class Shrine
|
|
|
79
79
|
self::Attachment.extend(plugin::AttachmentClassMethods) if defined?(plugin::AttachmentClassMethods)
|
|
80
80
|
self::Attacher.include(plugin::AttacherMethods) if defined?(plugin::AttacherMethods)
|
|
81
81
|
self::Attacher.extend(plugin::AttacherClassMethods) if defined?(plugin::AttacherClassMethods)
|
|
82
|
-
Plugins.configure(plugin, self,
|
|
82
|
+
Plugins.configure(plugin, self, ...)
|
|
83
83
|
plugin
|
|
84
84
|
end
|
|
85
85
|
|
|
@@ -95,8 +95,8 @@ class Shrine
|
|
|
95
95
|
# class Photo
|
|
96
96
|
# include Shrine::Attachment(:image) # creates a Shrine::Attachment object
|
|
97
97
|
# end
|
|
98
|
-
def Attachment(name, **
|
|
99
|
-
self::Attachment.new(name, **
|
|
98
|
+
def Attachment(name, **)
|
|
99
|
+
self::Attachment.new(name, **)
|
|
100
100
|
end
|
|
101
101
|
alias attachment Attachment
|
|
102
102
|
alias [] Attachment
|
|
@@ -104,8 +104,8 @@ class Shrine
|
|
|
104
104
|
# Uploads the file to the specified storage. It delegates to `Shrine#upload`.
|
|
105
105
|
#
|
|
106
106
|
# Shrine.upload(io, :store) #=> #<Shrine::UploadedFile>
|
|
107
|
-
def upload(io, storage, **
|
|
108
|
-
new(storage).upload(io, **
|
|
107
|
+
def upload(io, storage, **)
|
|
108
|
+
new(storage).upload(io, **)
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
# Instantiates a Shrine::UploadedFile from a hash, and optionally
|
|
@@ -201,13 +201,13 @@ class Shrine
|
|
|
201
201
|
# uploader.upload(io, metadata: { "foo" => "bar" }) # add metadata
|
|
202
202
|
# uploader.upload(io, location: "path/to/file") # specify location
|
|
203
203
|
# uploader.upload(io, upload_options: { acl: "public-read" }) # add upload options
|
|
204
|
-
def upload(io, **
|
|
204
|
+
def upload(io, **)
|
|
205
205
|
_enforce_io(io)
|
|
206
206
|
|
|
207
|
-
metadata = get_metadata(io, **
|
|
208
|
-
location = get_location(io,
|
|
207
|
+
metadata = get_metadata(io, **)
|
|
208
|
+
location = get_location(io, **, metadata:)
|
|
209
209
|
|
|
210
|
-
_upload(io,
|
|
210
|
+
_upload(io, **, location:, metadata:)
|
|
211
211
|
|
|
212
212
|
self.class::UploadedFile.new(
|
|
213
213
|
id: location,
|
|
@@ -219,13 +219,13 @@ class Shrine
|
|
|
219
219
|
# Generates a unique location for the uploaded file, preserving the
|
|
220
220
|
# file extension. Can be overriden in uploaders for generating custom
|
|
221
221
|
# location.
|
|
222
|
-
def generate_location(io, metadata: {}, **
|
|
223
|
-
basic_location(io, metadata:
|
|
222
|
+
def generate_location(io, metadata: {}, **)
|
|
223
|
+
basic_location(io, metadata:)
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
# Extracts filename, size and MIME type from the file, which is later
|
|
227
227
|
# accessible through UploadedFile#metadata.
|
|
228
|
-
def extract_metadata(io, **
|
|
228
|
+
def extract_metadata(io, **)
|
|
229
229
|
{
|
|
230
230
|
"filename" => extract_filename(io),
|
|
231
231
|
"size" => extract_size(io),
|
|
@@ -281,11 +281,11 @@ class Shrine
|
|
|
281
281
|
|
|
282
282
|
# If the IO object is a Shrine::UploadedFile, it simply copies over its
|
|
283
283
|
# metadata, otherwise it calls #extract_metadata.
|
|
284
|
-
def get_metadata(io, metadata: nil, **
|
|
284
|
+
def get_metadata(io, metadata: nil, **)
|
|
285
285
|
if io.is_a?(UploadedFile) && metadata != true
|
|
286
286
|
result = io.metadata.dup
|
|
287
287
|
elsif metadata != false
|
|
288
|
-
result = extract_metadata(io, **
|
|
288
|
+
result = extract_metadata(io, **)
|
|
289
289
|
else
|
|
290
290
|
result = {}
|
|
291
291
|
end
|
|
@@ -296,8 +296,8 @@ class Shrine
|
|
|
296
296
|
|
|
297
297
|
# Retrieves the location for the given IO and context. First it looks
|
|
298
298
|
# for the `:location` option, otherwise it calls #generate_location.
|
|
299
|
-
def get_location(io, location: nil, **
|
|
300
|
-
location ||= generate_location(io, **
|
|
299
|
+
def get_location(io, location: nil, **)
|
|
300
|
+
location ||= generate_location(io, **)
|
|
301
301
|
location or fail Error, "location generated for #{io.inspect} was nil"
|
|
302
302
|
end
|
|
303
303
|
|
data/shrine.gemspec
CHANGED
|
@@ -4,7 +4,7 @@ Gem::Specification.new do |gem|
|
|
|
4
4
|
gem.name = "shrine"
|
|
5
5
|
gem.version = Shrine.version
|
|
6
6
|
|
|
7
|
-
gem.required_ruby_version = ">= 2
|
|
7
|
+
gem.required_ruby_version = ">= 3.2"
|
|
8
8
|
|
|
9
9
|
gem.summary = "Toolkit for file attachments in Ruby applications"
|
|
10
10
|
gem.description = <<-END
|
|
@@ -38,7 +38,7 @@ direct uploads for fully asynchronous user experience.
|
|
|
38
38
|
|
|
39
39
|
# general testing helpers
|
|
40
40
|
gem.add_development_dependency "rake", ">= 11.1"
|
|
41
|
-
gem.add_development_dependency "minitest", "~>
|
|
41
|
+
gem.add_development_dependency "minitest", "~> 6.0"
|
|
42
42
|
gem.add_development_dependency "mocha", "~> 1.11"
|
|
43
43
|
|
|
44
44
|
# for endpoint plugins
|
|
@@ -57,7 +57,7 @@ direct uploads for fully asynchronous user experience.
|
|
|
57
57
|
|
|
58
58
|
# for store_dimensions plugin
|
|
59
59
|
gem.add_development_dependency "fastimage"
|
|
60
|
-
gem.add_development_dependency "mini_magick", "~>
|
|
60
|
+
gem.add_development_dependency "mini_magick", "~> 5.0" unless ENV["CI"]
|
|
61
61
|
gem.add_development_dependency "ruby-vips", "~> 2.0" unless ENV["CI"]
|
|
62
62
|
|
|
63
63
|
# for S3 storage
|
|
@@ -67,10 +67,10 @@ direct uploads for fully asynchronous user experience.
|
|
|
67
67
|
|
|
68
68
|
# for instrumentation plugin
|
|
69
69
|
gem.add_development_dependency "dry-monitor"
|
|
70
|
-
gem.add_development_dependency "activesupport",
|
|
70
|
+
gem.add_development_dependency "activesupport", RUBY_ENGINE == "jruby" ? "~> 7.2" : "~> 8.1"
|
|
71
71
|
|
|
72
72
|
# for ORM plugins
|
|
73
73
|
gem.add_development_dependency "sequel"
|
|
74
|
-
gem.add_development_dependency "activerecord", RUBY_ENGINE == "jruby" ? "~> 7.
|
|
75
|
-
gem.add_development_dependency "sqlite3", "~> 1
|
|
74
|
+
gem.add_development_dependency "activerecord", RUBY_ENGINE == "jruby" ? "~> 7.2" : "~> 8.1"
|
|
75
|
+
gem.add_development_dependency "sqlite3", "~> 2.1" unless RUBY_ENGINE == "jruby"
|
|
76
76
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shrine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Janko Marohnić
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: down
|
|
@@ -58,14 +57,14 @@ dependencies:
|
|
|
58
57
|
requirements:
|
|
59
58
|
- - "~>"
|
|
60
59
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
60
|
+
version: '6.0'
|
|
62
61
|
type: :development
|
|
63
62
|
prerelease: false
|
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
64
|
requirements:
|
|
66
65
|
- - "~>"
|
|
67
66
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
67
|
+
version: '6.0'
|
|
69
68
|
- !ruby/object:Gem::Dependency
|
|
70
69
|
name: mocha
|
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -218,14 +217,14 @@ dependencies:
|
|
|
218
217
|
requirements:
|
|
219
218
|
- - "~>"
|
|
220
219
|
- !ruby/object:Gem::Version
|
|
221
|
-
version: '
|
|
220
|
+
version: '5.0'
|
|
222
221
|
type: :development
|
|
223
222
|
prerelease: false
|
|
224
223
|
version_requirements: !ruby/object:Gem::Requirement
|
|
225
224
|
requirements:
|
|
226
225
|
- - "~>"
|
|
227
226
|
- !ruby/object:Gem::Version
|
|
228
|
-
version: '
|
|
227
|
+
version: '5.0'
|
|
229
228
|
- !ruby/object:Gem::Dependency
|
|
230
229
|
name: ruby-vips
|
|
231
230
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -302,14 +301,14 @@ dependencies:
|
|
|
302
301
|
requirements:
|
|
303
302
|
- - "~>"
|
|
304
303
|
- !ruby/object:Gem::Version
|
|
305
|
-
version: '
|
|
304
|
+
version: '8.1'
|
|
306
305
|
type: :development
|
|
307
306
|
prerelease: false
|
|
308
307
|
version_requirements: !ruby/object:Gem::Requirement
|
|
309
308
|
requirements:
|
|
310
309
|
- - "~>"
|
|
311
310
|
- !ruby/object:Gem::Version
|
|
312
|
-
version: '
|
|
311
|
+
version: '8.1'
|
|
313
312
|
- !ruby/object:Gem::Dependency
|
|
314
313
|
name: sequel
|
|
315
314
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -330,28 +329,28 @@ dependencies:
|
|
|
330
329
|
requirements:
|
|
331
330
|
- - "~>"
|
|
332
331
|
- !ruby/object:Gem::Version
|
|
333
|
-
version: '
|
|
332
|
+
version: '8.1'
|
|
334
333
|
type: :development
|
|
335
334
|
prerelease: false
|
|
336
335
|
version_requirements: !ruby/object:Gem::Requirement
|
|
337
336
|
requirements:
|
|
338
337
|
- - "~>"
|
|
339
338
|
- !ruby/object:Gem::Version
|
|
340
|
-
version: '
|
|
339
|
+
version: '8.1'
|
|
341
340
|
- !ruby/object:Gem::Dependency
|
|
342
341
|
name: sqlite3
|
|
343
342
|
requirement: !ruby/object:Gem::Requirement
|
|
344
343
|
requirements:
|
|
345
344
|
- - "~>"
|
|
346
345
|
- !ruby/object:Gem::Version
|
|
347
|
-
version: '1
|
|
346
|
+
version: '2.1'
|
|
348
347
|
type: :development
|
|
349
348
|
prerelease: false
|
|
350
349
|
version_requirements: !ruby/object:Gem::Requirement
|
|
351
350
|
requirements:
|
|
352
351
|
- - "~>"
|
|
353
352
|
- !ruby/object:Gem::Version
|
|
354
|
-
version: '1
|
|
353
|
+
version: '2.1'
|
|
355
354
|
description: |
|
|
356
355
|
Shrine is a toolkit for file attachments in Ruby applications. It supports
|
|
357
356
|
uploading, downloading, processing and deleting IO objects, backed by various
|
|
@@ -482,6 +481,8 @@ files:
|
|
|
482
481
|
- doc/release_notes/3.4.0.md
|
|
483
482
|
- doc/release_notes/3.5.0.md
|
|
484
483
|
- doc/release_notes/3.6.0.md
|
|
484
|
+
- doc/release_notes/3.7.0.md
|
|
485
|
+
- doc/release_notes/3.7.1.md
|
|
485
486
|
- doc/retrieving_uploads.md
|
|
486
487
|
- doc/securing_uploads.md
|
|
487
488
|
- doc/storage/file_system.md
|
|
@@ -561,7 +562,6 @@ metadata:
|
|
|
561
562
|
documentation_uri: https://shrinerb.com
|
|
562
563
|
mailing_list_uri: https://discourse.shrinerb.com
|
|
563
564
|
source_code_uri: https://github.com/shrinerb/shrine
|
|
564
|
-
post_install_message:
|
|
565
565
|
rdoc_options: []
|
|
566
566
|
require_paths:
|
|
567
567
|
- lib
|
|
@@ -569,15 +569,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
569
569
|
requirements:
|
|
570
570
|
- - ">="
|
|
571
571
|
- !ruby/object:Gem::Version
|
|
572
|
-
version: '2
|
|
572
|
+
version: '3.2'
|
|
573
573
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
574
574
|
requirements:
|
|
575
575
|
- - ">="
|
|
576
576
|
- !ruby/object:Gem::Version
|
|
577
577
|
version: '0'
|
|
578
578
|
requirements: []
|
|
579
|
-
rubygems_version: 3.
|
|
580
|
-
signing_key:
|
|
579
|
+
rubygems_version: 3.6.9
|
|
581
580
|
specification_version: 4
|
|
582
581
|
summary: Toolkit for file attachments in Ruby applications
|
|
583
582
|
test_files: []
|