activestorage 8.0.2.1 → 8.1.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -54
- data/README.md +6 -3
- data/app/assets/javascripts/activestorage.esm.js +37 -1
- data/app/assets/javascripts/activestorage.js +37 -1
- data/app/controllers/active_storage/disk_controller.rb +2 -2
- data/app/javascript/activestorage/direct_upload_controller.js +48 -1
- data/app/models/active_storage/blob/representable.rb +66 -0
- data/app/models/active_storage/blob.rb +1 -1
- data/app/models/active_storage/filename.rb +1 -0
- data/app/models/active_storage/variant.rb +7 -7
- data/app/models/active_storage/variation.rb +1 -1
- data/lib/active_storage/analyzer/image_analyzer/image_magick.rb +7 -11
- data/lib/active_storage/analyzer/image_analyzer/vips.rb +10 -11
- data/lib/active_storage/analyzer/image_analyzer.rb +5 -0
- data/lib/active_storage/attached/model.rb +4 -4
- data/lib/active_storage/attached.rb +0 -1
- data/lib/active_storage/downloader.rb +1 -1
- data/lib/active_storage/engine.rb +48 -10
- data/lib/active_storage/fixture_set.rb +1 -1
- data/lib/active_storage/gem_version.rb +3 -3
- data/lib/active_storage/service/configurator.rb +6 -0
- data/lib/active_storage/service/disk_service.rb +1 -1
- data/lib/active_storage/service/gcs_service.rb +10 -2
- data/lib/active_storage/service/mirror_service.rb +1 -1
- data/lib/active_storage/service/registry.rb +6 -0
- data/lib/active_storage/service/s3_service.rb +19 -4
- data/lib/active_storage/service.rb +4 -1
- data/lib/active_storage/transformers/image_magick.rb +72 -0
- data/lib/active_storage/transformers/image_processing_transformer.rb +5 -67
- data/lib/active_storage/transformers/vips.rb +11 -0
- data/lib/active_storage.rb +13 -0
- metadata +14 -13
- data/lib/active_storage/service/azure_storage_service.rb +0 -201
@@ -12,8 +12,6 @@ require "active_storage/previewer/mupdf_previewer"
|
|
12
12
|
require "active_storage/previewer/video_previewer"
|
13
13
|
|
14
14
|
require "active_storage/analyzer/image_analyzer"
|
15
|
-
require "active_storage/analyzer/image_analyzer/image_magick"
|
16
|
-
require "active_storage/analyzer/image_analyzer/vips"
|
17
15
|
require "active_storage/analyzer/video_analyzer"
|
18
16
|
require "active_storage/analyzer/audio_analyzer"
|
19
17
|
|
@@ -27,7 +25,7 @@ module ActiveStorage
|
|
27
25
|
|
28
26
|
config.active_storage = ActiveSupport::OrderedOptions.new
|
29
27
|
config.active_storage.previewers = [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
|
30
|
-
config.active_storage.analyzers = [ ActiveStorage::Analyzer::
|
28
|
+
config.active_storage.analyzers = [ ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer ]
|
31
29
|
config.active_storage.paths = ActiveSupport::OrderedOptions.new
|
32
30
|
config.active_storage.queues = ActiveSupport::InheritableOptions.new
|
33
31
|
config.active_storage.precompile_assets = true
|
@@ -84,11 +82,49 @@ module ActiveStorage
|
|
84
82
|
end
|
85
83
|
|
86
84
|
initializer "active_storage.configs" do
|
85
|
+
config.before_initialize do |app|
|
86
|
+
ActiveStorage.touch_attachment_records = app.config.active_storage.touch_attachment_records != false
|
87
|
+
end
|
88
|
+
|
87
89
|
config.after_initialize do |app|
|
88
90
|
ActiveStorage.logger = app.config.active_storage.logger || Rails.logger
|
89
|
-
ActiveStorage.variant_processor = app.config.active_storage.variant_processor
|
91
|
+
ActiveStorage.variant_processor = app.config.active_storage.variant_processor
|
90
92
|
ActiveStorage.previewers = app.config.active_storage.previewers || []
|
91
|
-
|
93
|
+
|
94
|
+
begin
|
95
|
+
analyzer, transformer =
|
96
|
+
case ActiveStorage.variant_processor
|
97
|
+
when :vips
|
98
|
+
[
|
99
|
+
ActiveStorage::Analyzer::ImageAnalyzer::Vips,
|
100
|
+
ActiveStorage::Transformers::Vips
|
101
|
+
]
|
102
|
+
when :mini_magick
|
103
|
+
[
|
104
|
+
ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick,
|
105
|
+
ActiveStorage::Transformers::ImageMagick
|
106
|
+
]
|
107
|
+
end
|
108
|
+
|
109
|
+
ActiveStorage.analyzers = [analyzer].compact.concat(app.config.active_storage.analyzers || [])
|
110
|
+
ActiveStorage.variant_transformer = transformer
|
111
|
+
rescue LoadError => error
|
112
|
+
case error.message
|
113
|
+
when /libvips/
|
114
|
+
ActiveStorage.logger.warn <<~WARNING.squish
|
115
|
+
Using vips to process variants requires the libvips library.
|
116
|
+
Please install libvips using the instructions on the libvips website.
|
117
|
+
WARNING
|
118
|
+
when /image_processing/
|
119
|
+
ActiveStorage.logger.warn <<~WARNING.squish
|
120
|
+
Generating image variants require the image_processing gem.
|
121
|
+
Please add `gem 'image_processing', '~> 1.2'` to your Gemfile.
|
122
|
+
WARNING
|
123
|
+
else
|
124
|
+
raise
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
92
128
|
ActiveStorage.paths = app.config.active_storage.paths || {}
|
93
129
|
ActiveStorage.routes_prefix = app.config.active_storage.routes_prefix || "/rails/active_storage"
|
94
130
|
ActiveStorage.draw_routes = app.config.active_storage.draw_routes != false
|
@@ -112,13 +148,15 @@ module ActiveStorage
|
|
112
148
|
ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
|
113
149
|
ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
|
114
150
|
ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
|
115
|
-
ActiveStorage.touch_attachment_records = app.config.active_storage.touch_attachment_records != false
|
116
151
|
ActiveStorage.service_urls_expire_in = app.config.active_storage.service_urls_expire_in || 5.minutes
|
117
152
|
ActiveStorage.urls_expire_in = app.config.active_storage.urls_expire_in
|
118
153
|
ActiveStorage.content_types_allowed_inline = app.config.active_storage.content_types_allowed_inline || []
|
119
154
|
ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
|
120
155
|
ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
|
121
156
|
ActiveStorage.track_variants = app.config.active_storage.track_variants || false
|
157
|
+
if app.config.active_storage.checksum_implementation
|
158
|
+
ActiveStorage.checksum_implementation = app.config.active_storage.checksum_implementation
|
159
|
+
end
|
122
160
|
end
|
123
161
|
end
|
124
162
|
|
@@ -136,9 +174,9 @@ module ActiveStorage
|
|
136
174
|
end
|
137
175
|
end
|
138
176
|
|
139
|
-
initializer "active_storage.services" do
|
177
|
+
initializer "active_storage.services" do |app|
|
140
178
|
ActiveSupport.on_load(:active_storage_blob) do
|
141
|
-
configs =
|
179
|
+
configs = app.config.active_storage.service_configurations ||=
|
142
180
|
begin
|
143
181
|
config_file = Rails.root.join("config/storage/#{Rails.env}.yml")
|
144
182
|
config_file = Rails.root.join("config/storage.yml") unless config_file.exist?
|
@@ -149,7 +187,7 @@ module ActiveStorage
|
|
149
187
|
|
150
188
|
ActiveStorage::Blob.services = ActiveStorage::Service::Registry.new(configs)
|
151
189
|
|
152
|
-
if config_choice =
|
190
|
+
if config_choice = app.config.active_storage.service
|
153
191
|
ActiveStorage::Blob.service = ActiveStorage::Blob.services.fetch(config_choice)
|
154
192
|
end
|
155
193
|
end
|
@@ -171,7 +209,7 @@ module ActiveStorage
|
|
171
209
|
initializer "action_view.configuration" do
|
172
210
|
config.after_initialize do |app|
|
173
211
|
ActiveSupport.on_load(:action_view) do
|
174
|
-
multiple_file_field_include_hidden = app.config.active_storage.
|
212
|
+
multiple_file_field_include_hidden = app.config.active_storage.multiple_file_field_include_hidden
|
175
213
|
|
176
214
|
unless multiple_file_field_include_hidden.nil?
|
177
215
|
ActionView::Helpers::FormHelper.multiple_file_field_include_hidden = multiple_file_field_include_hidden
|
@@ -50,7 +50,7 @@ module ActiveStorage
|
|
50
50
|
# by ActiveSupport::Testing::FileFixtures.file_fixture, and upload
|
51
51
|
# the file to the Service
|
52
52
|
#
|
53
|
-
#
|
53
|
+
# ==== Examples
|
54
54
|
#
|
55
55
|
# # tests/fixtures/active_storage/blobs.yml
|
56
56
|
# second_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
|
@@ -19,6 +19,12 @@ module ActiveStorage
|
|
19
19
|
)
|
20
20
|
end
|
21
21
|
|
22
|
+
def inspect # :nodoc:
|
23
|
+
attrs = configurations.any? ?
|
24
|
+
" configurations=[#{configurations.keys.map(&:inspect).join(", ")}]" : ""
|
25
|
+
"#<#{self.class}#{attrs}>"
|
26
|
+
end
|
27
|
+
|
22
28
|
private
|
23
29
|
def config_for(name)
|
24
30
|
configurations.fetch name do
|
@@ -161,7 +161,7 @@ module ActiveStorage
|
|
161
161
|
end
|
162
162
|
|
163
163
|
def ensure_integrity_of(key, checksum)
|
164
|
-
unless
|
164
|
+
unless ActiveStorage.checksum_implementation.file(path_for(key)).base64digest == checksum
|
165
165
|
delete key
|
166
166
|
raise ActiveStorage::IntegrityError
|
167
167
|
end
|
@@ -213,8 +213,16 @@ module ActiveStorage
|
|
213
213
|
lambda do |string_to_sign|
|
214
214
|
iam_client = Google::Apis::IamcredentialsV1::IAMCredentialsService.new
|
215
215
|
|
216
|
-
|
217
|
-
|
216
|
+
# We explicitly do not set iam_client.authorization so that it uses the
|
217
|
+
# credentials set by the application at Google::Apis::RequestOptions.default.authorization.
|
218
|
+
# If the application does not set it, the GCP libraries will automatically
|
219
|
+
# determine it on each call. This code previously explicitly set the
|
220
|
+
# authorization to Google::Auth.get_application_default which triggers
|
221
|
+
# an explicit call to the metadata server - given this lambda is called
|
222
|
+
# for a significant number of file operations, it can lead to considerable
|
223
|
+
# tail latencies and even metadata server overloads. Additionally, that
|
224
|
+
# prevented applications from being able to configure the credentials
|
225
|
+
# used to perform the signature operation.
|
218
226
|
|
219
227
|
request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
|
220
228
|
payload: string_to_sign
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/module/delegation"
|
4
3
|
|
5
4
|
module ActiveStorage
|
6
5
|
# = Active Storage Mirror \Service
|
@@ -31,6 +30,7 @@ module ActiveStorage
|
|
31
30
|
def initialize(primary:, mirrors:)
|
32
31
|
@primary, @mirrors = primary, mirrors
|
33
32
|
@executor = Concurrent::ThreadPoolExecutor.new(
|
33
|
+
name: "ActiveStorage-mirror-service",
|
34
34
|
min_threads: 1,
|
35
35
|
max_threads: mirrors.size,
|
36
36
|
max_queue: 0,
|
@@ -22,6 +22,12 @@ module ActiveStorage
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def inspect # :nodoc:
|
26
|
+
attrs = configurations.any? ?
|
27
|
+
" configurations=[#{configurations.keys.map(&:inspect).join(", ")}]" : ""
|
28
|
+
"#<#{self.class}#{attrs}>"
|
29
|
+
end
|
30
|
+
|
25
31
|
private
|
26
32
|
attr_reader :configurations, :services
|
27
33
|
|
@@ -16,6 +16,7 @@ module ActiveStorage
|
|
16
16
|
|
17
17
|
def initialize(bucket:, upload: {}, public: false, **options)
|
18
18
|
@client = Aws::S3::Resource.new(**options)
|
19
|
+
@transfer_manager = Aws::S3::TransferManager.new(client: @client.client) if defined?(Aws::S3::TransferManager)
|
19
20
|
@bucket = @client.bucket(bucket)
|
20
21
|
|
21
22
|
@multipart_upload_threshold = upload.delete(:multipart_threshold) || 100.megabytes
|
@@ -100,7 +101,8 @@ module ActiveStorage
|
|
100
101
|
def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
|
101
102
|
content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
|
102
103
|
|
103
|
-
|
104
|
+
upload_stream(
|
105
|
+
key: destination_key,
|
104
106
|
content_type: content_type,
|
105
107
|
content_disposition: content_disposition,
|
106
108
|
part_size: MINIMUM_UPLOAD_PART_SIZE,
|
@@ -116,6 +118,14 @@ module ActiveStorage
|
|
116
118
|
end
|
117
119
|
|
118
120
|
private
|
121
|
+
def upload_stream(key:, **options, &block)
|
122
|
+
if @transfer_manager
|
123
|
+
@transfer_manager.upload_stream(key: key, bucket: bucket.name, **options, &block)
|
124
|
+
else
|
125
|
+
object_for(key).upload_stream(**options, &block)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
119
129
|
def private_url(key, expires_in:, filename:, disposition:, content_type:, **client_opts)
|
120
130
|
object_for(key).presigned_url :get, expires_in: expires_in.to_i,
|
121
131
|
response_content_disposition: content_disposition_with(type: disposition, filename: filename),
|
@@ -126,7 +136,6 @@ module ActiveStorage
|
|
126
136
|
object_for(key).public_url(**client_opts)
|
127
137
|
end
|
128
138
|
|
129
|
-
|
130
139
|
MAXIMUM_UPLOAD_PARTS_COUNT = 10000
|
131
140
|
MINIMUM_UPLOAD_PART_SIZE = 5.megabytes
|
132
141
|
|
@@ -139,12 +148,18 @@ module ActiveStorage
|
|
139
148
|
def upload_with_multipart(key, io, content_type: nil, content_disposition: nil, custom_metadata: {})
|
140
149
|
part_size = [ io.size.fdiv(MAXIMUM_UPLOAD_PARTS_COUNT).ceil, MINIMUM_UPLOAD_PART_SIZE ].max
|
141
150
|
|
142
|
-
|
151
|
+
upload_stream(
|
152
|
+
key: key,
|
153
|
+
content_type: content_type,
|
154
|
+
content_disposition: content_disposition,
|
155
|
+
part_size: part_size,
|
156
|
+
metadata: custom_metadata,
|
157
|
+
**upload_options
|
158
|
+
) do |out|
|
143
159
|
IO.copy_stream(io, out)
|
144
160
|
end
|
145
161
|
end
|
146
162
|
|
147
|
-
|
148
163
|
def object_for(key)
|
149
164
|
bucket.object(key)
|
150
165
|
end
|
@@ -15,7 +15,6 @@ module ActiveStorage
|
|
15
15
|
# * +Disk+, to manage attachments saved directly on the hard drive.
|
16
16
|
# * +GCS+, to manage attachments through Google Cloud Storage.
|
17
17
|
# * +S3+, to manage attachments through Amazon S3.
|
18
|
-
# * +AzureStorage+, to manage attachments through Microsoft Azure Storage.
|
19
18
|
# * +Mirror+, to be able to use several services to manage attachments.
|
20
19
|
#
|
21
20
|
# Inside a \Rails application, you can set-up your services through the
|
@@ -148,6 +147,10 @@ module ActiveStorage
|
|
148
147
|
@public
|
149
148
|
end
|
150
149
|
|
150
|
+
def inspect # :nodoc:
|
151
|
+
"#<#{self.class}#{name.present? ? " name=#{name.inspect}" : ""}>"
|
152
|
+
end
|
153
|
+
|
151
154
|
private
|
152
155
|
def private_url(key, expires_in:, filename:, disposition:, content_type:, **)
|
153
156
|
raise NotImplementedError
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveStorage
|
4
|
+
module Transformers
|
5
|
+
class ImageMagick < ImageProcessingTransformer
|
6
|
+
private
|
7
|
+
def processor
|
8
|
+
ImageProcessing::MiniMagick
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate_transformation(name, argument)
|
12
|
+
method_name = name.to_s.tr("-", "_")
|
13
|
+
|
14
|
+
unless ActiveStorage.supported_image_processing_methods.include?(method_name)
|
15
|
+
raise UnsupportedImageProcessingMethod, <<~ERROR.squish
|
16
|
+
The provided transformation method is not supported: #{method_name}.
|
17
|
+
ERROR
|
18
|
+
end
|
19
|
+
|
20
|
+
if argument.present?
|
21
|
+
if argument.is_a?(String) || argument.is_a?(Symbol)
|
22
|
+
validate_arg_string(argument)
|
23
|
+
elsif argument.is_a?(Array)
|
24
|
+
validate_arg_array(argument)
|
25
|
+
elsif argument.is_a?(Hash)
|
26
|
+
validate_arg_hash(argument)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_arg_string(argument)
|
34
|
+
unsupported_arguments = ActiveStorage.unsupported_image_processing_arguments.any? do |bad_arg|
|
35
|
+
argument.to_s.downcase.include?(bad_arg)
|
36
|
+
end
|
37
|
+
|
38
|
+
raise UnsupportedImageProcessingArgument if unsupported_arguments
|
39
|
+
end
|
40
|
+
|
41
|
+
def validate_arg_array(argument)
|
42
|
+
argument.each do |arg|
|
43
|
+
if arg.is_a?(Integer) || arg.is_a?(Float)
|
44
|
+
next
|
45
|
+
elsif arg.is_a?(String) || arg.is_a?(Symbol)
|
46
|
+
validate_arg_string(arg)
|
47
|
+
elsif arg.is_a?(Array)
|
48
|
+
validate_arg_array(arg)
|
49
|
+
elsif arg.is_a?(Hash)
|
50
|
+
validate_arg_hash(arg)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def validate_arg_hash(argument)
|
56
|
+
argument.each do |key, value|
|
57
|
+
validate_arg_string(key)
|
58
|
+
|
59
|
+
if value.is_a?(Integer) || value.is_a?(Float)
|
60
|
+
next
|
61
|
+
elsif value.is_a?(String) || value.is_a?(Symbol)
|
62
|
+
validate_arg_string(value)
|
63
|
+
elsif value.is_a?(Array)
|
64
|
+
validate_arg_array(value)
|
65
|
+
elsif value.is_a?(Hash)
|
66
|
+
validate_arg_hash(value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -25,22 +25,9 @@ module ActiveStorage
|
|
25
25
|
call
|
26
26
|
end
|
27
27
|
|
28
|
-
def processor
|
29
|
-
ImageProcessing.const_get(ActiveStorage.variant_processor.to_s.camelize)
|
30
|
-
end
|
31
|
-
|
32
28
|
def operations
|
33
29
|
transformations.each_with_object([]) do |(name, argument), list|
|
34
|
-
|
35
|
-
validate_transformation(name, argument)
|
36
|
-
end
|
37
|
-
|
38
|
-
if name.to_s == "combine_options"
|
39
|
-
raise ArgumentError, <<~ERROR.squish
|
40
|
-
Active Storage's ImageProcessing transformer doesn't support :combine_options,
|
41
|
-
as it always generates a single command.
|
42
|
-
ERROR
|
43
|
-
end
|
30
|
+
validate_transformation(name, argument)
|
44
31
|
|
45
32
|
if argument.present?
|
46
33
|
list << [ name, argument ]
|
@@ -49,61 +36,12 @@ module ActiveStorage
|
|
49
36
|
end
|
50
37
|
|
51
38
|
def validate_transformation(name, argument)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
One or more of the provided transformation methods is not supported.
|
39
|
+
if name.to_s == "combine_options"
|
40
|
+
raise ArgumentError, <<~ERROR.squish
|
41
|
+
Active Storage's ImageProcessing transformer doesn't support :combine_options,
|
42
|
+
as it always generates a single command.
|
57
43
|
ERROR
|
58
44
|
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
45
|
end
|
108
46
|
end
|
109
47
|
end
|
data/lib/active_storage.rb
CHANGED
@@ -49,6 +49,8 @@ module ActiveStorage
|
|
49
49
|
mattr_accessor :verifier
|
50
50
|
mattr_accessor :variant_processor, default: :mini_magick
|
51
51
|
|
52
|
+
mattr_accessor :variant_transformer
|
53
|
+
|
52
54
|
mattr_accessor :queues, default: {}
|
53
55
|
|
54
56
|
mattr_accessor :previewers, default: []
|
@@ -360,6 +362,15 @@ module ActiveStorage
|
|
360
362
|
|
361
363
|
mattr_accessor :track_variants, default: false
|
362
364
|
|
365
|
+
singleton_class.attr_accessor :checksum_implementation
|
366
|
+
@checksum_implementation = OpenSSL::Digest::MD5
|
367
|
+
begin
|
368
|
+
@checksum_implementation.hexdigest("test")
|
369
|
+
rescue # OpenSSL may have MD5 disabled
|
370
|
+
require "digest/md5"
|
371
|
+
@checksum_implementation = Digest::MD5
|
372
|
+
end
|
373
|
+
|
363
374
|
mattr_accessor :video_preview_arguments, default: "-y -vframes 1 -f image2"
|
364
375
|
|
365
376
|
module Transformers
|
@@ -367,5 +378,7 @@ module ActiveStorage
|
|
367
378
|
|
368
379
|
autoload :Transformer
|
369
380
|
autoload :ImageProcessingTransformer
|
381
|
+
autoload :Vips
|
382
|
+
autoload :ImageMagick
|
370
383
|
end
|
371
384
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activestorage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0.
|
4
|
+
version: 8.1.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
@@ -15,56 +15,56 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 8.0.
|
18
|
+
version: 8.1.0.beta1
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - '='
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: 8.0.
|
25
|
+
version: 8.1.0.beta1
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: actionpack
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - '='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 8.0.
|
32
|
+
version: 8.1.0.beta1
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - '='
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 8.0.
|
39
|
+
version: 8.1.0.beta1
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: activejob
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - '='
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 8.0.
|
46
|
+
version: 8.1.0.beta1
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - '='
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 8.0.
|
53
|
+
version: 8.1.0.beta1
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
55
|
name: activerecord
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - '='
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 8.0.
|
60
|
+
version: 8.1.0.beta1
|
61
61
|
type: :runtime
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - '='
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: 8.0.
|
67
|
+
version: 8.1.0.beta1
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
69
|
name: marcel
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,15 +173,16 @@ files:
|
|
173
173
|
- lib/active_storage/previewer/video_previewer.rb
|
174
174
|
- lib/active_storage/reflection.rb
|
175
175
|
- lib/active_storage/service.rb
|
176
|
-
- lib/active_storage/service/azure_storage_service.rb
|
177
176
|
- lib/active_storage/service/configurator.rb
|
178
177
|
- lib/active_storage/service/disk_service.rb
|
179
178
|
- lib/active_storage/service/gcs_service.rb
|
180
179
|
- lib/active_storage/service/mirror_service.rb
|
181
180
|
- lib/active_storage/service/registry.rb
|
182
181
|
- lib/active_storage/service/s3_service.rb
|
182
|
+
- lib/active_storage/transformers/image_magick.rb
|
183
183
|
- lib/active_storage/transformers/image_processing_transformer.rb
|
184
184
|
- lib/active_storage/transformers/transformer.rb
|
185
|
+
- lib/active_storage/transformers/vips.rb
|
185
186
|
- lib/active_storage/version.rb
|
186
187
|
- lib/tasks/activestorage.rake
|
187
188
|
homepage: https://rubyonrails.org
|
@@ -189,10 +190,10 @@ licenses:
|
|
189
190
|
- MIT
|
190
191
|
metadata:
|
191
192
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
192
|
-
changelog_uri: https://github.com/rails/rails/blob/v8.0.
|
193
|
-
documentation_uri: https://api.rubyonrails.org/v8.0.
|
193
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.1.0.beta1/activestorage/CHANGELOG.md
|
194
|
+
documentation_uri: https://api.rubyonrails.org/v8.1.0.beta1/
|
194
195
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
195
|
-
source_code_uri: https://github.com/rails/rails/tree/v8.0.
|
196
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.1.0.beta1/activestorage
|
196
197
|
rubygems_mfa_required: 'true'
|
197
198
|
rdoc_options: []
|
198
199
|
require_paths:
|