Skip to main content

Shrine 2.19.0

New features

  • A new instrumentation plugin has been added. It sends and logs events for various Shrine operations, and provides an API for other plugins to send and log their own events.

    Shrine.plugin :instrumentation
    
    uploaded_file = Shrine.upload(io, :store)
    uploaded_file.exists?
    uploaded_file.download
    uploaded_file.delete
    Metadata (32ms) – {:storage=>:store, :io=>StringIO, :uploader=>Shrine}
    Upload (1523ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :io=>StringIO, :upload_options=>{}, :uploader=>Shrine}
    Exists (755ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :uploader=>Shrine}
    Download (1002ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :download_options=>{}, :uploader=>Shrine}
    Delete (700ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :uploader=>Shrine}

    It supports ActiveSupport::Notifications (default) and dry-monitor notification backends out of the box.

    require "dry-monitor"
    
    Shrine.plugin :instrumentation, notifications: Dry::Monitor::Notifications.new(:test)
  • Metadata extraction can now be skipped during the upload by passing metadata: false to the uploader. This is useful in tests, where you might want to skip any potentially expensive metadata extraction while creating test data.

    uploaded_file = uploader.upload(io, metadata: false) # skips metadata extraction
    uploaded_file.metadata #=> {}
  • Metadata extraction can now be forced during the upload of a Shrine::UploadedFile object by passing metadata: true to the uploader.

    uploaded_file = uploader.upload(another_uploaded_file, metadata: true) # forces metadata extraction
    uploaded_file.metadata #=> re-extracted metadata
  • The pretty_location plugin now supports specifying a different identifier.

    plugin :pretty_location, identifier: "uuid"
    # "user/aa357797-5845-451b-8662-08eecdc9f762/profile_picture/493g82jf23.jpg"
    
    plugin :pretty_location, identifier: :email
    # "user/foo@bar.com/profile_picture/493g82jf23.jpg"
  • The store_dimensions plugin has gained an :on_error option for specifying how to react when an error occurrs while extracting dimensions.

    plugin :store_dimensions, on_error: :warn        # prints a warning message (default)
    plugin :store_dimensions, on_error: :fail        # raises the exception
    plugin :store_dimensions, on_error: :ignore      # ignores the exception
    plugin :store_dimensions, on_error: -> (error) { # custom handler
      # report the exception to your exception handler
    }
  • The FileSystem#upload method now accepts a :move option for moving the file instead of copying it. This is now preferred over the moving plugin.

    uploader.upload(file, move: true)
    File.exist?(file.path) #=> false
  • The FileSystem#clear! method can now take a block for more control over which files should be deleted.

    file_system.clear! { |path| path.mtime < Time.now - 7*24*60*60 } # delete files older than 1 week

Other improvements

  • Registering storage objects under string keys now works again (this got broken in version 2.18.0).

  • Several plugins now add their own instrumentation when the instrumentation plugin has been loaded:

    PluginInstrumentation
    derivation_endpointinstruments file processing
    determine_mime_typeinstruments analyzing MIME type
    store_dimensionsinstruments extracting image dimensions
    signatureinstruments calculating signature
    infer_extensioninstruments inferring extension
    remote_urlinstruments remote URL downloading
    data_uriinstruments data URI parsing
  • Shrine.logger has been added, and any warnings or other messages (such as from the instrumentation plugin) now go through it. This way you can change the logging destination:

    # log messages into the Rails logger
    Shrine.logger = Rails.logger
  • The store_dimensions plugin now prints warnings by default when extracting dimensions failed.

  • The pretty_location plugin now comes with a #pretty_location method which you can call for customization.

    def generate_location(io, record: nil, **context)
      identifier = record.email if record.is_a?(User)
      pretty_location(io, record: record, identifier: identifier, **context)
    end
  • The Shrine::UploadedFile#[] operator has been added for easier metadata retrieving.

    uploaded_file.metadata["duration"]
    # can now be just
    uploaded_file["duration"]
  • The Shrine.mime_type, Shrine.dimensions, and Shrine.signature aliases have been added to determine_mime_type, store_dimensions, and signature plugins.

    Shrine.determine_mime_type(io)
    # can now be just
    Shrine.mime_type(io)
    Shrine.extract_dimensions(io)
    # can now be just
    Shrine.dimensions(io)
    Shrine.calculate_signature(io)
    # can now be just
    Shrine.signature(io)
  • The #validate_{max,min}_dimensions validators have been added to the validation_helpers plugin.

    validate_min_width  10
    validate_min_height 10
    validate_max_width  5000
    validate_max_height 5000
    
    # can now be written as
    
    validate_min_dimensions [10, 10]
    validate_max_dimensions [5000, 5000]
    
    # which can be additionally shortened to
    
    validate_dimensions [10..5000, 10..5000]
  • The #validate_size, #validate_width, and #validate_height shorthands have been added to the validation_helpers plugin.

    validate_min_size 1024
    validate_max_size 10*1024*1024
    
    # can now be shortned to
    
    validate_size 1024..10*1024*1024
    validate_min_width 10
    validate_max_width 5000
    
    # can now be shortened to
    
    validate_width 10..5000
    validate_min_height 10
    validate_max_height 5000
    
    # can now be shortened to
    
    validate_height 10..5000
  • The #validate_mime_type and #validate_extension shorthands have been added to the validation_helpers plugin.

    validate_mime_type_inclusion %w[image/jpeg image/png image/webp]
    # can now be just
    validate_mime_type %w[image/jpeg image/png image/webp]
    validate_extension_inclusion %w[jpeg png webp]
    # can now be just
    validate_extension %w[jpeg png webp]
  • Default error messages in validation_helpers plugin have been simplified.

  • You can now call super when overriding Shrine::UploadedFile methods defined by the add_metadata plugin.

Backwards compatibility

  • The logging plugin has been deprecated in favour of the instrumentation plugin.

  • The moving pluing has been deprecated in favour of the :move option to FileSystem#upload. This means that the #move && #movable? methods are not part of the storage abstraction anymore.

  • The backup plugin has been deprecated (a new mirroring plugin will get added in 3.0).

  • The copy plugin has been deprecated.

  • The Shrine::Plugins::DataUri::DataFile constant from the data_uri plugin has been renamed to Shrine::DataFile.

  • The Shrine::Plugins::RackFile::UploadedFile constant from the data_uri plugin has been renamed to Shrine::RackFile.

  • The :older_than option for FileSystem#clear! has been deprecated in favour of passing a block.

    file_system.clear!(older_than: Time.now - 7*24*60*60)
    # should now be replaced with
    file_system.clear! { |path| path.mtime < Time.now - 7*24*60*60 }
  • The FileSystem#upload method deprecates ignoring unrecognized upload options.

  • The FileSystem#upload method doesn't backfill size metadata anymore if an IO with unknown size is being uploaded via Shrine#upload.

  • Several plugins have changed how they store configuration options internally. If you were accessing these options directly, you will need to update your code.