activestorage 6.1.1 → 6.1.6
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.
Potentially problematic release.
This version of activestorage might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +112 -0
- data/MIT-LICENSE +1 -1
- data/README.md +1 -1
- data/app/controllers/active_storage/representations/base_controller.rb +14 -0
- data/app/controllers/active_storage/representations/proxy_controller.rb +3 -9
- data/app/controllers/active_storage/representations/redirect_controller.rb +2 -4
- data/app/models/active_storage/attachment.rb +1 -1
- data/app/models/active_storage/blob/representable.rb +3 -3
- data/app/models/active_storage/blob.rb +11 -3
- data/app/models/active_storage/variant.rb +4 -4
- data/app/models/active_storage/variant_with_record.rb +1 -1
- data/app/models/active_storage/variation.rb +4 -4
- data/lib/active_storage/engine.rb +16 -0
- data/lib/active_storage/errors.rb +3 -0
- data/lib/active_storage/gem_version.rb +1 -1
- data/lib/active_storage/previewer/video_previewer.rb +3 -1
- data/lib/active_storage/previewer.rb +10 -1
- data/lib/active_storage/transformers/image_processing_transformer.rb +65 -0
- data/lib/active_storage.rb +294 -1
- data/lib/tasks/activestorage.rake +5 -1
- metadata +23 -21
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 985aeed1b2150be57a83d7779240e61be0b36689b342ccd710c8ba35c3f6c84d
         | 
| 4 | 
            +
              data.tar.gz: 8334b4728bd51120473b7f720a20cda36df0f6f96acaf2e76c12d0eb94bf95a1
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 5227ab769b5adff20f44dc3bca81e3eca7e72fe589d0dbec32be507a57bb6f285d55289934340214ee692d8a38ff421e59658c9b60c6da5ddee96336eed688ab
         | 
| 7 | 
            +
              data.tar.gz: c3490ed2c45b821f619d6837f9adffbc43c854d953bf43e29c0092452819c53a95ed87b5f45c3fed6e0f169070b6532f4bbb85cbc5bf64e8d1fc4cf90df2ca63
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,115 @@ | |
| 1 | 
            +
            ## Rails 6.1.5.1 (April 26, 2022) ##
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            *   No changes.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
            ## Rails 6.1.5 (March 09, 2022) ##
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            *   Attachments can be deleted after their association is no longer defined.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                Fixes #42514
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                *Don Sisco*
         | 
| 13 | 
            +
             | 
| 14 | 
            +
             | 
| 15 | 
            +
            ## Rails 6.1.4.7 (March 08, 2022) ##
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            *   Added image transformation validation via configurable allow-list.
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                Variant now offers a configurable allow-list for
         | 
| 20 | 
            +
                transformation methods in addition to a configurable deny-list for arguments.
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                [CVE-2022-21831]
         | 
| 23 | 
            +
             | 
| 24 | 
            +
             | 
| 25 | 
            +
            ## Rails 6.1.4.6 (February 11, 2022) ##
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            *   No changes.
         | 
| 28 | 
            +
             | 
| 29 | 
            +
             | 
| 30 | 
            +
            ## Rails 6.1.4.5 (February 11, 2022) ##
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            *   No changes.
         | 
| 33 | 
            +
             | 
| 34 | 
            +
             | 
| 35 | 
            +
            ## Rails 6.1.4.4 (December 15, 2021) ##
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            *   No changes.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
             | 
| 40 | 
            +
            ## Rails 6.1.4.3 (December 14, 2021) ##
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            *   No changes.
         | 
| 43 | 
            +
             | 
| 44 | 
            +
             | 
| 45 | 
            +
            ## Rails 6.1.4.2 (December 14, 2021) ##
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            *   No changes.
         | 
| 48 | 
            +
             | 
| 49 | 
            +
             | 
| 50 | 
            +
            ## Rails 6.1.4.1 (August 19, 2021) ##
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            *   No changes.
         | 
| 53 | 
            +
             | 
| 54 | 
            +
             | 
| 55 | 
            +
            ## Rails 6.1.4 (June 24, 2021) ##
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            *   The parameters sent to `ffmpeg` for generating a video preview image are now
         | 
| 58 | 
            +
                configurable under `config.active_storage.video_preview_arguments`.
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                *Brendon Muir*
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            *   Fix Active Storage update task when running in an engine.
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                *Justin Malčić*
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            *   Don't raise an error if the mime type is not recognized.
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                Fixes #41777.
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                *Alex Ghiculescu*
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            *   `ActiveStorage::PreviewError` is raised when a previewer is unable to generate a preview image.
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                *Alex Robbin*
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            *   respond with 404 given invalid variation key when asking for representations.
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                *George Claghorn*
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            *   `Blob` creation shouldn't crash if no service selected.
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                *Alex Ghiculescu*
         | 
| 83 | 
            +
             | 
| 84 | 
            +
             | 
| 85 | 
            +
            ## Rails 6.1.3.2 (May 05, 2021) ##
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            *   No changes.
         | 
| 88 | 
            +
             | 
| 89 | 
            +
             | 
| 90 | 
            +
            ## Rails 6.1.3.1 (March 26, 2021) ##
         | 
| 91 | 
            +
             | 
| 92 | 
            +
            *  Marcel is upgraded to version 1.0.0 to avoid a dependency on GPL-licensed
         | 
| 93 | 
            +
               mime types data.
         | 
| 94 | 
            +
             | 
| 95 | 
            +
               *George Claghorn*
         | 
| 96 | 
            +
             | 
| 97 | 
            +
             | 
| 98 | 
            +
            ## Rails 6.1.3 (February 17, 2021) ##
         | 
| 99 | 
            +
             | 
| 100 | 
            +
            *   No changes.
         | 
| 101 | 
            +
             | 
| 102 | 
            +
             | 
| 103 | 
            +
            ## Rails 6.1.2.1 (February 10, 2021) ##
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            *   No changes.
         | 
| 106 | 
            +
             | 
| 107 | 
            +
             | 
| 108 | 
            +
            ## Rails 6.1.2 (February 09, 2021) ##
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            *   No changes.
         | 
| 111 | 
            +
             | 
| 112 | 
            +
             | 
| 1 113 | 
             
            ## Rails 6.1.1 (January 07, 2021) ##
         | 
