activestorage 6.0.3.2 → 6.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.
Potentially problematic release.
This version of activestorage might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +149 -148
- data/MIT-LICENSE +1 -1
- data/README.md +35 -3
- data/app/controllers/active_storage/base_controller.rb +11 -0
- data/app/controllers/active_storage/blobs/proxy_controller.rb +14 -0
- data/app/controllers/active_storage/{blobs_controller.rb → blobs/redirect_controller.rb} +2 -2
- data/app/controllers/active_storage/direct_uploads_controller.rb +1 -1
- data/app/controllers/active_storage/disk_controller.rb +8 -20
- data/app/controllers/active_storage/representations/proxy_controller.rb +19 -0
- data/app/controllers/active_storage/{representations_controller.rb → representations/redirect_controller.rb} +2 -2
- data/app/controllers/concerns/active_storage/file_server.rb +18 -0
- data/app/controllers/concerns/active_storage/set_blob.rb +1 -1
- data/app/controllers/concerns/active_storage/set_current.rb +2 -2
- data/app/controllers/concerns/active_storage/set_headers.rb +12 -0
- data/app/jobs/active_storage/mirror_job.rb +15 -0
- data/app/models/active_storage/attachment.rb +18 -10
- data/app/models/active_storage/blob.rb +114 -59
- data/app/models/active_storage/blob/analyzable.rb +6 -2
- data/app/models/active_storage/blob/identifiable.rb +7 -6
- data/app/models/active_storage/blob/representable.rb +34 -4
- data/app/models/active_storage/preview.rb +31 -10
- data/app/models/active_storage/record.rb +7 -0
- data/app/models/active_storage/variant.rb +28 -41
- data/app/models/active_storage/variant_record.rb +8 -0
- data/app/models/active_storage/variant_with_record.rb +54 -0
- data/app/models/active_storage/variation.rb +25 -20
- data/config/routes.rb +58 -8
- data/db/migrate/20170806125915_create_active_storage_tables.rb +14 -5
- data/db/update_migrate/20190112182829_add_service_name_to_active_storage_blobs.rb +17 -0
- data/db/update_migrate/20191206030411_create_active_storage_variant_records.rb +11 -0
- data/lib/active_storage.rb +5 -2
- data/lib/active_storage/analyzer.rb +6 -0
- data/lib/active_storage/analyzer/image_analyzer.rb +3 -0
- data/lib/active_storage/analyzer/null_analyzer.rb +4 -0
- data/lib/active_storage/analyzer/video_analyzer.rb +14 -3
- data/lib/active_storage/attached/changes/create_many.rb +1 -0
- data/lib/active_storage/attached/changes/create_one.rb +17 -4
- data/lib/active_storage/attached/many.rb +4 -3
- data/lib/active_storage/attached/model.rb +77 -16
- data/lib/active_storage/attached/one.rb +4 -3
- data/lib/active_storage/engine.rb +25 -27
- data/lib/active_storage/gem_version.rb +3 -3
- data/lib/active_storage/log_subscriber.rb +6 -0
- data/lib/active_storage/previewer.rb +3 -2
- data/lib/active_storage/previewer/mupdf_previewer.rb +3 -3
- data/lib/active_storage/previewer/poppler_pdf_previewer.rb +3 -3
- data/lib/active_storage/previewer/video_previewer.rb +2 -2
- data/lib/active_storage/service.rb +36 -7
- data/lib/active_storage/service/azure_storage_service.rb +40 -35
- data/lib/active_storage/service/configurator.rb +3 -1
- data/lib/active_storage/service/disk_service.rb +36 -31
- data/lib/active_storage/service/gcs_service.rb +18 -16
- data/lib/active_storage/service/mirror_service.rb +31 -7
- data/lib/active_storage/service/registry.rb +32 -0
- data/lib/active_storage/service/s3_service.rb +53 -23
- data/lib/active_storage/transformers/image_processing_transformer.rb +13 -7
- data/lib/active_storage/transformers/transformer.rb +0 -3
- metadata +56 -20
- data/db/update_migrate/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb +0 -9
- data/lib/active_storage/downloading.rb +0 -47
- data/lib/active_storage/transformers/mini_magick_transformer.rb +0 -38
@@ -14,7 +14,9 @@ module ActiveStorage
|
|
14
14
|
|
15
15
|
def build(service_name)
|
16
16
|
config = config_for(service_name.to_sym)
|
17
|
-
resolve(config.fetch(:service)).build(
|
17
|
+
resolve(config.fetch(:service)).build(
|
18
|
+
**config, configurator: self, name: service_name
|
19
|
+
)
|
18
20
|
end
|
19
21
|
|
20
22
|
private
|
@@ -11,8 +11,9 @@ module ActiveStorage
|
|
11
11
|
class Service::DiskService < Service
|
12
12
|
attr_reader :root
|
13
13
|
|
14
|
-
def initialize(root:)
|
14
|
+
def initialize(root:, public: false, **options)
|
15
15
|
@root = root
|
16
|
+
@public = public
|
16
17
|
end
|
17
18
|
|
18
19
|
def upload(key, io, checksum: nil, **)
|
@@ -71,35 +72,6 @@ module ActiveStorage
|
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
|
-
def url(key, expires_in:, filename:, disposition:, content_type:)
|
75
|
-
instrument :url, key: key do |payload|
|
76
|
-
content_disposition = content_disposition_with(type: disposition, filename: filename)
|
77
|
-
verified_key_with_expiration = ActiveStorage.verifier.generate(
|
78
|
-
{
|
79
|
-
key: key,
|
80
|
-
disposition: content_disposition,
|
81
|
-
content_type: content_type
|
82
|
-
},
|
83
|
-
expires_in: expires_in,
|
84
|
-
purpose: :blob_key
|
85
|
-
)
|
86
|
-
|
87
|
-
current_uri = URI.parse(current_host)
|
88
|
-
|
89
|
-
generated_url = url_helpers.rails_disk_service_url(verified_key_with_expiration,
|
90
|
-
protocol: current_uri.scheme,
|
91
|
-
host: current_uri.host,
|
92
|
-
port: current_uri.port,
|
93
|
-
disposition: content_disposition,
|
94
|
-
content_type: content_type,
|
95
|
-
filename: filename
|
96
|
-
)
|
97
|
-
payload[:url] = generated_url
|
98
|
-
|
99
|
-
generated_url
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
75
|
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
|
104
76
|
instrument :url, key: key do |payload|
|
105
77
|
verified_token_with_expiration = ActiveStorage.verifier.generate(
|
@@ -107,7 +79,8 @@ module ActiveStorage
|
|
107
79
|
key: key,
|
108
80
|
content_type: content_type,
|
109
81
|
content_length: content_length,
|
110
|
-
checksum: checksum
|
82
|
+
checksum: checksum,
|
83
|
+
service_name: name
|
111
84
|
},
|
112
85
|
expires_in: expires_in,
|
113
86
|
purpose: :blob_token
|
@@ -130,6 +103,38 @@ module ActiveStorage
|
|
130
103
|
end
|
131
104
|
|
132
105
|
private
|
106
|
+
def private_url(key, expires_in:, filename:, content_type:, disposition:, **)
|
107
|
+
generate_url(key, expires_in: expires_in, filename: filename, content_type: content_type, disposition: disposition)
|
108
|
+
end
|
109
|
+
|
110
|
+
def public_url(key, filename:, content_type: nil, disposition: :attachment, **)
|
111
|
+
generate_url(key, expires_in: nil, filename: filename, content_type: content_type, disposition: disposition)
|
112
|
+
end
|
113
|
+
|
114
|
+
def generate_url(key, expires_in:, filename:, content_type:, disposition:)
|
115
|
+
content_disposition = content_disposition_with(type: disposition, filename: filename)
|
116
|
+
verified_key_with_expiration = ActiveStorage.verifier.generate(
|
117
|
+
{
|
118
|
+
key: key,
|
119
|
+
disposition: content_disposition,
|
120
|
+
content_type: content_type,
|
121
|
+
service_name: name
|
122
|
+
},
|
123
|
+
expires_in: expires_in,
|
124
|
+
purpose: :blob_key
|
125
|
+
)
|
126
|
+
|
127
|
+
current_uri = URI.parse(current_host)
|
128
|
+
|
129
|
+
url_helpers.rails_disk_service_url(verified_key_with_expiration,
|
130
|
+
protocol: current_uri.scheme,
|
131
|
+
host: current_uri.host,
|
132
|
+
port: current_uri.port,
|
133
|
+
filename: filename
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
133
138
|
def stream(key)
|
134
139
|
File.open(path_for(key), "rb") do |file|
|
135
140
|
while data = file.read(5.megabytes)
|
@@ -7,8 +7,9 @@ module ActiveStorage
|
|
7
7
|
# Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API
|
8
8
|
# documentation that applies to all services.
|
9
9
|
class Service::GCSService < Service
|
10
|
-
def initialize(**config)
|
10
|
+
def initialize(public: false, **config)
|
11
11
|
@config = config
|
12
|
+
@public = public
|
12
13
|
end
|
13
14
|
|
14
15
|
def upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil)
|
@@ -81,19 +82,6 @@ module ActiveStorage
|
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
84
|
-
def url(key, expires_in:, filename:, content_type:, disposition:)
|
85
|
-
instrument :url, key: key do |payload|
|
86
|
-
generated_url = file_for(key).signed_url expires: expires_in, query: {
|
87
|
-
"response-content-disposition" => content_disposition_with(type: disposition, filename: filename),
|
88
|
-
"response-content-type" => content_type
|
89
|
-
}
|
90
|
-
|
91
|
-
payload[:url] = generated_url
|
92
|
-
|
93
|
-
generated_url
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
85
|
def url_for_direct_upload(key, expires_in:, checksum:, **)
|
98
86
|
instrument :url, key: key do |payload|
|
99
87
|
generated_url = bucket.signed_url key, method: "PUT", expires: expires_in, content_md5: checksum
|
@@ -104,11 +92,25 @@ module ActiveStorage
|
|
104
92
|
end
|
105
93
|
end
|
106
94
|
|
107
|
-
def headers_for_direct_upload(key, checksum:, **)
|
108
|
-
|
95
|
+
def headers_for_direct_upload(key, checksum:, filename: nil, disposition: nil, **)
|
96
|
+
content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
|
97
|
+
|
98
|
+
{ "Content-MD5" => checksum, "Content-Disposition" => content_disposition }
|
109
99
|
end
|
110
100
|
|
111
101
|
private
|
102
|
+
def private_url(key, expires_in:, filename:, content_type:, disposition:, **)
|
103
|
+
file_for(key).signed_url expires: expires_in, query: {
|
104
|
+
"response-content-disposition" => content_disposition_with(type: disposition, filename: filename),
|
105
|
+
"response-content-type" => content_type
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def public_url(key, **)
|
110
|
+
file_for(key).public_url
|
111
|
+
end
|
112
|
+
|
113
|
+
|
112
114
|
attr_reader :config
|
113
115
|
|
114
116
|
def file_for(key, skip_lookup: true)
|
@@ -4,18 +4,26 @@ require "active_support/core_ext/module/delegation"
|
|
4
4
|
|
5
5
|
module ActiveStorage
|
6
6
|
# Wraps a set of mirror services and provides a single ActiveStorage::Service object that will all
|
7
|
-
# have the files uploaded to them. A +primary+ service is designated to answer calls to
|
8
|
-
#
|
7
|
+
# have the files uploaded to them. A +primary+ service is designated to answer calls to:
|
8
|
+
# * +download+
|
9
|
+
# * +exists?+
|
10
|
+
# * +url+
|
11
|
+
# * +url_for_direct_upload+
|
12
|
+
# * +headers_for_direct_upload+
|
9
13
|
class Service::MirrorService < Service
|
10
14
|
attr_reader :primary, :mirrors
|
11
15
|
|
12
|
-
delegate :download, :download_chunk, :exist?, :url,
|
16
|
+
delegate :download, :download_chunk, :exist?, :url,
|
17
|
+
:url_for_direct_upload, :headers_for_direct_upload, :path_for, to: :primary
|
13
18
|
|
14
19
|
# Stitch together from named services.
|
15
|
-
def self.build(primary:, mirrors:, configurator:, **options) #:nodoc:
|
16
|
-
new
|
20
|
+
def self.build(primary:, mirrors:, name:, configurator:, **options) #:nodoc:
|
21
|
+
new(
|
17
22
|
primary: configurator.build(primary),
|
18
|
-
mirrors: mirrors.collect { |
|
23
|
+
mirrors: mirrors.collect { |mirror_name| configurator.build mirror_name }
|
24
|
+
).tap do |service_instance|
|
25
|
+
service_instance.name = name
|
26
|
+
end
|
19
27
|
end
|
20
28
|
|
21
29
|
def initialize(primary:, mirrors:)
|
@@ -26,7 +34,8 @@ module ActiveStorage
|
|
26
34
|
# ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.
|
27
35
|
def upload(key, io, checksum: nil, **options)
|
28
36
|
each_service.collect do |service|
|
29
|
-
|
37
|
+
io.rewind
|
38
|
+
service.upload key, io, checksum: checksum, **options
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
@@ -40,6 +49,21 @@ module ActiveStorage
|
|
40
49
|
perform_across_services :delete_prefixed, prefix
|
41
50
|
end
|
42
51
|
|
52
|
+
|
53
|
+
# Copy the file at the +key+ from the primary service to each of the mirrors where it doesn't already exist.
|
54
|
+
def mirror(key, checksum:)
|
55
|
+
instrument :mirror, key: key, checksum: checksum do
|
56
|
+
if (mirrors_in_need_of_mirroring = mirrors.select { |service| !service.exist?(key) }).any?
|
57
|
+
primary.open(key, checksum: checksum) do |io|
|
58
|
+
mirrors_in_need_of_mirroring.each do |service|
|
59
|
+
io.rewind
|
60
|
+
service.upload key, io, checksum: checksum
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
43
67
|
private
|
44
68
|
def each_service(&block)
|
45
69
|
[ primary, *mirrors ].each(&block)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveStorage
|
4
|
+
class Service::Registry #:nodoc:
|
5
|
+
def initialize(configurations)
|
6
|
+
@configurations = configurations.deep_symbolize_keys
|
7
|
+
@services = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch(name)
|
11
|
+
services.fetch(name.to_sym) do |key|
|
12
|
+
if configurations.include?(key)
|
13
|
+
services[key] = configurator.build(key)
|
14
|
+
else
|
15
|
+
if block_given?
|
16
|
+
yield key
|
17
|
+
else
|
18
|
+
raise KeyError, "Missing configuration for the #{key} Active Storage service. " \
|
19
|
+
"Configurations available for the #{configurations.keys.to_sentence} services."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
attr_reader :configurations, :services
|
27
|
+
|
28
|
+
def configurator
|
29
|
+
@configurator ||= ActiveStorage::Service::Configurator.new(configurations)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
gem "aws-sdk-s3", "~> 1.48"
|
4
|
+
|
3
5
|
require "aws-sdk-s3"
|
4
6
|
require "active_support/core_ext/numeric/bytes"
|
5
7
|
|
@@ -7,20 +9,29 @@ module ActiveStorage
|
|
7
9
|
# Wraps the Amazon Simple Storage Service (S3) as an Active Storage service.
|
8
10
|
# See ActiveStorage::Service for the generic API documentation that applies to all services.
|
9
11
|
class Service::S3Service < Service
|
10
|
-
attr_reader :client, :bucket
|
12
|
+
attr_reader :client, :bucket
|
13
|
+
attr_reader :multipart_upload_threshold, :upload_options
|
11
14
|
|
12
|
-
def initialize(bucket:, upload: {}, **options)
|
15
|
+
def initialize(bucket:, upload: {}, public: false, **options)
|
13
16
|
@client = Aws::S3::Resource.new(**options)
|
14
17
|
@bucket = @client.bucket(bucket)
|
15
18
|
|
19
|
+
@multipart_upload_threshold = upload.fetch(:multipart_threshold, 100.megabytes)
|
20
|
+
@public = public
|
21
|
+
|
16
22
|
@upload_options = upload
|
23
|
+
@upload_options[:acl] = "public-read" if public?
|
17
24
|
end
|
18
25
|
|
19
|
-
def upload(key, io, checksum: nil, content_type: nil, **)
|
26
|
+
def upload(key, io, checksum: nil, filename: nil, content_type: nil, disposition: nil, **)
|
20
27
|
instrument :upload, key: key, checksum: checksum do
|
21
|
-
|
22
|
-
|
23
|
-
|
28
|
+
content_disposition = content_disposition_with(filename: filename, type: disposition) if disposition && filename
|
29
|
+
|
30
|
+
if io.size < multipart_upload_threshold
|
31
|
+
upload_with_single_part key, io, checksum: checksum, content_type: content_type, content_disposition: content_disposition
|
32
|
+
else
|
33
|
+
upload_with_multipart key, io, content_type: content_type, content_disposition: content_disposition
|
34
|
+
end
|
24
35
|
end
|
25
36
|
end
|
26
37
|
|
@@ -40,7 +51,7 @@ module ActiveStorage
|
|
40
51
|
|
41
52
|
def download_chunk(key, range)
|
42
53
|
instrument :download_chunk, key: key, range: range do
|
43
|
-
object_for(key).get(range: "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body.
|
54
|
+
object_for(key).get(range: "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body.string.force_encoding(Encoding::BINARY)
|
44
55
|
rescue Aws::S3::Errors::NoSuchKey
|
45
56
|
raise ActiveStorage::FileNotFoundError
|
46
57
|
end
|
@@ -66,23 +77,11 @@ module ActiveStorage
|
|
66
77
|
end
|
67
78
|
end
|
68
79
|
|
69
|
-
def url(key, expires_in:, filename:, disposition:, content_type:)
|
70
|
-
instrument :url, key: key do |payload|
|
71
|
-
generated_url = object_for(key).presigned_url :get, expires_in: expires_in.to_i,
|
72
|
-
response_content_disposition: content_disposition_with(type: disposition, filename: filename),
|
73
|
-
response_content_type: content_type
|
74
|
-
|
75
|
-
payload[:url] = generated_url
|
76
|
-
|
77
|
-
generated_url
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
80
|
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
|
82
81
|
instrument :url, key: key do |payload|
|
83
82
|
generated_url = object_for(key).presigned_url :put, expires_in: expires_in.to_i,
|
84
83
|
content_type: content_type, content_length: content_length, content_md5: checksum,
|
85
|
-
whitelist_headers: [
|
84
|
+
whitelist_headers: ["content-length"], **upload_options
|
86
85
|
|
87
86
|
payload[:url] = generated_url
|
88
87
|
|
@@ -90,11 +89,42 @@ module ActiveStorage
|
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
93
|
-
def headers_for_direct_upload(key, content_type:, checksum:, **)
|
94
|
-
|
92
|
+
def headers_for_direct_upload(key, content_type:, checksum:, filename: nil, disposition: nil, **)
|
93
|
+
content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
|
94
|
+
|
95
|
+
{ "Content-Type" => content_type, "Content-MD5" => checksum, "Content-Disposition" => content_disposition }
|
95
96
|
end
|
96
97
|
|
97
98
|
private
|
99
|
+
def private_url(key, expires_in:, filename:, disposition:, content_type:, **)
|
100
|
+
object_for(key).presigned_url :get, expires_in: expires_in.to_i,
|
101
|
+
response_content_disposition: content_disposition_with(type: disposition, filename: filename),
|
102
|
+
response_content_type: content_type
|
103
|
+
end
|
104
|
+
|
105
|
+
def public_url(key, **)
|
106
|
+
object_for(key).public_url
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
MAXIMUM_UPLOAD_PARTS_COUNT = 10000
|
111
|
+
MINIMUM_UPLOAD_PART_SIZE = 5.megabytes
|
112
|
+
|
113
|
+
def upload_with_single_part(key, io, checksum: nil, content_type: nil, content_disposition: nil)
|
114
|
+
object_for(key).put(body: io, content_md5: checksum, content_type: content_type, content_disposition: content_disposition, **upload_options)
|
115
|
+
rescue Aws::S3::Errors::BadDigest
|
116
|
+
raise ActiveStorage::IntegrityError
|
117
|
+
end
|
118
|
+
|
119
|
+
def upload_with_multipart(key, io, content_type: nil, content_disposition: nil)
|
120
|
+
part_size = [ io.size.fdiv(MAXIMUM_UPLOAD_PARTS_COUNT).ceil, MINIMUM_UPLOAD_PART_SIZE ].max
|
121
|
+
|
122
|
+
object_for(key).upload_stream(content_type: content_type, content_disposition: content_disposition, part_size: part_size, **upload_options) do |out|
|
123
|
+
IO.copy_stream(io, out)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
98
128
|
def object_for(key)
|
99
129
|
bucket.object(key)
|
100
130
|
end
|
@@ -109,7 +139,7 @@ module ActiveStorage
|
|
109
139
|
raise ActiveStorage::FileNotFoundError unless object.exists?
|
110
140
|
|
111
141
|
while offset < object.content_length
|
112
|
-
yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}").body.
|
142
|
+
yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}").body.string.force_encoding(Encoding::BINARY)
|
113
143
|
offset += chunk_size
|
114
144
|
end
|
115
145
|
end
|
@@ -1,6 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
begin
|
4
|
+
require "image_processing"
|
5
|
+
rescue LoadError
|
6
|
+
raise LoadError, <<~ERROR.squish
|
7
|
+
Generating image variants require the image_processing gem.
|
8
|
+
Please add `gem 'image_processing', '~> 1.2'` to your Gemfile.
|
9
|
+
ERROR
|
10
|
+
end
|
4
11
|
|
5
12
|
module ActiveStorage
|
6
13
|
module Transformers
|
@@ -22,14 +29,13 @@ module ActiveStorage
|
|
22
29
|
def operations
|
23
30
|
transformations.each_with_object([]) do |(name, argument), list|
|
24
31
|
if name.to_s == "combine_options"
|
25
|
-
|
32
|
+
raise ArgumentError, <<~ERROR.squish
|
26
33
|
Active Storage's ImageProcessing transformer doesn't support :combine_options,
|
27
|
-
as it always generates a single ImageMagick command.
|
28
|
-
|
29
|
-
|
34
|
+
as it always generates a single ImageMagick command.
|
35
|
+
ERROR
|
36
|
+
end
|
30
37
|
|
31
|
-
|
32
|
-
elsif argument.present?
|
38
|
+
if argument.present?
|
33
39
|
list << [ name, argument ]
|
34
40
|
end
|
35
41
|
end
|
@@ -8,9 +8,6 @@ module ActiveStorage
|
|
8
8
|
#
|
9
9
|
# * ActiveStorage::Transformers::ImageProcessingTransformer:
|
10
10
|
# backed by ImageProcessing, a common interface for MiniMagick and ruby-vips
|
11
|
-
#
|
12
|
-
# * ActiveStorage::Transformers::MiniMagickTransformer:
|
13
|
-
# backed by MiniMagick, a wrapper around the ImageMagick CLI
|
14
11
|
class Transformer
|
15
12
|
attr_reader :transformations
|
16
13
|
|
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activestorage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.1.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: actionpack
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - '='
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0
|
33
|
+
version: 6.1.0
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
38
|
- - '='
|
25
39
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.0
|
40
|
+
version: 6.1.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: activejob
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - '='
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: 6.0
|
47
|
+
version: 6.1.0
|
34
48
|
type: :runtime
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
52
|
- - '='
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version: 6.0
|
54
|
+
version: 6.1.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: activerecord
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - '='
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: 6.0
|
61
|
+
version: 6.1.0
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - '='
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: 6.0
|
68
|
+
version: 6.1.0
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: marcel
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +80,20 @@ dependencies:
|
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: 0.3.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mimemagic
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.3.2
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.3.2
|
69
97
|
description: Attach cloud and local files in Rails applications.
|
70
98
|
email: david@loudthinking.com
|
71
99
|
executables: []
|
@@ -77,12 +105,16 @@ files:
|
|
77
105
|
- README.md
|
78
106
|
- app/assets/javascripts/activestorage.js
|
79
107
|
- app/controllers/active_storage/base_controller.rb
|
80
|
-
- app/controllers/active_storage/
|
108
|
+
- app/controllers/active_storage/blobs/proxy_controller.rb
|
109
|
+
- app/controllers/active_storage/blobs/redirect_controller.rb
|
81
110
|
- app/controllers/active_storage/direct_uploads_controller.rb
|
82
111
|
- app/controllers/active_storage/disk_controller.rb
|
83
|
-
- app/controllers/active_storage/
|
112
|
+
- app/controllers/active_storage/representations/proxy_controller.rb
|
113
|
+
- app/controllers/active_storage/representations/redirect_controller.rb
|
114
|
+
- app/controllers/concerns/active_storage/file_server.rb
|
84
115
|
- app/controllers/concerns/active_storage/set_blob.rb
|
85
116
|
- app/controllers/concerns/active_storage/set_current.rb
|
117
|
+
- app/controllers/concerns/active_storage/set_headers.rb
|
86
118
|
- app/javascript/activestorage/blob_record.js
|
87
119
|
- app/javascript/activestorage/blob_upload.js
|
88
120
|
- app/javascript/activestorage/direct_upload.js
|
@@ -94,6 +126,7 @@ files:
|
|
94
126
|
- app/javascript/activestorage/ujs.js
|
95
127
|
- app/jobs/active_storage/analyze_job.rb
|
96
128
|
- app/jobs/active_storage/base_job.rb
|
129
|
+
- app/jobs/active_storage/mirror_job.rb
|
97
130
|
- app/jobs/active_storage/purge_job.rb
|
98
131
|
- app/models/active_storage/attachment.rb
|
99
132
|
- app/models/active_storage/blob.rb
|
@@ -103,11 +136,15 @@ files:
|
|
103
136
|
- app/models/active_storage/current.rb
|
104
137
|
- app/models/active_storage/filename.rb
|
105
138
|
- app/models/active_storage/preview.rb
|
139
|
+
- app/models/active_storage/record.rb
|
106
140
|
- app/models/active_storage/variant.rb
|
141
|
+
- app/models/active_storage/variant_record.rb
|
142
|
+
- app/models/active_storage/variant_with_record.rb
|
107
143
|
- app/models/active_storage/variation.rb
|
108
144
|
- config/routes.rb
|
109
145
|
- db/migrate/20170806125915_create_active_storage_tables.rb
|
110
|
-
- db/update_migrate/
|
146
|
+
- db/update_migrate/20190112182829_add_service_name_to_active_storage_blobs.rb
|
147
|
+
- db/update_migrate/20191206030411_create_active_storage_variant_records.rb
|
111
148
|
- lib/active_storage.rb
|
112
149
|
- lib/active_storage/analyzer.rb
|
113
150
|
- lib/active_storage/analyzer/image_analyzer.rb
|
@@ -124,7 +161,6 @@ files:
|
|
124
161
|
- lib/active_storage/attached/model.rb
|
125
162
|
- lib/active_storage/attached/one.rb
|
126
163
|
- lib/active_storage/downloader.rb
|
127
|
-
- lib/active_storage/downloading.rb
|
128
164
|
- lib/active_storage/engine.rb
|
129
165
|
- lib/active_storage/errors.rb
|
130
166
|
- lib/active_storage/gem_version.rb
|
@@ -140,9 +176,9 @@ files:
|
|
140
176
|
- lib/active_storage/service/disk_service.rb
|
141
177
|
- lib/active_storage/service/gcs_service.rb
|
142
178
|
- lib/active_storage/service/mirror_service.rb
|
179
|
+
- lib/active_storage/service/registry.rb
|
143
180
|
- lib/active_storage/service/s3_service.rb
|
144
181
|
- lib/active_storage/transformers/image_processing_transformer.rb
|
145
|
-
- lib/active_storage/transformers/mini_magick_transformer.rb
|
146
182
|
- lib/active_storage/transformers/transformer.rb
|
147
183
|
- lib/active_storage/version.rb
|
148
184
|
- lib/tasks/activestorage.rake
|
@@ -151,11 +187,11 @@ licenses:
|
|
151
187
|
- MIT
|
152
188
|
metadata:
|
153
189
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
154
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.0
|
155
|
-
documentation_uri: https://api.rubyonrails.org/v6.0
|
190
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.1.0/activestorage/CHANGELOG.md
|
191
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.0/
|
156
192
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
157
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.0
|
158
|
-
post_install_message:
|
193
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.1.0/activestorage
|
194
|
+
post_install_message:
|
159
195
|
rdoc_options: []
|
160
196
|
require_paths:
|
161
197
|
- lib
|
@@ -170,8 +206,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
206
|
- !ruby/object:Gem::Version
|
171
207
|
version: '0'
|
172
208
|
requirements: []
|
173
|
-
rubygems_version: 3.1.
|
174
|
-
signing_key:
|
209
|
+
rubygems_version: 3.1.4
|
210
|
+
signing_key:
|
175
211
|
specification_version: 4
|
176
212
|
summary: Local and cloud file storage framework.
|
177
213
|
test_files: []
|