Shrine 2.14.0
New features
Shrine::Storage::S3
now accepts a:client
option for specifying an AWS SDK client object. This allows the user to configure client-side encryption by passing aAws::S3::Encryption::Client
object:client = Aws::S3::Encryption::Client.new( kms_key_id: "alias/my-key", **options ) Shrine::Storage::S3.new(client: client, bucket: "my-bucket")
The metadata blocks in the
add_metadata
plugin now have previous metadata available to them incontext[:metadata]
(thanks to @jrochkind).add_metadata :foo do |io, context| context[:metadata] #=> # { # "filename" => "nature.jpg", # "size" => 123, # "mime_type" => "image/jpeg" # } "foo" end add_metadata :bar do |io, context| context[:metadata] #=> # { # "filename" => "nature.jpg", # "size" => 123, # "mime_type" => "image/jpeg", # "foo" => "foo" # } "bar" end
UploadedFile#to_rack_response
fromrack_response
plugin now accepts:type
and:filename
options for overriding the values in metadata that would otherwise be used for theContent-Type
andContent-Disposition
response headers.status, headers, body = uploaded_file.to_rack_response( type: "text/csv; charset=utf-8", filename: "export.csv", ) headers["Content-Type"] #=> "text/csv; charset=utf-8" headers["Content-Disposition"] #=> "inline; filename=\"export.csv\""
Shrine.data_uri
fromdata_uri
plugin now accepts a:filename
string, which will be returned inShrine::Plugins::DataUri::DataFile#original_filename
.io = Shrine.data_uri("data:,content", filename: "foo.txt") io.original_filename #=> "foo.txt"
UploadedFile#download_url
fromdownload_endpoint
plugin now accepts a:host
option. Previously it was only possible to configure the URL host on the plugin level.uploaded_file.download_url(host: "https://example.com")
Attacher#cached?
andAttacher#stored?
now accept an optional uploaded file parameter, and return whether the given uploaded file is uploaded to the temporary or permanent storage of the attacher (thanks to @jrochkind).
Performance improvements
UploadedFile#download
doesn't callStorage#download
anymore (onlyStorage#open
). This improves performance when the uploaded file is already opened, e.g. when usingrefresh_metadata
plugin andShrine.with_file
during metadata extraction. Instead of performing a new download request,UploadedFile#download
will in this case reuse the already opened IO object.Added
tempfile
plugin that makes it easier to avoid copying theUploadedFile
to disk multiple times during promotion. For example, in the following code the uploaded file will be downloaded to disk only once instead of three times.Shrine.plugin :tempfile
class MyUploader < Shrine plugin :processing plugin :add_metadata plugin :refresh_metadata process(:store) do |io, context| io.open do io.refresh_metadata! processor = ImageProcessing::Vips.source(io.tempfile) # ... processing ... end end add_metadata :foo do |io, context| Shrine.with_file(io) { "..." } unless context[:action] == :store end add_metadata :bar do |io, context| Shrine.with_file(io) { "..." } unless context[:action] == :store end end
UploadedFile#refresh_metadata!
fromrefresh_metadata
plugin now detects when the uploaded file is already opened and in that case doesn't re-open the file. This makes code like this faster:uploaded_file.open do uploaded_file.refresh_metadata! # doesn't re-open the file anymore end
The
rack_response
plugin now integrates withRack::Sendfile
middleware whenShrine::Storage::FileSystem
is used. It does so by making the response body respond to#to_path
.#<name>_attacher
doesn't look up the attachment class every time it's called with a new model instance anymore, making it slightly faster (thanks to @printercu).
Other improvements
The
lib/shrine.rb
file has been split intolib/shrine.rb
,lib/shrine/uploaded_file.rb
,lib/shrine/attacher.rb
,lib/shrine/attachment.rb
, andlib/shrine/plugins.rb
(thanks to @printercu).Shrine::Storage::S3
andrack_response
plugin now use the content_disposition gem for generating correctly formattedContent-Disposition
header values.The
S3#download
andS3#open
methods now work correctly with server-side encryption (as long as the necessary:sse_*
parameters are passed in).Fixed
FileSystem#clear!
not working with symlinks (at least on MRI).Fixed
add_metadata
plugin overriding previously defined metadata blocks when loaded again.Fixed
processing
plugin overriding previously defined processing blocks when loaded again.Fixed
backgrounding
plugin erroring when temorary/permanent storage is declared inShrine::Attachment.new
and there are no:cache
or:store
storages defined.Fixed
UploadedFile#extension
(and thus the tempfile inUploadedFile#download
) including URL query parameters in the file extension whenShrine::Storage::Url
is used (shrine-url
gem) with URLs that have query parameters (thanks to @jrochkind).Fixed
backgrounding
plugin aborting promotion when cached file metadata was refreshed in the processing block and Active Record JSON column was used.refresh_metadata
plugin now avoids mutating the uploaded file data hashbackgrounding
plugin now continues promotion if cached file metadata has changed
The
Shrine.data_uri
method from thedata_uri
plugin now picks up media type parameters from the data URI and includes them inShrine::Plugins::DataUri::DataFile#content_type
.io = Shrine.data_uri("data:text/plain;charset=utf-8,content") io.content_type #=> # BEFORE: "text/plain" # AFTER: "text/plain;charset=utf-8"
When fetching
mime_type
metadata value fromio.content_type
, any media type parameters are now stripped. This means that if the user uploads a text file with aContent-Type
oftext/plain; charset=utf-8
, themime_type
will now correctly be stored astext/plain
. This fixes any MIME type validations that might not have been passing due to additional media type parameters.When
determine_mime_type
plugin is loaded with the:default
analyzer, a warning is not printed anymore.When
Shrine::Storage::S3
is initialized withbucket: nil
, an appropriate error message is now raised.The
:content_type
MIME type analyzer has been added to theShrine.mime_type_analyzers
hash indetermine_mime_type
plugin (previously known as:default
).
Documentation
- The Retrieving Uploads guide has been added.
Backwards compatibility
Support for MRI 2.1 and MRI 2.2 has been dropped.
Shrine::Plugins::Base
module has been removed and contained modules have been moved toInstanceMethods
andClassMethods
modules inside the corresponding core classes. This should not break anything unless you were referencing those modules directly.Shrine::Plugins::Base::InstanceMethods => Shrine::InstanceMethods Shrine::Plugins::Base::ClassMethods => Shrine::ClassMethods Shrine::Plugins::Base::FileMethods => Shrine::UploadedFile::InstanceMethods Shrine::Plugins::Base::FileClassMethods => Shrine::UploadedFile::ClassMethods Shrine::Plugins::Base::AttacherMethods => Shrine::Attacher::InstanceMethods Shrine::Plugins::Base::AttacherClassMethods => Shrine::Attacher::ClassMethods Shrine::Plugins::Base::AttachmentMethods => Shrine::Attachment::InstanceMethods Shrine::Plugins::Base::AttachmentClassMethods => Shrine::Attachment::ClassMethods
UploadedFile#download
doesn't callStorage#download
anymore, it now always callsStorage#open
. SinceStorage#download
is not used anywhere else in Shrine, storages can remove the#download
method.Shrine::Storage::S3#download
has been deprecated and will be removed in Shrine 3.In
Shrine::Storage::S3#upload
,#open
, and#presign
it's now deprecated to pass theContent-Disposition
header value with non-ASCII characters. Starting with Shrine 3 these characters won't be escaped anymore. You should now use the content_disposition gem to properly format theContent-Disposition
header value.# BAD: plugin :default_url_options, store: -> (io, **options) do { response_content_disposition: "attachment; filename=\"#{io.original_filename}\"" } end # GOOD: plugin :default_url_options, store: -> (io, **options) do { response_content_disposition: ContentDisposition.attachment(io.original_filename) } end
The
mime_type
metadata value will now strip any additional media type parameters such ascharset
fromio.content_type
. If you were relying on this behaviour, you will need to update your code.In
determine_mime_type
plugin, the:default
MIME type analyzer has been renamed to:content_type
. The:default
alias will stop being supported in Shrine 3.plugin :determine_mime_type, analyzer: :default # should be changed to plugin :determine_mime_type, analyzer: :content_type
The
UploadedFile
private methods that were added by therack_response
plugin have now been moved to an internal class (leaving only#to_rack_response
). If you've are currently overriding any of these private methods, you'll need to update your code.The
UploadedFile
private methods that were added by thedownload_endpoint
plugin have now been moved to an internal class (leaving only#download_url
). If you've are currently overriding any of these private methods, you'll need to update your code.