| 2 114 |  | 
| 3 115 | 
             
            *   Fix S3 multipart uploads when threshold is larger than file.
         | 
    
        data/MIT-LICENSE
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -10,7 +10,7 @@ You can read more about Active Storage in the [Active Storage Overview](https:// | |
| 10 10 |  | 
| 11 11 | 
             
            ## Compared to other storage solutions
         | 
| 12 12 |  | 
| 13 | 
            -
            A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/ | 
| 13 | 
            +
            A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the `Attachment` join model, which then connects to the actual `Blob`.
         | 
| 14 14 |  | 
| 15 15 | 
             
            `Blob` models store attachment metadata (filename, content-type, etc.), and their identifier key in the storage service. Blob models do not store the actual binary data. They are intended to be immutable in spirit. One file, one blob. You can associate the same blob with multiple application models as well. And if you want to do transformations of a given `Blob`, the idea is that you'll simply create a new one, rather than attempt to mutate the existing one (though of course you can delete the previous version later if you don't need it).
         | 
| 16 16 |  | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class ActiveStorage::Representations::BaseController < ActiveStorage::BaseController #:nodoc:
         | 
| 4 | 
            +
              include ActiveStorage::SetBlob
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              before_action :set_representation
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              private
         | 
| 9 | 
            +
                def set_representation
         | 
| 10 | 
            +
                  @representation = @blob.representation(params[:variation_key]).processed
         | 
| 11 | 
            +
                rescue ActiveSupport::MessageVerifier::InvalidSignature
         | 
| 12 | 
            +
                  head :not_found
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
            end
         | 
| @@ -1,19 +1,13 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            # Proxy files through application. This avoids having a redirect and makes files easier to cache.
         | 
| 4 | 
            -
            class ActiveStorage::Representations::ProxyController < ActiveStorage::BaseController
         | 
| 5 | 
            -
              include ActiveStorage::SetBlob
         | 
| 4 | 
            +
            class ActiveStorage::Representations::ProxyController < ActiveStorage::Representations::BaseController
         | 
| 6 5 | 
             
              include ActiveStorage::SetHeaders
         | 
| 7 6 |  | 
| 8 7 | 
             
              def show
         | 
| 9 8 | 
             
                http_cache_forever public: true do
         | 
| 10 | 
            -
                  set_content_headers_from representation.image
         | 
| 11 | 
            -
                  stream representation
         | 
| 9 | 
            +
                  set_content_headers_from @representation.image
         | 
| 10 | 
            +
                  stream @representation
         | 
| 12 11 | 
             
                end
         | 
| 13 12 | 
             
              end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
              private
         | 
| 16 | 
            -
                def representation
         | 
| 17 | 
            -
                  @representation ||= @blob.representation(params[:variation_key]).processed
         | 
| 18 | 
            -
                end
         | 
| 19 13 | 
             
            end
         | 
| @@ -4,11 +4,9 @@ | |
| 4 4 | 
             
            # Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
         | 
| 5 5 | 
             
            # security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own
         | 
| 6 6 | 
             
            # authenticated redirection controller.
         | 
| 7 | 
            -
            class ActiveStorage::Representations::RedirectController < ActiveStorage::BaseController
         | 
| 8 | 
            -
              include ActiveStorage::SetBlob
         | 
| 9 | 
            -
             | 
| 7 | 
            +
            class ActiveStorage::Representations::RedirectController < ActiveStorage::Representations::BaseController
         | 
| 10 8 | 
             
              def show
         | 
| 11 9 | 
             
                expires_in ActiveStorage.service_urls_expire_in
         | 
| 12 | 
            -
                redirect_to @ | 
| 10 | 
            +
                redirect_to @representation.url(disposition: params[:disposition])
         | 
| 13 11 | 
             
              end
         | 
| 14 12 | 
             
            end
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require " | 
| 3 | 
            +
            require "mini_mime"
         | 
| 4 4 |  | 
| 5 5 | 
             
            module ActiveStorage::Blob::Representable
         | 
| 6 6 | 
             
              extend ActiveSupport::Concern
         | 
| @@ -110,10 +110,10 @@ module ActiveStorage::Blob::Representable | |
| 110 110 | 
             
                end
         | 
| 111 111 |  | 
| 112 112 | 
             
                def format
         | 
| 113 | 
            -
                  if filename.extension.present? &&  | 
| 113 | 
            +
                  if filename.extension.present? && MiniMime.lookup_by_extension(filename.extension)&.content_type == content_type
         | 
| 114 114 | 
             
                    filename.extension
         | 
| 115 115 | 
             
                  else
         | 
| 116 | 
            -
                     | 
| 116 | 
            +
                    MiniMime.lookup_by_content_type(content_type)&.extension
         | 
| 117 117 | 
             
                  end
         | 
| 118 118 | 
             
                end
         | 
| 119 119 |  | 
| @@ -49,7 +49,7 @@ class ActiveStorage::Blob < ActiveStorage::Record | |
| 49 49 | 
             
              scope :unattached, -> { where.missing(:attachments) }
         | 
| 50 50 |  | 
| 51 51 | 
             
              after_initialize do
         | 
| 52 | 
            -
                self.service_name ||= self.class.service | 
| 52 | 
            +
                self.service_name ||= self.class.service&.name
         | 
| 53 53 | 
             
              end
         | 
| 54 54 |  | 
| 55 55 | 
             
              after_update_commit :update_service_metadata, if: :content_type_previously_changed?
         | 
| @@ -74,8 +74,16 @@ class ActiveStorage::Blob < ActiveStorage::Record | |
| 74 74 | 
             
                # that was created ahead of the upload itself on form submission.
         | 
| 75 75 | 
             
                #
         | 
| 76 76 | 
             
                # The signed ID is also used to create stable URLs for the blob through the BlobsController.
         | 
| 77 | 
            -
                def find_signed | 
