title: Shrine 2.6.0

New plugins

Shrine.plugin :signature

Shrine.calculate_signature(io, :md5)
#=> "8c7dd922ad47494fc02c388e12c00eac"

Shrine.calculate_signature(io, :md5, format: :base64)
#=> "jH3ZIq1HSU/ALDiOEsAOrA==\n"

You can then easily create a new metadata field with the calculated hash:

Shrine.plugin :signature
Shrine.plugin :add_metadata

MyUploader.add_metadata :md5 do |io, context|
  calculate_signature(io, :md5)
end
Shrine.plugin :metadata_attributes

# Syncs `size` metadata to `#<attachment>_size` record attribute, and
# `mime_type` metadata to `#<attachment>_type` record attribute.
Shrine::Attacher.metadata_attributes :size => :size, :mime_type => :type

# ...

user.avatar = image
user.avatar.metadata["size"]      #=> 95724
user.avatar_size                  #=> 95724
user.avatar.metadata["mime_type"] #=> "image/jpeg"
user.avatar_type                  #=> "image/jpeg"

user.avatar = nil
user.avatar_size #=> nil
user.avatar_type #=> nil
Shrine.plugin :refresh_metadata

# ...

uploaded_file.refresh_metadata!
uploaded_file.metadata # re-extracted metadata

New features

Shrine.plugin :determine_mime_type

Shrine.determine_mime_type(io) # calls the defined analyzer
#=> "image/jpeg"

Shrine.mime_type_analyzers[:file].call(io) # calls a built-in analyzer
#=> "image/jpeg"
Shrine.plugin :store_dimensions

Shrine.extract_dimensions(io) # calls the defined analyzer
#=> [300, 400]

Shrine.dimensions_analyzers[:fastimage].call(io) # calls a built-in analyzer
#=> [300, 400]
Shrine.plugin :data_uri

io = Shrine.data_uri("data:image/png;base64,9kfg07a80ihtiort87t85")
io.content_type #=> "image/png"
io.size         #=> 482
Shrine.plugin :rack_file

file_hash #=>
# {
#   :name => "file",
#   :filename => "cats.png",
#   :type => "image/png",
#   :tempfile => #<Tempfile:/var/folders/3n/3asd/-Tmp-/RackMultipart201-1476-nfw2-0>,
#   :head => "Content-Disposition: form-data; ...",
# }

io = Shrine.rack_file(file_hash)
io.original_filename #=> "cats.png"
io.content_type      #=> "image/png"
io.size              #=> 58342

Performance improvements

Other improvements

s3.object("image.jpg") #=> #<Aws::S3::Object bucket_name="your-bucket" key="image.jpg">
filesystem.path("image.jpg") #=> #<Pathname:public/image.jpg>

Backwards compatibility

# deprecated
validate_mime_type_inclusion [/image\//]
validate_extension_inclusion [/jpe?g/]

# use strings instead
validate_mime_type_inclusion %w[image/jpeg image/png image/gif ...]
validate_extension_inclusion %w[jpg jpeg png gif ...]
if validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
  validate_max_width 1000
  validate_max_height 1000
end