Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
264 lines (200 sloc) 8.29 KB

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)
    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:
  • 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/"
  • 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 < - 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:

    Plugin Instrumentation
    derivation_endpoint instruments file processing
    determine_mime_type instruments analyzing MIME type
    store_dimensions instruments extracting image dimensions
    signature instruments calculating signature
    infer_extension instruments inferring extension
    remote_url instruments remote URL downloading
    data_uri instruments 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 = if record.is_a?(User)
      pretty_location(io, record: record, identifier: identifier, **context)
  • The Shrine::UploadedFile#[] operator has been added for easier metadata retrieving.

    # can now be just
  • The Shrine.mime_type, Shrine.dimensions, and Shrine.signature aliases have been added to determine_mime_type, store_dimensions, and signature plugins.

    # can now be just
    # can now be just
    # can now be just
  • 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 over mirroring uploads via the instrumentation plugin.

  • 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: - 7*24*60*60)
    # should now be replaced with
    file_system.clear! { |path| path.mtime < - 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.

You can’t perform that action at this time.