| 78 | 
            -
                  super(id, purpose:  | 
| 77 | 
            +
                def find_signed(id, record: nil, purpose: :blob_id)
         | 
| 78 | 
            +
                  super(id, purpose: purpose)
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                # Works like +find_signed+, but will raise an +ActiveSupport::MessageVerifier::InvalidSignature+
         | 
| 82 | 
            +
                # exception if the +signed_id+ has either expired, has a purpose mismatch, is for another record,
         | 
| 83 | 
            +
                # or has been tampered with. It will also raise an +ActiveRecord::RecordNotFound+ exception if
         | 
| 84 | 
            +
                # the valid signed id can't find a record.
         | 
| 85 | 
            +
                def find_signed!(id, record: nil, purpose: :blob_id)
         | 
| 86 | 
            +
                  super(id, purpose: purpose)
         | 
| 79 87 | 
             
                end
         | 
| 80 88 |  | 
| 81 89 | 
             
                def build_after_upload(io:, filename:, content_type: nil, metadata: nil, service_name: nil, identify: true, record: nil) #:nodoc:
         | 
| @@ -4,7 +4,7 @@ | |
| 4 4 | 
             
            # These variants are used to create thumbnails, fixed-size avatars, or any other derivative image from the
         | 
| 5 5 | 
             
            # original.
         | 
| 6 6 | 
             
            #
         | 
| 7 | 
            -
            # Variants rely on {ImageProcessing}[https://github.com/janko | 
| 7 | 
            +
            # Variants rely on {ImageProcessing}[https://github.com/janko/image_processing] gem for the actual transformations
         | 
| 8 8 | 
             
            # of the file, so you must add <tt>gem "image_processing"</tt> to your Gemfile if you wish to use variants. By
         | 
| 9 9 | 
             
            # default, images will be processed with {ImageMagick}[http://imagemagick.org] using the
         | 
| 10 10 | 
             
            # {MiniMagick}[https://github.com/minimagick/minimagick] gem, but you can also switch to the
         | 
| @@ -46,9 +46,9 @@ | |
| 46 46 | 
             
            #
         | 
| 47 47 | 
             
            # Visit the following links for a list of available ImageProcessing commands and ImageMagick/libvips operations:
         | 
| 48 48 | 
             
            #
         | 
| 49 | 
            -
            # * {ImageProcessing::MiniMagick}[https://github.com/janko | 
| 49 | 
            +
            # * {ImageProcessing::MiniMagick}[https://github.com/janko/image_processing/blob/master/doc/minimagick.md#methods]
         | 
| 50 50 | 
             
            # * {ImageMagick reference}[https://www.imagemagick.org/script/mogrify.php]
         | 
| 51 | 
            -
            # * {ImageProcessing::Vips}[https://github.com/janko | 
| 51 | 
            +
            # * {ImageProcessing::Vips}[https://github.com/janko/image_processing/blob/master/doc/vips.md#methods]
         | 
| 52 52 | 
             
            # * {ruby-vips reference}[http://www.rubydoc.info/gems/ruby-vips/Vips/Image]
         | 
| 53 53 | 
             
            class ActiveStorage::Variant
         | 
| 54 54 | 
             
              attr_reader :blob, :variation
         | 
| @@ -89,7 +89,7 @@ class ActiveStorage::Variant | |
| 89 89 | 
             
              end
         | 
| 90 90 |  | 
| 91 91 | 
             
              def filename
         | 
| 92 | 
            -
                ActiveStorage::Filename.new "#{blob.filename.base}.#{variation.format}"
         | 
| 92 | 
            +
                ActiveStorage::Filename.new "#{blob.filename.base}.#{variation.format.downcase}"
         | 
| 93 93 | 
             
              end
         | 
| 94 94 |  | 
| 95 95 | 
             
              alias_method :content_type_for_serving, :content_type
         | 
| @@ -33,7 +33,7 @@ class ActiveStorage::VariantWithRecord | |
| 33 33 | 
             
                def transform_blob
         | 
| 34 34 | 
             
                  blob.open do |input|
         | 
| 35 35 | 
             
                    variation.transform(input) do |output|
         | 
| 36 | 
            -
                      yield io: output, filename: "#{blob.filename.base}.#{variation.format}",
         | 
| 36 | 
            +
                      yield io: output, filename: "#{blob.filename.base}.#{variation.format.downcase}",
         | 
| 37 37 | 
             
                        content_type: variation.content_type, service_name: blob.service.name
         | 
| 38 38 | 
             
                    end
         | 
| 39 39 | 
             
                  end
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require " | 
| 3 | 
            +
            require "mini_mime"
         | 
| 4 4 |  | 
| 5 5 | 
             
            # A set of transformations that can be applied to a blob to create a variant. This class is exposed via
         | 
| 6 6 | 
             
            # the ActiveStorage::Blob#variant method and should rarely be used directly.
         | 
| @@ -10,7 +10,7 @@ require "mimemagic" | |
| 10 10 | 
             
            #
         | 
| 11 11 | 
             
            #   ActiveStorage::Variation.new(resize_to_limit: [100, 100], monochrome: true, trim: true, rotate: "-90")
         | 
| 12 12 | 
             
            #
         | 
| 13 | 
            -
            # The options map directly to {ImageProcessing}[https://github.com/janko | 
| 13 | 
            +
            # The options map directly to {ImageProcessing}[https://github.com/janko/image_processing] commands.
         | 
| 14 14 | 
             
            class ActiveStorage::Variation
         | 
| 15 15 | 
             
              attr_reader :transformations
         | 
| 16 16 |  | 
| @@ -59,14 +59,14 @@ class ActiveStorage::Variation | |
| 59 59 |  | 
| 60 60 | 
             
              def format
         | 
| 61 61 | 
             
                transformations.fetch(:format, :png).tap do |format|
         | 
| 62 | 
            -
                  if  | 
| 62 | 
            +
                  if MiniMime.lookup_by_extension(format.to_s).nil?
         | 
| 63 63 | 
             
                    raise ArgumentError, "Invalid variant format (#{format.inspect})"
         | 
| 64 64 | 
             
                  end
         | 
| 65 65 | 
             
                end
         | 
| 66 66 | 
             
              end
         | 
| 67 67 |  | 
| 68 68 | 
             
              def content_type
         | 
| 69 | 
            -
                 | 
| 69 | 
            +
                MiniMime.lookup_by_extension(format.to_s).content_type
         | 
| 70 70 | 
             
              end
         | 
| 71 71 |  | 
| 72 72 | 
             
              # Returns a signed key for all the +transformations+ that this variation was instantiated with.
         | 
| @@ -86,12 +86,28 @@ module ActiveStorage | |
| 86 86 | 
             
                    ActiveStorage.draw_routes       = app.config.active_storage.draw_routes != false
         | 
| 87 87 | 
             
                    ActiveStorage.resolve_model_to_route = app.config.active_storage.resolve_model_to_route || :rails_storage_redirect
         | 
| 88 88 |  | 
| 89 | 
            +
                    ActiveStorage.supported_image_processing_methods += app.config.active_storage.supported_image_processing_methods || []
         | 
| 90 | 
            +
                    ActiveStorage.unsupported_image_processing_arguments = app.config.active_storage.unsupported_image_processing_arguments || %w(
         | 
| 91 | 
            +
                      -debug
         | 
| 92 | 
            +
                      -display
         | 
| 93 | 
            +
                      -distribute-cache
         | 
| 94 | 
            +
                      -help
         | 
| 95 | 
            +
                      -path
         | 
| 96 | 
            +
                      -print
         | 
| 97 | 
            +
                      -set
         | 
| 98 | 
            +
                      -verbose
         | 
| 99 | 
            +
                      -version
         | 
| 100 | 
            +
                      -write
         | 
| 101 | 
            +
                      -write-mask
         | 
| 102 | 
            +
                    )
         | 
| 103 | 
            +
             | 
| 89 104 | 
             
                    ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
         | 
| 90 105 | 
             
                    ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
         | 
| 91 106 | 
             
                    ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
         | 
| 92 107 | 
             
                    ActiveStorage.service_urls_expire_in = app.config.active_storage.service_urls_expire_in || 5.minutes
         | 
| 93 108 | 
             
                    ActiveStorage.content_types_allowed_inline = app.config.active_storage.content_types_allowed_inline || []
         | 
| 94 109 | 
             
                    ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
         | 
| 110 | 
            +
                    ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
         | 
| 95 111 |  | 
| 96 112 | 
             
                    ActiveStorage.replace_on_assign_to_many = app.config.active_storage.replace_on_assign_to_many || false
         | 
| 97 113 | 
             
                    ActiveStorage.track_variants = app.config.active_storage.track_variants || false
         | 
| @@ -23,4 +23,7 @@ module ActiveStorage | |
| 23 23 | 
             
              # Raised when ActiveStorage::Blob#download is called on a blob where the
         | 
| 24 24 | 
             
              # backing file is no longer present in its service.
         | 
| 25 25 | 
             
              class FileNotFoundError < Error; end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              # Raised when a Previewer is unable to generate a preview image.
         | 
| 28 | 
            +
              class PreviewError < Error; end
         | 
| 26 29 | 
             
            end
         | 
| @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require "shellwords"
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            module ActiveStorage
         | 
| 4 6 | 
             
              class Previewer::VideoPreviewer < Previewer
         | 
| 5 7 | 
             
                class << self
         | 
| @@ -28,7 +30,7 @@ module ActiveStorage | |
| 28 30 |  | 
| 29 31 | 
             
                private
         | 
| 30 32 | 
             
                  def draw_relevant_frame_from(file, &block)
         | 
| 31 | 
            -
                    draw self.class.ffmpeg_path, "-i", file.path,  | 
| 33 | 
            +
                    draw self.class.ffmpeg_path, "-i", file.path, *Shellwords.split(ActiveStorage.video_preview_arguments), "-", &block
         | 
| 32 34 | 
             
                  end
         | 
| 33 35 | 
             
              end
         | 
| 34 36 | 
             
            end
         | 
| @@ -70,7 +70,16 @@ module ActiveStorage | |
| 70 70 |  | 
| 71 71 | 
             
                  def capture(*argv, to:)
         | 
| 72 72 | 
             
                    to.binmode
         | 
| 73 | 
            -
             | 
| 73 | 
            +
             | 
| 74 | 
            +
                    open_tempfile do |err|
         | 
| 75 | 
            +
                      IO.popen(argv, err: err) { |out| IO.copy_stream(out, to) }
         | 
| 76 | 
            +
                      err.rewind
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      unless $?.success?
         | 
| 79 | 
            +
                        raise PreviewError, "#{argv.first} failed (status #{$?.exitstatus}): #{err.read.to_s.chomp}"
         | 
| 80 | 
            +
                      end
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
             | 
| 74 83 | 
             
                    to.rewind
         | 
| 75 84 | 
             
                  end
         | 
| 76 85 |  | 
| @@ -13,6 +13,9 @@ module ActiveStorage | |
| 13 13 | 
             
              module Transformers
         | 
| 14 14 | 
             
                class ImageProcessingTransformer < Transformer
         | 
| 15 15 | 
             
                  private
         | 
| 16 | 
            +
                    class UnsupportedImageProcessingMethod < StandardError; end
         | 
| 17 | 
            +
                    class UnsupportedImageProcessingArgument < StandardError; end
         | 
| 18 | 
            +
             | 
| 16 19 | 
             
                    def process(file, format:)
         | 
| 17 20 | 
             
                      processor.
         | 
| 18 21 | 
             
                        source(file).
         | 
| @@ -28,6 +31,10 @@ module ActiveStorage | |
| 28 31 |  | 
| 29 32 | 
             
                    def operations
         | 
| 30 33 | 
             
                      transformations.each_with_object([]) do |(name, argument), list|
         | 
| 34 | 
            +
                        if ActiveStorage.variant_processor == :mini_magick
         | 
| 35 | 
            +
                          validate_transformation(name, argument)
         | 
| 36 | 
            +
                        end
         | 
| 37 | 
            +
             | 
| 31 38 | 
             
                        if name.to_s == "combine_options"
         | 
| 32 39 | 
             
                          raise ArgumentError, <<~ERROR.squish
         | 
| 33 40 | 
             
                            Active Storage's ImageProcessing transformer doesn't support :combine_options,
         | 
| @@ -40,6 +47,64 @@ module ActiveStorage | |
| 40 47 | 
             
                        end
         | 
| 41 48 | 
             
                      end
         | 
| 42 49 | 
             
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    def validate_transformation(name, argument)
         | 
| 52 | 
            +
                      method_name = name.to_s.tr("-", "_")
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                      unless ActiveStorage.supported_image_processing_methods.any? { |method| method_name == method }
         | 
| 55 | 
            +
                        raise UnsupportedImageProcessingMethod, <<~ERROR.squish
         | 
| 56 | 
            +
                          One or more of the provided transformation methods is not supported.
         | 
| 57 | 
            +
                        ERROR
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                      if argument.present?
         | 
| 61 | 
            +
                        if argument.is_a?(String) || argument.is_a?(Symbol)
         | 
| 62 | 
            +
                          validate_arg_string(argument)
         | 
| 63 | 
            +
                        elsif argument.is_a?(Array)
         | 
| 64 | 
            +
                          validate_arg_array(argument)
         | 
| 65 | 
            +
                        elsif argument.is_a?(Hash)
         | 
| 66 | 
            +
                          validate_arg_hash(argument)
         | 
| 67 | 
            +
                        end
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                    def validate_arg_string(argument)
         | 
| 72 | 
            +
                      unsupported_arguments = ActiveStorage.unsupported_image_processing_arguments.any? do |bad_arg|
         | 
| 73 | 
            +
                        argument.to_s.downcase.include?(bad_arg)
         | 
| 74 | 
            +
                      end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                      raise UnsupportedImageProcessingArgument if unsupported_arguments
         | 
| 77 | 
            +
                    end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    def validate_arg_array(argument)
         | 
| 80 | 
            +
                      argument.each do |arg|
         | 
| 81 | 
            +
                        if arg.is_a?(Integer) || arg.is_a?(Float)
         | 
| 82 | 
            +
                          next
         | 
| 83 | 
            +
                        elsif arg.is_a?(String) || arg.is_a?(Symbol)
         | 
| 84 | 
            +
                          validate_arg_string(arg)
         | 
| 85 | 
            +
                        elsif arg.is_a?(Array)
         | 
| 86 | 
            +
                          validate_arg_array(arg)
         | 
| 87 | 
            +
                        elsif arg.is_a?(Hash)
         | 
| 88 | 
            +
                          validate_arg_hash(arg)
         | 
| 89 | 
            +
                        end
         | 
| 90 | 
            +
                      end
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    def validate_arg_hash(argument)
         | 
| 94 | 
            +
                      argument.each do |key, value|
         | 
| 95 | 
            +
                        validate_arg_string(key)
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                        if value.is_a?(Integer) || value.is_a?(Float)
         | 
| 98 | 
            +
                          next
         | 
| 99 | 
            +
                        elsif value.is_a?(String) || value.is_a?(Symbol)
         | 
| 100 | 
            +
                          validate_arg_string(value)
         | 
| 101 | 
            +
                        elsif value.is_a?(Array)
         | 
| 102 | 
            +
                          validate_arg_array(value)
         | 
| 103 | 
            +
                        elsif value.is_a?(Hash)
         | 
| 104 | 
            +
                          validate_arg_hash(value)
         | 
| 105 | 
            +
                        end
         | 
| 106 | 
            +
                      end
         | 
| 107 | 
            +
                    end
         | 
| 43 108 | 
             
                end
         | 
| 44 109 | 
             
              end
         | 
| 45 110 | 
             
            end
         | 
    
        data/lib/active_storage.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            #--
         | 
| 4 | 
            -
            # Copyright (c) 2017- | 
| 4 | 
            +
            # Copyright (c) 2017-2022 David Heinemeier Hansson, Basecamp
         | 
| 5 5 | 
             
            #
         | 
| 6 6 | 
             
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 7 7 | 
             
            # a copy of this software and associated documentation files (the
         | 
| @@ -58,6 +58,297 @@ module ActiveStorage | |
| 58 58 | 
             
              mattr_accessor :content_types_to_serve_as_binary, default: []
         | 
| 59 59 | 
             
              mattr_accessor :content_types_allowed_inline,     default: []
         | 
| 60 60 |  | 
| 61 | 
            +
              mattr_accessor :supported_image_processing_methods, default: [
         | 
| 62 | 
            +
                "adaptive_blur",
         | 
| 63 | 
            +
                "adaptive_resize",
         | 
| 64 | 
            +
                "adaptive_sharpen",
         | 
| 65 | 
            +
                "adjoin",
         | 
| 66 | 
            +
                "affine",
         | 
| 67 | 
            +
                "alpha",
         | 
| 68 | 
            +
                "annotate",
         | 
| 69 | 
            +
                "antialias",
         | 
| 70 | 
            +
                "append",
         | 
| 71 | 
            +
                "apply",
         | 
| 72 | 
            +
                "attenuate",
         | 
| 73 | 
            +
                "authenticate",
         | 
| 74 | 
            +
                "auto_gamma",
         | 
| 75 | 
            +
                "auto_level",
         | 
| 76 | 
            +
                "auto_orient",
         | 
| 77 | 
            +
                "auto_threshold",
         | 
| 78 | 
            +
                "backdrop",
         | 
| 79 | 
            +
                "background",
         | 
| 80 | 
            +
                "bench",
         | 
| 81 | 
            +
                "bias",
         | 
| 82 | 
            +
                "bilateral_blur",
         | 
| 83 | 
            +
                "black_point_compensation",
         | 
| 84 | 
            +
                "black_threshold",
         | 
| 85 | 
            +
                "blend",
         | 
| 86 | 
            +
                "blue_primary",
         | 
| 87 | 
            +
                "blue_shift",
         | 
| 88 | 
            +
                "blur",
         | 
| 89 | 
            +
                "border",
         | 
| 90 | 
            +
                "bordercolor",
         | 
| 91 | 
            +
                "borderwidth",
         | 
| 92 | 
            +
                "brightness_contrast",
         | 
| 93 | 
            +
                "cache",
         | 
| 94 | 
            +
                "canny",
         | 
| 95 | 
            +
                "caption",
         | 
| 96 | 
            +
                "channel",
         | 
| 97 | 
            +
                "channel_fx",
         | 
| 98 | 
            +
                "charcoal",
         | 
| 99 | 
            +
                "chop",
         | 
| 100 | 
            +
                "clahe",
         | 
| 101 | 
            +
                "clamp",
         | 
| 102 | 
            +
                "clip",
         | 
| 103 | 
            +
                "clip_path",
         | 
| 104 | 
            +
                "clone",
         | 
| 105 | 
            +
                "clut",
         | 
| 106 | 
            +
                "coalesce",
         | 
| 107 | 
            +
                "colorize",
         | 
| 108 | 
            +
                "colormap",
         | 
| 109 | 
            +
                "color_matrix",
         | 
| 110 | 
            +
                "colors",
         | 
| 111 | 
            +
                "colorspace",
         | 
| 112 | 
            +
                "colourspace",
         | 
| 113 | 
            +
                "color_threshold",
         | 
| 114 | 
            +
                "combine",
         | 
| 115 | 
            +
                "combine_options",
         | 
| 116 | 
            +
                "comment",
         | 
| 117 | 
            +
                "compare",
         | 
| 118 | 
            +
                "complex",
         | 
| 119 | 
            +
                "compose",
         | 
| 120 | 
            +
                "composite",
         | 
| 121 | 
            +
                "compress",
         | 
| 122 | 
            +
                "connected_components",
         | 
| 123 | 
            +
                "contrast",
         | 
| 124 | 
            +
                "contrast_stretch",
         | 
| 125 | 
            +
                "convert",
         | 
| 126 | 
            +
                "convolve",
         | 
| 127 | 
            +
                "copy",
         | 
| 128 | 
            +
                "crop",
         | 
| 129 | 
            +
                "cycle",
         | 
| 130 | 
            +
                "deconstruct",
         | 
| 131 | 
            +
                "define",
         | 
| 132 | 
            +
                "delay",
         | 
| 133 | 
            +
                "delete",
         | 
| 134 | 
            +
                "density",
         | 
| 135 | 
            +
                "depth",
         | 
| 136 | 
            +
                "descend",
         | 
| 137 | 
            +
                "deskew",
         | 
| 138 | 
            +
                "despeckle",
         | 
| 139 | 
            +
                "direction",
         | 
| 140 | 
            +
                "displace",
         | 
| 141 | 
            +
                "dispose",
         | 
| 142 | 
            +
                "dissimilarity_threshold",
         | 
| 143 | 
            +
                "dissolve",
         | 
| 144 | 
            +
                "distort",
         | 
| 145 | 
            +
                "dither",
         | 
| 146 | 
            +
                "draw",
         | 
| 147 | 
            +
                "duplicate",
         | 
| 148 | 
            +
                "edge",
         | 
| 149 | 
            +
                "emboss",
         | 
| 150 | 
            +
                "encoding",
         | 
| 151 | 
            +
                "endian",
         | 
| 152 | 
            +
                "enhance",
         | 
| 153 | 
            +
                "equalize",
         | 
| 154 | 
            +
                "evaluate",
         | 
| 155 | 
            +
                "evaluate_sequence",
         | 
| 156 | 
            +
                "extent",
         | 
| 157 | 
            +
                "extract",
         | 
| 158 | 
            +
                "family",
         | 
| 159 | 
            +
                "features",
         | 
| 160 | 
            +
                "fft",
         | 
| 161 | 
            +
                "fill",
         | 
| 162 | 
            +
                "filter",
         | 
| 163 | 
            +
                "flatten",
         | 
| 164 | 
            +
                "flip",
         | 
| 165 | 
            +
                "floodfill",
         | 
| 166 | 
            +
                "flop",
         | 
| 167 | 
            +
                "font",
         | 
| 168 | 
            +
                "foreground",
         | 
| 169 | 
            +
                "format",
         | 
| 170 | 
            +
                "frame",
         | 
| 171 | 
            +
                "function",
         | 
| 172 | 
            +
                "fuzz",
         | 
| 173 | 
            +
                "fx",
         | 
| 174 | 
            +
                "gamma",
         | 
| 175 | 
            +
                "gaussian_blur",
         | 
| 176 | 
            +
                "geometry",
         | 
| 177 | 
            +
                "gravity",
         | 
| 178 | 
            +
                "grayscale",
         | 
| 179 | 
            +
                "green_primary",
         | 
| 180 | 
            +
                "hald_clut",
         | 
| 181 | 
            +
                "highlight_color",
         | 
| 182 | 
            +
                "hough_lines",
         | 
| 183 | 
            +
                "iconGeometry",
         | 
| 184 | 
            +
                "iconic",
         | 
| 185 | 
            +
                "identify",
         | 
| 186 | 
            +
                "ift",
         | 
| 187 | 
            +
                "illuminant",
         | 
| 188 | 
            +
                "immutable",
         | 
| 189 | 
            +
                "implode",
         | 
| 190 | 
            +
                "insert",
         | 
| 191 | 
            +
                "intensity",
         | 
| 192 | 
            +
                "intent",
         | 
| 193 | 
            +
                "interlace",
         | 
| 194 | 
            +
                "interline_spacing",
         | 
| 195 | 
            +
                "interpolate",
         | 
| 196 | 
            +
                "interpolative_resize",
         | 
| 197 | 
            +
                "interword_spacing",
         | 
| 198 | 
            +
                "kerning",
         | 
| 199 | 
            +
                "kmeans",
         | 
| 200 | 
            +
                "kuwahara",
         | 
| 201 | 
            +
                "label",
         | 
| 202 | 
            +
                "lat",
         | 
| 203 | 
            +
                "layers",
         | 
| 204 | 
            +
                "level",
         | 
| 205 | 
            +
                "level_colors",
         | 
| 206 | 
            +
                "limit",
         | 
| 207 | 
            +
                "limits",
         | 
| 208 | 
            +
                "linear_stretch",
         | 
| 209 | 
            +
                "linewidth",
         | 
| 210 | 
            +
                "liquid_rescale",
         | 
| 211 | 
            +
                "list",
         | 
| 212 | 
            +
                "loader",
         | 
| 213 | 
            +
                "log",
         | 
| 214 | 
            +
                "loop",
         | 
| 215 | 
            +
                "lowlight_color",
         | 
| 216 | 
            +
                "magnify",
         | 
| 217 | 
            +
                "map",
         | 
| 218 | 
            +
                "mattecolor",
         | 
| 219 | 
            +
                "median",
         | 
| 220 | 
            +
                "mean_shift",
         | 
| 221 | 
            +
                "metric",
         | 
| 222 | 
            +
                "mode",
         | 
| 223 | 
            +
                "modulate",
         | 
| 224 | 
            +
                "moments",
         | 
| 225 | 
            +
                "monitor",
         | 
| 226 | 
            +
                "monochrome",
         | 
| 227 | 
            +
                "morph",
         | 
| 228 | 
            +
                "morphology",
         | 
| 229 | 
            +
                "mosaic",
         | 
| 230 | 
            +
                "motion_blur",
         | 
| 231 | 
            +
                "name",
         | 
| 232 | 
            +
                "negate",
         | 
| 233 | 
            +
                "noise",
         | 
| 234 | 
            +
                "normalize",
         | 
| 235 | 
            +
                "opaque",
         | 
| 236 | 
            +
                "ordered_dither",
         | 
| 237 | 
            +
                "orient",
         | 
| 238 | 
            +
                "page",
         | 
| 239 | 
            +
                "paint",
         | 
| 240 | 
            +
                "pause",
         | 
| 241 | 
            +
                "perceptible",
         | 
| 242 | 
            +
                "ping",
         | 
| 243 | 
            +
                "pointsize",
         | 
| 244 | 
            +
                "polaroid",
         | 
| 245 | 
            +
                "poly",
         | 
| 246 | 
            +
                "posterize",
         | 
| 247 | 
            +
                "precision",
         | 
| 248 | 
            +
                "preview",
         | 
| 249 | 
            +
                "process",
         | 
| 250 | 
            +
                "quality",
         | 
| 251 | 
            +
                "quantize",
         | 
| 252 | 
            +
                "quiet",
         | 
| 253 | 
            +
                "radial_blur",
         | 
| 254 | 
            +
                "raise",
         | 
| 255 | 
            +
                "random_threshold",
         | 
| 256 | 
            +
                "range_threshold",
         | 
| 257 | 
            +
                "red_primary",
         | 
| 258 | 
            +
                "regard_warnings",
         | 
| 259 | 
            +
                "region",
         | 
| 260 | 
            +
                "remote",
         | 
| 261 | 
            +
                "render",
         | 
| 262 | 
            +
                "repage",
         | 
| 263 | 
            +
                "resample",
         | 
| 264 | 
            +
                "resize",
         | 
| 265 | 
            +
                "resize_to_fill",
         | 
| 266 | 
            +
                "resize_to_fit",
         | 
| 267 | 
            +
                "resize_to_limit",
         | 
| 268 | 
            +
                "resize_and_pad",
         | 
| 269 | 
            +
                "respect_parentheses",
         | 
| 270 | 
            +
                "reverse",
         | 
| 271 | 
            +
                "roll",
         | 
| 272 | 
            +
                "rotate",
         | 
| 273 | 
            +
                "sample",
         | 
| 274 | 
            +
                "sampling_factor",
         | 
| 275 | 
            +
                "saver",
         | 
| 276 | 
            +
                "scale",
         | 
| 277 | 
            +
                "scene",
         | 
| 278 | 
            +
                "screen",
         | 
| 279 | 
            +
                "seed",
         | 
| 280 | 
            +
                "segment",
         | 
| 281 | 
            +
                "selective_blur",
         | 
| 282 | 
            +
                "separate",
         | 
| 283 | 
            +
                "sepia_tone",
         | 
| 284 | 
            +
                "shade",
         | 
| 285 | 
            +
                "shadow",
         | 
| 286 | 
            +
                "shared_memory",
         | 
| 287 | 
            +
                "sharpen",
         | 
| 288 | 
            +
                "shave",
         | 
| 289 | 
            +
                "shear",
         | 
| 290 | 
            +
                "sigmoidal_contrast",
         | 
| 291 | 
            +
                "silent",
         | 
| 292 | 
            +
                "similarity_threshold",
         | 
| 293 | 
            +
                "size",
         | 
| 294 | 
            +
                "sketch",
         | 
| 295 | 
            +
                "smush",
         | 
| 296 | 
            +
                "snaps",
         | 
| 297 | 
            +
                "solarize",
         | 
| 298 | 
            +
                "sort_pixels",
         | 
| 299 | 
            +
                "sparse_color",
         | 
| 300 | 
            +
                "splice",
         | 
| 301 | 
            +
                "spread",
         | 
| 302 | 
            +
                "statistic",
         | 
| 303 | 
            +
                "stegano",
         | 
| 304 | 
            +
                "stereo",
         | 
| 305 | 
            +
                "storage_type",
         | 
| 306 | 
            +
                "stretch",
         | 
| 307 | 
            +
                "strip",
         | 
| 308 | 
            +
                "stroke",
         | 
| 309 | 
            +
                "strokewidth",
         | 
| 310 | 
            +
                "style",
         | 
| 311 | 
            +
                "subimage_search",
         | 
| 312 | 
            +
                "swap",
         | 
| 313 | 
            +
                "swirl",
         | 
| 314 | 
            +
                "synchronize",
         | 
| 315 | 
            +
                "taint",
         | 
| 316 | 
            +
                "text_font",
         | 
| 317 | 
            +
                "threshold",
         | 
| 318 | 
            +
                "thumbnail",
         | 
| 319 | 
            +
                "tile_offset",
         | 
| 320 | 
            +
                "tint",
         | 
| 321 | 
            +
                "title",
         | 
| 322 | 
            +
                "transform",
         | 
| 323 | 
            +
                "transparent",
         | 
| 324 | 
            +
                "transparent_color",
         | 
| 325 | 
            +
                "transpose",
         | 
| 326 | 
            +
                "transverse",
         | 
| 327 | 
            +
                "treedepth",
         | 
| 328 | 
            +
                "trim",
         | 
| 329 | 
            +
                "type",
         | 
| 330 | 
            +
                "undercolor",
         | 
| 331 | 
            +
                "unique_colors",
         | 
| 332 | 
            +
                "units",
         | 
| 333 | 
            +
                "unsharp",
         | 
| 334 | 
            +
                "update",
         | 
| 335 | 
            +
                "valid_image",
         | 
| 336 | 
            +
                "view",
         | 
| 337 | 
            +
                "vignette",
         | 
| 338 | 
            +
                "virtual_pixel",
         | 
| 339 | 
            +
                "visual",
         | 
| 340 | 
            +
                "watermark",
         | 
| 341 | 
            +
                "wave",
         | 
| 342 | 
            +
                "wavelet_denoise",
         | 
| 343 | 
            +
                "weight",
         | 
| 344 | 
            +
                "white_balance",
         | 
| 345 | 
            +
                "white_point",
         | 
| 346 | 
            +
                "white_threshold",
         | 
| 347 | 
            +
                "window",
         | 
| 348 | 
            +
                "window_group"
         | 
| 349 | 
            +
              ]
         | 
| 350 | 
            +
              mattr_accessor :unsupported_image_processing_arguments
         | 
| 351 | 
            +
             | 
| 61 352 | 
             
              mattr_accessor :service_urls_expire_in, default: 5.minutes
         | 
| 62 353 |  | 
| 63 354 | 
             
              mattr_accessor :routes_prefix, default: "/rails/active_storage"
         | 
| @@ -67,6 +358,8 @@ module ActiveStorage | |
| 67 358 | 
             
              mattr_accessor :replace_on_assign_to_many, default: false
         | 
| 68 359 | 
             
              mattr_accessor :track_variants, default: false
         | 
| 69 360 |  | 
| 361 | 
            +
              mattr_accessor :video_preview_arguments, default: "-y -vframes 1 -f image2"
         | 
| 362 | 
            +
             | 
| 70 363 | 
             
              module Transformers
         | 
| 71 364 | 
             
                extend ActiveSupport::Autoload
         | 
| 72 365 |  | 
| @@ -17,6 +17,10 @@ namespace :active_storage do | |
| 17 17 | 
             
              task update: :environment do
         | 
| 18 18 | 
             
                ENV["MIGRATIONS_PATH"] = "db/update_migrate"
         | 
| 19 19 |  | 
| 20 | 
            -
                Rake::Task | 
| 20 | 
            +
                if Rake::Task.task_defined?("active_storage:install")
         | 
| 21 | 
            +
                  Rake::Task["active_storage:install"].invoke
         | 
| 22 | 
            +
                else
         | 
| 23 | 
            +
                  Rake::Task["app:active_storage:install"].invoke
         | 
| 24 | 
            +
                end
         | 
| 21 25 | 
             
              end
         | 
| 22 26 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: activestorage
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 6.1. | 
| 4 | 
            +
              version: 6.1.6
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - David Heinemeier Hansson
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2022-05-09 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -16,84 +16,84 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - '='
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: 6.1. | 
| 19 | 
            +
                    version: 6.1.6
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - '='
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: 6.1. | 
| 26 | 
            +
                    version: 6.1.6
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: actionpack
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - '='
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: 6.1. | 
| 33 | 
            +
                    version: 6.1.6
         | 
| 34 34 | 
             
              type: :runtime
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 37 | 
             
                requirements:
         | 
| 38 38 | 
             
                - - '='
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version: 6.1. | 
| 40 | 
            +
                    version: 6.1.6
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 42 | 
             
              name: activejob
         | 
| 43 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 44 | 
             
                requirements:
         | 
| 45 45 | 
             
                - - '='
         | 
| 46 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            -
                    version: 6.1. | 
| 47 | 
            +
                    version: 6.1.6
         | 
| 48 48 | 
             
              type: :runtime
         | 
| 49 49 | 
             
              prerelease: false
         | 
| 50 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 52 | 
             
                - - '='
         | 
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            -
                    version: 6.1. | 
| 54 | 
            +
                    version: 6.1.6
         | 
| 55 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 56 | 
             
              name: activerecord
         | 
| 57 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 59 | 
             
                - - '='
         | 
| 60 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            -
                    version: 6.1. | 
| 61 | 
            +
                    version: 6.1.6
         | 
| 62 62 | 
             
              type: :runtime
         | 
| 63 63 | 
             
              prerelease: false
         | 
| 64 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 65 | 
             
                requirements:
         | 
| 66 66 | 
             
                - - '='
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            -
                    version: 6.1. | 
| 68 | 
            +
                    version: 6.1.6
         | 
| 69 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 70 | 
             
              name: marcel
         | 
| 71 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 73 | 
             
                - - "~>"
         | 
| 74 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            -
                    version: 0 | 
| 75 | 
            +
                    version: '1.0'
         | 
| 76 76 | 
             
              type: :runtime
         | 
| 77 77 | 
             
              prerelease: false
         | 
| 78 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 79 | 
             
                requirements:
         | 
| 80 80 | 
             
                - - "~>"
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            -
                    version: 0 | 
| 82 | 
            +
                    version: '1.0'
         | 
| 83 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            -
              name:  | 
| 84 | 
            +
              name: mini_mime
         | 
| 85 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
                requirements:
         | 
| 87 | 
            -
                - - " | 
| 87 | 
            +
                - - ">="
         | 
| 88 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            -
                    version:  | 
| 89 | 
            +
                    version: 1.1.0
         | 
| 90 90 | 
             
              type: :runtime
         | 
| 91 91 | 
             
              prerelease: false
         | 
| 92 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 93 | 
             
                requirements:
         | 
| 94 | 
            -
                - - " | 
| 94 | 
            +
                - - ">="
         | 
| 95 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            -
                    version:  | 
| 96 | 
            +
                    version: 1.1.0
         | 
| 97 97 | 
             
            description: Attach cloud and local files in Rails applications.
         | 
| 98 98 | 
             
            email: david@loudthinking.com
         | 
| 99 99 | 
             
            executables: []
         | 
| @@ -109,6 +109,7 @@ files: | |
| 109 109 | 
             
            - app/controllers/active_storage/blobs/redirect_controller.rb
         | 
| 110 110 | 
             
            - app/controllers/active_storage/direct_uploads_controller.rb
         | 
| 111 111 | 
             
            - app/controllers/active_storage/disk_controller.rb
         | 
| 112 | 
            +
            - app/controllers/active_storage/representations/base_controller.rb
         | 
| 112 113 | 
             
            - app/controllers/active_storage/representations/proxy_controller.rb
         | 
| 113 114 | 
             
            - app/controllers/active_storage/representations/redirect_controller.rb
         | 
| 114 115 | 
             
            - app/controllers/concerns/active_storage/file_server.rb
         | 
| @@ -187,10 +188,11 @@ licenses: | |
| 187 188 | 
             
            - MIT
         | 
| 188 189 | 
             
            metadata:
         | 
| 189 190 | 
             
              bug_tracker_uri: https://github.com/rails/rails/issues
         | 
| 190 | 
            -
              changelog_uri: https://github.com/rails/rails/blob/v6.1. | 
| 191 | 
            -
              documentation_uri: https://api.rubyonrails.org/v6.1. | 
| 191 | 
            +
              changelog_uri: https://github.com/rails/rails/blob/v6.1.6/activestorage/CHANGELOG.md
         | 
| 192 | 
            +
              documentation_uri: https://api.rubyonrails.org/v6.1.6/
         | 
| 192 193 | 
             
              mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
         | 
| 193 | 
            -
              source_code_uri: https://github.com/rails/rails/tree/v6.1. | 
| 194 | 
            +
              source_code_uri: https://github.com/rails/rails/tree/v6.1.6/activestorage
         | 
| 195 | 
            +
              rubygems_mfa_required: 'true'
         | 
| 194 196 | 
             
            post_install_message:
         | 
| 195 197 | 
             
            rdoc_options: []
         | 
| 196 198 | 
             
            require_paths:
         | 
| @@ -206,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 206 208 | 
             
                - !ruby/object:Gem::Version
         | 
| 207 209 | 
             
                  version: '0'
         | 
| 208 210 | 
             
            requirements: []
         | 
| 209 | 
            -
            rubygems_version: 3. | 
| 211 | 
            +
            rubygems_version: 3.3.7
         | 
| 210 212 | 
             
            signing_key:
         | 
| 211 213 | 
             
            specification_version: 4
         | 
| 212 214 | 
             
            summary: Local and cloud file storage framework.
         |