activestorage 7.0.0 → 7.1.0
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 +158 -178
- data/MIT-LICENSE +1 -1
- data/README.md +7 -7
- data/app/assets/javascripts/activestorage.esm.js +10 -18
- data/app/assets/javascripts/activestorage.js +11 -17
- data/app/controllers/active_storage/base_controller.rb +1 -1
- data/app/controllers/active_storage/blobs/proxy_controller.rb +2 -0
- data/app/controllers/active_storage/direct_uploads_controller.rb +1 -7
- data/app/controllers/active_storage/disk_controller.rb +4 -2
- data/app/controllers/active_storage/representations/proxy_controller.rb +3 -0
- data/app/controllers/concerns/active_storage/disable_session.rb +12 -0
- data/app/controllers/concerns/active_storage/file_server.rb +4 -1
- data/app/controllers/concerns/active_storage/streaming.rb +1 -0
- data/app/javascript/activestorage/blob_record.js +6 -10
- data/app/javascript/activestorage/direct_upload.js +3 -4
- data/app/javascript/activestorage/direct_upload_controller.js +1 -9
- data/app/javascript/activestorage/index.js +3 -1
- data/app/jobs/active_storage/analyze_job.rb +1 -1
- data/app/jobs/active_storage/mirror_job.rb +1 -1
- data/app/jobs/active_storage/purge_job.rb +1 -1
- data/app/jobs/active_storage/transform_job.rb +12 -0
- data/app/models/active_storage/attachment.rb +88 -14
- data/app/models/active_storage/blob/analyzable.rb +4 -3
- data/app/models/active_storage/blob/identifiable.rb +1 -0
- data/app/models/active_storage/blob/representable.rb +7 -3
- data/app/models/active_storage/blob.rb +27 -47
- data/app/models/active_storage/current.rb +0 -10
- data/app/models/active_storage/filename.rb +2 -0
- data/app/models/active_storage/named_variant.rb +21 -0
- data/app/models/active_storage/preview.rb +5 -3
- data/app/models/active_storage/variant.rb +11 -10
- data/app/models/active_storage/variant_with_record.rb +20 -8
- data/app/models/active_storage/variation.rb +6 -4
- data/config/routes.rb +6 -4
- data/db/migrate/20170806125915_create_active_storage_tables.rb +1 -1
- data/db/update_migrate/20190112182829_add_service_name_to_active_storage_blobs.rb +4 -0
- data/db/update_migrate/20191206030411_create_active_storage_variant_records.rb +2 -0
- data/db/update_migrate/20211119233751_remove_not_null_on_active_storage_blobs_checksum.rb +2 -0
- data/lib/active_storage/analyzer/audio_analyzer.rb +17 -5
- data/lib/active_storage/analyzer/image_analyzer/image_magick.rb +9 -7
- data/lib/active_storage/analyzer/image_analyzer/vips.rb +9 -7
- data/lib/active_storage/analyzer/image_analyzer.rb +2 -0
- data/lib/active_storage/analyzer/video_analyzer.rb +15 -6
- data/lib/active_storage/analyzer.rb +2 -0
- data/lib/active_storage/attached/changes/create_many.rb +8 -3
- data/lib/active_storage/attached/changes/create_one.rb +45 -3
- data/lib/active_storage/attached/many.rb +5 -4
- data/lib/active_storage/attached/model.rb +66 -43
- data/lib/active_storage/attached/one.rb +5 -4
- data/lib/active_storage/attached.rb +2 -0
- data/lib/active_storage/deprecator.rb +7 -0
- data/lib/active_storage/engine.rb +31 -9
- data/lib/active_storage/errors.rb +0 -3
- data/lib/active_storage/fixture_set.rb +7 -8
- data/lib/active_storage/gem_version.rb +2 -2
- data/lib/active_storage/log_subscriber.rb +12 -0
- data/lib/active_storage/previewer/video_previewer.rb +2 -0
- data/lib/active_storage/previewer.rb +8 -1
- data/lib/active_storage/reflection.rb +3 -3
- data/lib/active_storage/service/azure_storage_service.rb +2 -0
- data/lib/active_storage/service/disk_service.rb +2 -0
- data/lib/active_storage/service/gcs_service.rb +11 -20
- data/lib/active_storage/service/mirror_service.rb +10 -5
- data/lib/active_storage/service/s3_service.rb +2 -0
- data/lib/active_storage/service.rb +4 -2
- data/lib/active_storage/transformers/image_processing_transformer.rb +65 -0
- data/lib/active_storage/transformers/transformer.rb +2 -0
- data/lib/active_storage/version.rb +1 -1
- data/lib/active_storage.rb +310 -4
- metadata +21 -32
- data/lib/active_storage/direct_upload_token.rb +0 -59
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
module ActiveStorage
|
4
4
|
class Attached::Changes::CreateMany # :nodoc:
|
5
|
-
attr_reader :name, :record, :attachables
|
5
|
+
attr_reader :name, :record, :attachables, :pending_uploads
|
6
6
|
|
7
|
-
def initialize(name, record, attachables)
|
7
|
+
def initialize(name, record, attachables, pending_uploads: [])
|
8
8
|
@name, @record, @attachables = name, record, Array(attachables)
|
9
9
|
blobs.each(&:identify_without_saving)
|
10
|
+
@pending_uploads = Array(pending_uploads) + subchanges_without_blobs
|
10
11
|
attachments
|
11
12
|
end
|
12
13
|
|
@@ -19,7 +20,7 @@ module ActiveStorage
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def upload
|
22
|
-
|
23
|
+
pending_uploads.each(&:upload)
|
23
24
|
end
|
24
25
|
|
25
26
|
def save
|
@@ -36,6 +37,10 @@ module ActiveStorage
|
|
36
37
|
ActiveStorage::Attached::Changes::CreateOneOfMany.new(name, record, attachable)
|
37
38
|
end
|
38
39
|
|
40
|
+
def subchanges_without_blobs
|
41
|
+
subchanges.reject { |subchange| subchange.attachable.is_a?(ActiveStorage::Blob) }
|
42
|
+
end
|
43
|
+
|
39
44
|
def assign_associated_attachments
|
40
45
|
record.public_send("#{name}_attachments=", persisted_or_new_attachments)
|
41
46
|
end
|
@@ -22,10 +22,26 @@ module ActiveStorage
|
|
22
22
|
|
23
23
|
def upload
|
24
24
|
case attachable
|
25
|
-
when ActionDispatch::Http::UploadedFile
|
25
|
+
when ActionDispatch::Http::UploadedFile
|
26
26
|
blob.upload_without_unfurling(attachable.open)
|
27
|
+
when Rack::Test::UploadedFile
|
28
|
+
blob.upload_without_unfurling(
|
29
|
+
attachable.respond_to?(:open) ? attachable.open : attachable
|
30
|
+
)
|
27
31
|
when Hash
|
28
32
|
blob.upload_without_unfurling(attachable.fetch(:io))
|
33
|
+
when File
|
34
|
+
blob.upload_without_unfurling(attachable)
|
35
|
+
when Pathname
|
36
|
+
blob.upload_without_unfurling(attachable.open)
|
37
|
+
when ActiveStorage::Blob
|
38
|
+
when String
|
39
|
+
else
|
40
|
+
raise(
|
41
|
+
ArgumentError,
|
42
|
+
"Could not upload: expected attachable, " \
|
43
|
+
"got #{attachable.inspect}"
|
44
|
+
)
|
29
45
|
end
|
30
46
|
end
|
31
47
|
|
@@ -53,7 +69,7 @@ module ActiveStorage
|
|
53
69
|
case attachable
|
54
70
|
when ActiveStorage::Blob
|
55
71
|
attachable
|
56
|
-
when ActionDispatch::Http::UploadedFile
|
72
|
+
when ActionDispatch::Http::UploadedFile
|
57
73
|
ActiveStorage::Blob.build_after_unfurling(
|
58
74
|
io: attachable.open,
|
59
75
|
filename: attachable.original_filename,
|
@@ -61,6 +77,14 @@ module ActiveStorage
|
|
61
77
|
record: record,
|
62
78
|
service_name: attachment_service_name
|
63
79
|
)
|
80
|
+
when Rack::Test::UploadedFile
|
81
|
+
ActiveStorage::Blob.build_after_unfurling(
|
82
|
+
io: attachable.respond_to?(:open) ? attachable.open : attachable,
|
83
|
+
filename: attachable.original_filename,
|
84
|
+
content_type: attachable.content_type,
|
85
|
+
record: record,
|
86
|
+
service_name: attachment_service_name
|
87
|
+
)
|
64
88
|
when Hash
|
65
89
|
ActiveStorage::Blob.build_after_unfurling(
|
66
90
|
**attachable.reverse_merge(
|
@@ -70,8 +94,26 @@ module ActiveStorage
|
|
70
94
|
)
|
71
95
|
when String
|
72
96
|
ActiveStorage::Blob.find_signed!(attachable, record: record)
|
97
|
+
when File
|
98
|
+
ActiveStorage::Blob.build_after_unfurling(
|
99
|
+
io: attachable,
|
100
|
+
filename: File.basename(attachable),
|
101
|
+
record: record,
|
102
|
+
service_name: attachment_service_name
|
103
|
+
)
|
104
|
+
when Pathname
|
105
|
+
ActiveStorage::Blob.build_after_unfurling(
|
106
|
+
io: attachable.open,
|
107
|
+
filename: File.basename(attachable),
|
108
|
+
record: record,
|
109
|
+
service_name: attachment_service_name
|
110
|
+
)
|
73
111
|
else
|
74
|
-
raise
|
112
|
+
raise(
|
113
|
+
ArgumentError,
|
114
|
+
"Could not find or build blob: expected attachable, " \
|
115
|
+
"got #{attachable.inspect}"
|
116
|
+
)
|
75
117
|
end
|
76
118
|
end
|
77
119
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveStorage
|
4
|
+
# = Active Storage \Attached \Many
|
5
|
+
#
|
4
6
|
# Decorated proxy object representing of multiple attachments to a model.
|
5
7
|
class Attached::Many < Attached
|
6
8
|
##
|
@@ -47,12 +49,11 @@ module ActiveStorage
|
|
47
49
|
# document.images.attach(io: File.open("/path/to/racecar.jpg"), filename: "racecar.jpg", content_type: "image/jpeg")
|
48
50
|
# document.images.attach([ first_blob, second_blob ])
|
49
51
|
def attach(*attachables)
|
52
|
+
record.public_send("#{name}=", blobs + attachables.flatten)
|
50
53
|
if record.persisted? && !record.changed?
|
51
|
-
|
52
|
-
record.save
|
53
|
-
else
|
54
|
-
record.public_send("#{name}=", (change&.attachables || blobs) + attachables.flatten)
|
54
|
+
return if !record.save
|
55
55
|
end
|
56
|
+
record.public_send("#{name}")
|
56
57
|
end
|
57
58
|
|
58
59
|
# Returns true if any attachments have been made.
|
@@ -3,10 +3,54 @@
|
|
3
3
|
require "active_support/core_ext/object/try"
|
4
4
|
|
5
5
|
module ActiveStorage
|
6
|
+
# = Active Storage \Attached \Model
|
7
|
+
#
|
6
8
|
# Provides the class-level DSL for declaring an Active Record model's attachments.
|
7
9
|
module Attached::Model
|
8
10
|
extend ActiveSupport::Concern
|
9
11
|
|
12
|
+
##
|
13
|
+
# :method: *_attachment
|
14
|
+
#
|
15
|
+
# Returns the attachment for the +has_one_attached+.
|
16
|
+
#
|
17
|
+
# User.last.avatar_attachment
|
18
|
+
|
19
|
+
##
|
20
|
+
# :method: *_attachments
|
21
|
+
#
|
22
|
+
# Returns the attachments for the +has_many_attached+.
|
23
|
+
#
|
24
|
+
# Gallery.last.photos_attachments
|
25
|
+
|
26
|
+
##
|
27
|
+
# :method: *_blob
|
28
|
+
#
|
29
|
+
# Returns the blob for the +has_one_attached+ attachment.
|
30
|
+
#
|
31
|
+
# User.last.avatar_blob
|
32
|
+
|
33
|
+
##
|
34
|
+
# :method: *_blobs
|
35
|
+
#
|
36
|
+
# Returns the blobs for the +has_many_attached+ attachments.
|
37
|
+
#
|
38
|
+
# Gallery.last.photos_blobs
|
39
|
+
|
40
|
+
##
|
41
|
+
# :method: with_attached_*
|
42
|
+
#
|
43
|
+
# Includes the attached blobs in your query to avoid N+1 queries.
|
44
|
+
#
|
45
|
+
# If +ActiveStorage.track_variants+ is enabled, it will also include the
|
46
|
+
# variants record and their attached blobs.
|
47
|
+
#
|
48
|
+
# User.with_attached_avatar
|
49
|
+
#
|
50
|
+
# Use the plural form for +has_many_attached+:
|
51
|
+
#
|
52
|
+
# Gallery.with_attached_photos
|
53
|
+
|
10
54
|
class_methods do
|
11
55
|
# Specifies the relation between a single attachment and the model.
|
12
56
|
#
|
@@ -59,7 +103,7 @@ module ActiveStorage
|
|
59
103
|
|
60
104
|
def #{name}=(attachable)
|
61
105
|
attachment_changes["#{name}"] =
|
62
|
-
if attachable.nil?
|
106
|
+
if attachable.nil? || attachable == ""
|
63
107
|
ActiveStorage::Attached::Changes::DeleteOne.new("#{name}", self)
|
64
108
|
else
|
65
109
|
ActiveStorage::Attached::Changes::CreateOne.new("#{name}", self, attachable)
|
@@ -70,7 +114,13 @@ module ActiveStorage
|
|
70
114
|
has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record, inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
|
71
115
|
has_one :"#{name}_blob", through: :"#{name}_attachment", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
|
72
116
|
|
73
|
-
scope :"with_attached_#{name}", -> {
|
117
|
+
scope :"with_attached_#{name}", -> {
|
118
|
+
if ActiveStorage.track_variants
|
119
|
+
includes("#{name}_attachment": { blob: { variant_records: { image_attachment: :blob } } })
|
120
|
+
else
|
121
|
+
includes("#{name}_attachment": :blob)
|
122
|
+
end
|
123
|
+
}
|
74
124
|
|
75
125
|
after_save { attachment_changes[name.to_s]&.save }
|
76
126
|
|
@@ -138,57 +188,22 @@ module ActiveStorage
|
|
138
188
|
|
139
189
|
def #{name}=(attachables)
|
140
190
|
attachables = Array(attachables).compact_blank
|
191
|
+
pending_uploads = attachment_changes["#{name}"].try(:pending_uploads)
|
141
192
|
|
142
|
-
if
|
143
|
-
|
144
|
-
if attachables.none?
|
145
|
-
ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
|
146
|
-
else
|
147
|
-
ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables)
|
148
|
-
end
|
193
|
+
attachment_changes["#{name}"] = if attachables.none?
|
194
|
+
ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
|
149
195
|
else
|
150
|
-
|
151
|
-
"config.active_storage.replace_on_assign_to_many is deprecated and will be removed in Rails 7.1. " \
|
152
|
-
"Make sure that your code works well with config.active_storage.replace_on_assign_to_many set to true before upgrading. " \
|
153
|
-
"To append new attachables to the Active Storage association, prefer using `attach`. " \
|
154
|
-
"Using association setter would result in purging the existing attached attachments and replacing them with new ones."
|
155
|
-
|
156
|
-
if attachables.any?
|
157
|
-
attachment_changes["#{name}"] =
|
158
|
-
ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, #{name}.blobs + attachables)
|
159
|
-
end
|
196
|
+
ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables, pending_uploads: pending_uploads)
|
160
197
|
end
|
161
198
|
end
|
162
199
|
CODE
|
163
200
|
|
164
|
-
has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
|
165
|
-
def purge
|
166
|
-
deprecate(:purge)
|
167
|
-
each(&:purge)
|
168
|
-
reset
|
169
|
-
end
|
170
|
-
|
171
|
-
def purge_later
|
172
|
-
deprecate(:purge_later)
|
173
|
-
each(&:purge_later)
|
174
|
-
reset
|
175
|
-
end
|
176
|
-
|
177
|
-
private
|
178
|
-
def deprecate(action)
|
179
|
-
reflection_name = proxy_association.reflection.name
|
180
|
-
attached_name = reflection_name.to_s.partition("_").first
|
181
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
182
|
-
Calling `#{action}` from `#{reflection_name}` is deprecated and will be removed in Rails 7.1.
|
183
|
-
To migrate to Rails 7.1's behavior call `#{action}` from `#{attached_name}` instead: `#{attached_name}.#{action}`.
|
184
|
-
MSG
|
185
|
-
end
|
186
|
-
end
|
201
|
+
has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
|
187
202
|
has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
|
188
203
|
|
189
204
|
scope :"with_attached_#{name}", -> {
|
190
205
|
if ActiveStorage.track_variants
|
191
|
-
includes("#{name}_attachments": { blob: :
|
206
|
+
includes("#{name}_attachments": { blob: { variant_records: { image_attachment: :blob } } })
|
192
207
|
else
|
193
208
|
includes("#{name}_attachments": :blob)
|
194
209
|
end
|
@@ -215,6 +230,14 @@ module ActiveStorage
|
|
215
230
|
ActiveStorage::Blob.services.fetch(service) do
|
216
231
|
raise ArgumentError, "Cannot configure service :#{service} for #{name}##{association_name}"
|
217
232
|
end
|
233
|
+
else
|
234
|
+
validate_global_service_configuration
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def validate_global_service_configuration
|
239
|
+
if connected? && ActiveStorage::Blob.table_exists? && Rails.configuration.active_storage.service.nil?
|
240
|
+
raise RuntimeError, "Missing Active Storage service name. Specify Active Storage service name for config.active_storage.service in config/environments/#{Rails.env}.rb"
|
218
241
|
end
|
219
242
|
end
|
220
243
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveStorage
|
4
|
+
# = Active Storage \Attached \One
|
5
|
+
#
|
4
6
|
# Representation of a single attachment to a model.
|
5
7
|
class Attached::One < Attached
|
6
8
|
##
|
@@ -54,12 +56,11 @@ module ActiveStorage
|
|
54
56
|
# person.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpeg")
|
55
57
|
# person.avatar.attach(avatar_blob) # ActiveStorage::Blob object
|
56
58
|
def attach(attachable)
|
59
|
+
record.public_send("#{name}=", attachable)
|
57
60
|
if record.persisted? && !record.changed?
|
58
|
-
record.
|
59
|
-
record.save
|
60
|
-
else
|
61
|
-
record.public_send("#{name}=", attachable)
|
61
|
+
return if !record.save
|
62
62
|
end
|
63
|
+
record.public_send("#{name}")
|
63
64
|
end
|
64
65
|
|
65
66
|
# Returns +true+ if an attachment has been made.
|
@@ -3,6 +3,8 @@
|
|
3
3
|
require "active_support/core_ext/module/delegation"
|
4
4
|
|
5
5
|
module ActiveStorage
|
6
|
+
# = Active Storage \Attached
|
7
|
+
#
|
6
8
|
# Abstract base class for the concrete ActiveStorage::Attached::One and ActiveStorage::Attached::Many
|
7
9
|
# classes that both provide proxy access to the blob association for a record.
|
8
10
|
class Attached
|
@@ -30,13 +30,12 @@ module ActiveStorage
|
|
30
30
|
config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer::Vips, ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick, ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer ]
|
31
31
|
config.active_storage.paths = ActiveSupport::OrderedOptions.new
|
32
32
|
config.active_storage.queues = ActiveSupport::InheritableOptions.new
|
33
|
+
config.active_storage.precompile_assets = true
|
33
34
|
|
34
35
|
config.active_storage.variable_content_types = %w(
|
35
36
|
image/png
|
36
37
|
image/gif
|
37
|
-
image/jpg
|
38
38
|
image/jpeg
|
39
|
-
image/pjpeg
|
40
39
|
image/tiff
|
41
40
|
image/bmp
|
42
41
|
image/vnd.adobe.photoshop
|
@@ -50,13 +49,11 @@ module ActiveStorage
|
|
50
49
|
config.active_storage.web_image_content_types = %w(
|
51
50
|
image/png
|
52
51
|
image/jpeg
|
53
|
-
image/jpg
|
54
52
|
image/gif
|
55
53
|
)
|
56
54
|
|
57
55
|
config.active_storage.content_types_to_serve_as_binary = %w(
|
58
56
|
text/html
|
59
|
-
text/javascript
|
60
57
|
image/svg+xml
|
61
58
|
application/postscript
|
62
59
|
application/x-shockwave-flash
|
@@ -70,7 +67,6 @@ module ActiveStorage
|
|
70
67
|
config.active_storage.content_types_allowed_inline = %w(
|
71
68
|
image/png
|
72
69
|
image/gif
|
73
|
-
image/jpg
|
74
70
|
image/jpeg
|
75
71
|
image/tiff
|
76
72
|
image/bmp
|
@@ -81,6 +77,10 @@ module ActiveStorage
|
|
81
77
|
|
82
78
|
config.eager_load_namespaces << ActiveStorage
|
83
79
|
|
80
|
+
initializer "active_storage.deprecator", before: :load_environment_config do |app|
|
81
|
+
app.deprecators[:active_storage] = ActiveStorage.deprecator
|
82
|
+
end
|
83
|
+
|
84
84
|
initializer "active_storage.configs" do
|
85
85
|
config.after_initialize do |app|
|
86
86
|
ActiveStorage.logger = app.config.active_storage.logger || Rails.logger
|
@@ -92,6 +92,21 @@ module ActiveStorage
|
|
92
92
|
ActiveStorage.draw_routes = app.config.active_storage.draw_routes != false
|
93
93
|
ActiveStorage.resolve_model_to_route = app.config.active_storage.resolve_model_to_route || :rails_storage_redirect
|
94
94
|
|
95
|
+
ActiveStorage.supported_image_processing_methods += app.config.active_storage.supported_image_processing_methods || []
|
96
|
+
ActiveStorage.unsupported_image_processing_arguments = app.config.active_storage.unsupported_image_processing_arguments || %w(
|
97
|
+
-debug
|
98
|
+
-display
|
99
|
+
-distribute-cache
|
100
|
+
-help
|
101
|
+
-path
|
102
|
+
-print
|
103
|
+
-set
|
104
|
+
-verbose
|
105
|
+
-version
|
106
|
+
-write
|
107
|
+
-write-mask
|
108
|
+
)
|
109
|
+
|
95
110
|
ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
|
96
111
|
ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
|
97
112
|
ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
|
@@ -101,9 +116,14 @@ module ActiveStorage
|
|
101
116
|
ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
|
102
117
|
ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
|
103
118
|
|
104
|
-
|
119
|
+
unless app.config.active_storage.silence_invalid_content_types_warning.nil?
|
120
|
+
ActiveStorage.silence_invalid_content_types_warning = app.config.active_storage.silence_invalid_content_types_warning
|
121
|
+
end
|
122
|
+
|
123
|
+
unless app.config.active_storage.replace_on_assign_to_many.nil?
|
124
|
+
ActiveStorage.replace_on_assign_to_many = app.config.active_storage.replace_on_assign_to_many
|
125
|
+
end
|
105
126
|
|
106
|
-
ActiveStorage.replace_on_assign_to_many = app.config.active_storage.replace_on_assign_to_many || false
|
107
127
|
ActiveStorage.track_variants = app.config.active_storage.track_variants || false
|
108
128
|
end
|
109
129
|
end
|
@@ -167,8 +187,10 @@ module ActiveStorage
|
|
167
187
|
end
|
168
188
|
|
169
189
|
initializer "active_storage.asset" do
|
170
|
-
|
171
|
-
|
190
|
+
config.after_initialize do |app|
|
191
|
+
if app.config.respond_to?(:assets) && app.config.active_storage.precompile_assets
|
192
|
+
app.config.assets.precompile += %w( activestorage activestorage.esm )
|
193
|
+
end
|
172
194
|
end
|
173
195
|
end
|
174
196
|
|
@@ -4,19 +4,18 @@ require "active_support/testing/file_fixtures"
|
|
4
4
|
require "active_record/secure_token"
|
5
5
|
|
6
6
|
module ActiveStorage
|
7
|
+
# = Active Storage \FixtureSet
|
8
|
+
#
|
7
9
|
# Fixtures are a way of organizing data that you want to test against; in
|
8
10
|
# short, sample data.
|
9
11
|
#
|
10
|
-
# To learn more about fixtures, read the
|
11
|
-
# {ActiveRecord::FixtureSet}[rdoc-ref:ActiveRecord::FixtureSet] documentation.
|
12
|
+
# To learn more about fixtures, read the ActiveRecord::FixtureSet documentation.
|
12
13
|
#
|
13
14
|
# === YAML
|
14
15
|
#
|
15
|
-
# Like other Active Record-backed models,
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# {ActiveRecord::Base}[rdoc-ref:ActiveRecord::Base] instances and therefore
|
19
|
-
# can be populated by fixtures.
|
16
|
+
# Like other Active Record-backed models, ActiveStorage::Attachment and
|
17
|
+
# ActiveStorage::Blob records inherit from ActiveRecord::Base instances and
|
18
|
+
# therefore can be populated by fixtures.
|
20
19
|
#
|
21
20
|
# Consider a hypothetical <tt>Article</tt> model class, its related
|
22
21
|
# fixture data, as well as fixture data for related ActiveStorage::Attachment
|
@@ -44,7 +43,7 @@ module ActiveStorage
|
|
44
43
|
|
45
44
|
# Generate a YAML-encoded representation of an ActiveStorage::Blob
|
46
45
|
# instance's attributes, resolve the file relative to the directory mentioned
|
47
|
-
# by
|
46
|
+
# by ActiveSupport::Testing::FileFixtures.file_fixture, and upload
|
48
47
|
# the file to the Service
|
49
48
|
#
|
50
49
|
# === Examples
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveStorage
|
4
|
-
# Returns the version of
|
4
|
+
# Returns the currently loaded version of Active Storage as a +Gem::Version+.
|
5
5
|
def self.gem_version
|
6
6
|
Gem::Version.new VERSION::STRING
|
7
7
|
end
|
8
8
|
|
9
9
|
module VERSION
|
10
10
|
MAJOR = 7
|
11
|
-
MINOR =
|
11
|
+
MINOR = 1
|
12
12
|
TINY = 0
|
13
13
|
PRE = nil
|
14
14
|
|
@@ -9,34 +9,46 @@ module ActiveStorage
|
|
9
9
|
message += " (checksum: #{event.payload[:checksum]})" if event.payload[:checksum]
|
10
10
|
info event, color(message, GREEN)
|
11
11
|
end
|
12
|
+
subscribe_log_level :service_upload, :info
|
12
13
|
|
13
14
|
def service_download(event)
|
14
15
|
info event, color("Downloaded file from key: #{key_in(event)}", BLUE)
|
15
16
|
end
|
17
|
+
subscribe_log_level :service_download, :info
|
16
18
|
|
17
19
|
alias_method :service_streaming_download, :service_download
|
18
20
|
|
21
|
+
def preview(event)
|
22
|
+
info event, color("Previewed file from key: #{key_in(event)}", BLUE)
|
23
|
+
end
|
24
|
+
subscribe_log_level :preview, :info
|
25
|
+
|
19
26
|
def service_delete(event)
|
20
27
|
info event, color("Deleted file from key: #{key_in(event)}", RED)
|
21
28
|
end
|
29
|
+
subscribe_log_level :service_delete, :info
|
22
30
|
|
23
31
|
def service_delete_prefixed(event)
|
24
32
|
info event, color("Deleted files by key prefix: #{event.payload[:prefix]}", RED)
|
25
33
|
end
|
34
|
+
subscribe_log_level :service_delete_prefixed, :info
|
26
35
|
|
27
36
|
def service_exist(event)
|
28
37
|
debug event, color("Checked if file exists at key: #{key_in(event)} (#{event.payload[:exist] ? "yes" : "no"})", BLUE)
|
29
38
|
end
|
39
|
+
subscribe_log_level :service_exist, :debug
|
30
40
|
|
31
41
|
def service_url(event)
|
32
42
|
debug event, color("Generated URL for file at key: #{key_in(event)} (#{event.payload[:url]})", BLUE)
|
33
43
|
end
|
44
|
+
subscribe_log_level :service_url, :debug
|
34
45
|
|
35
46
|
def service_mirror(event)
|
36
47
|
message = "Mirrored file at key: #{key_in(event)}"
|
37
48
|
message += " (checksum: #{event.payload[:checksum]})" if event.payload[:checksum]
|
38
49
|
debug event, color(message, GREEN)
|
39
50
|
end
|
51
|
+
subscribe_log_level :service_mirror, :debug
|
40
52
|
|
41
53
|
def logger
|
42
54
|
ActiveStorage.logger
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveStorage
|
4
|
+
# = Active Storage \Previewer
|
5
|
+
#
|
4
6
|
# This is an abstract base class for previewers, which generate images from blobs. See
|
5
7
|
# ActiveStorage::Previewer::MuPDFPreviewer and ActiveStorage::Previewer::VideoPreviewer for
|
6
8
|
# examples of concrete subclasses.
|
@@ -65,7 +67,12 @@ module ActiveStorage
|
|
65
67
|
end
|
66
68
|
|
67
69
|
def instrument(operation, payload = {}, &block)
|
68
|
-
ActiveSupport::Notifications.instrument "#{operation}.active_storage", payload, &block
|
70
|
+
ActiveSupport::Notifications.instrument "#{operation}.active_storage", payload.merge(service: service_name), &block
|
71
|
+
end
|
72
|
+
|
73
|
+
def service_name
|
74
|
+
# ActiveStorage::Service::DiskService => Disk
|
75
|
+
blob.service.class.to_s.split("::").third.remove("Service")
|
69
76
|
end
|
70
77
|
|
71
78
|
def capture(*argv, to:)
|
@@ -4,11 +4,11 @@ module ActiveStorage
|
|
4
4
|
module Reflection
|
5
5
|
class HasAttachedReflection < ActiveRecord::Reflection::MacroReflection # :nodoc:
|
6
6
|
def variant(name, transformations)
|
7
|
-
|
7
|
+
named_variants[name] = NamedVariant.new(transformations)
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
@
|
10
|
+
def named_variants
|
11
|
+
@named_variants ||= {}
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -7,6 +7,8 @@ require "azure/storage/blob"
|
|
7
7
|
require "azure/storage/common/core/auth/shared_access_signature"
|
8
8
|
|
9
9
|
module ActiveStorage
|
10
|
+
# = Active Storage \Azure Storage \Service
|
11
|
+
#
|
10
12
|
# Wraps the Microsoft Azure Storage Blob Service as an Active Storage service.
|
11
13
|
# See ActiveStorage::Service for the generic API documentation that applies to all services.
|
12
14
|
class Service::AzureStorageService < Service
|
@@ -6,6 +6,8 @@ require "openssl"
|
|
6
6
|
require "active_support/core_ext/numeric/bytes"
|
7
7
|
|
8
8
|
module ActiveStorage
|
9
|
+
# = Active Storage \Disk \Service
|
10
|
+
#
|
9
11
|
# Wraps a local disk path as an Active Storage service. See ActiveStorage::Service for the generic API
|
10
12
|
# documentation that applies to all services.
|
11
13
|
class Service::DiskService < Service
|
@@ -5,6 +5,8 @@ require "google/apis/iamcredentials_v1"
|
|
5
5
|
require "google/cloud/storage"
|
6
6
|
|
7
7
|
module ActiveStorage
|
8
|
+
# = Active Storage \GCS \Service
|
9
|
+
#
|
8
10
|
# Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API
|
9
11
|
# documentation that applies to all services.
|
10
12
|
class Service::GCSService < Service
|
@@ -195,26 +197,15 @@ module ActiveStorage
|
|
195
197
|
end
|
196
198
|
|
197
199
|
def issuer
|
198
|
-
@issuer ||=
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
response = http.request(request)
|
208
|
-
rescue SocketError
|
209
|
-
raise MetadataServerNotFoundError
|
210
|
-
end
|
211
|
-
|
212
|
-
if response.is_a?(Net::HTTPSuccess)
|
213
|
-
response.body
|
214
|
-
else
|
215
|
-
raise MetadataServerError
|
216
|
-
end
|
217
|
-
end
|
200
|
+
@issuer ||= @config[:gsa_email].presence || email_from_metadata_server
|
201
|
+
end
|
202
|
+
|
203
|
+
def email_from_metadata_server
|
204
|
+
env = Google::Cloud.env
|
205
|
+
raise MetadataServerNotFoundError if !env.metadata?
|
206
|
+
|
207
|
+
email = env.lookup_metadata("instance", "service-accounts/default/email")
|
208
|
+
email.presence or raise MetadataServerError
|
218
209
|
end
|
219
210
|
|
220
211
|
def signer
|