activestorage 6.1.7.8 → 7.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activestorage might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +126 -326
- data/MIT-LICENSE +1 -1
- data/README.md +25 -11
- data/app/assets/javascripts/activestorage.esm.js +844 -0
- data/app/assets/javascripts/activestorage.js +257 -376
- data/app/controllers/active_storage/base_controller.rb +1 -10
- data/app/controllers/active_storage/blobs/proxy_controller.rb +14 -5
- data/app/controllers/active_storage/blobs/redirect_controller.rb +6 -4
- data/app/controllers/active_storage/representations/base_controller.rb +5 -1
- data/app/controllers/active_storage/representations/proxy_controller.rb +6 -5
- data/app/controllers/active_storage/representations/redirect_controller.rb +6 -4
- data/app/controllers/concerns/active_storage/set_blob.rb +6 -2
- data/app/controllers/concerns/active_storage/set_current.rb +3 -3
- data/app/controllers/concerns/active_storage/streaming.rb +65 -0
- data/app/javascript/activestorage/ujs.js +1 -1
- data/app/models/active_storage/attachment.rb +35 -2
- data/app/models/active_storage/blob/representable.rb +7 -5
- data/app/models/active_storage/blob.rb +26 -27
- data/app/models/active_storage/current.rb +12 -2
- data/app/models/active_storage/preview.rb +6 -4
- data/app/models/active_storage/record.rb +1 -1
- data/app/models/active_storage/variant.rb +6 -9
- data/app/models/active_storage/variant_record.rb +2 -0
- data/app/models/active_storage/variant_with_record.rb +9 -5
- data/app/models/active_storage/variation.rb +3 -3
- data/config/routes.rb +10 -10
- data/db/migrate/20170806125915_create_active_storage_tables.rb +11 -2
- data/db/update_migrate/20190112182829_add_service_name_to_active_storage_blobs.rb +0 -4
- data/db/update_migrate/20191206030411_create_active_storage_variant_records.rb +1 -3
- data/lib/active_storage/analyzer/audio_analyzer.rb +65 -0
- data/lib/active_storage/analyzer/image_analyzer/image_magick.rb +39 -0
- data/lib/active_storage/analyzer/image_analyzer/vips.rb +49 -0
- data/lib/active_storage/analyzer/image_analyzer.rb +2 -30
- data/lib/active_storage/analyzer/video_analyzer.rb +26 -11
- data/lib/active_storage/analyzer.rb +8 -4
- data/lib/active_storage/attached/changes/create_many.rb +7 -3
- data/lib/active_storage/attached/changes/create_one.rb +1 -1
- data/lib/active_storage/attached/changes/create_one_of_many.rb +1 -1
- data/lib/active_storage/attached/changes/delete_many.rb +1 -1
- data/lib/active_storage/attached/changes/delete_one.rb +1 -1
- data/lib/active_storage/attached/changes/detach_many.rb +18 -0
- data/lib/active_storage/attached/changes/detach_one.rb +24 -0
- data/lib/active_storage/attached/changes/purge_many.rb +27 -0
- data/lib/active_storage/attached/changes/purge_one.rb +27 -0
- data/lib/active_storage/attached/changes.rb +7 -1
- data/lib/active_storage/attached/many.rb +27 -15
- data/lib/active_storage/attached/model.rb +31 -5
- data/lib/active_storage/attached/one.rb +32 -27
- data/lib/active_storage/downloader.rb +2 -2
- data/lib/active_storage/engine.rb +28 -16
- data/lib/active_storage/fixture_set.rb +76 -0
- data/lib/active_storage/gem_version.rb +4 -4
- data/lib/active_storage/previewer/video_previewer.rb +0 -2
- data/lib/active_storage/previewer.rb +4 -4
- data/lib/active_storage/reflection.rb +12 -2
- data/lib/active_storage/service/azure_storage_service.rb +1 -1
- data/lib/active_storage/service/configurator.rb +1 -1
- data/lib/active_storage/service/disk_service.rb +13 -18
- data/lib/active_storage/service/gcs_service.rb +91 -7
- data/lib/active_storage/service/mirror_service.rb +1 -1
- data/lib/active_storage/service/registry.rb +1 -1
- data/lib/active_storage/service/s3_service.rb +4 -4
- data/lib/active_storage/service.rb +3 -3
- data/lib/active_storage/transformers/image_processing_transformer.rb +1 -66
- data/lib/active_storage/transformers/transformer.rb +1 -1
- data/lib/active_storage.rb +3 -292
- metadata +32 -25
- data/app/controllers/concerns/active_storage/disable_session.rb +0 -12
- data/app/controllers/concerns/active_storage/set_headers.rb +0 -12
@@ -1,12 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
gem "google-cloud-storage", "~> 1.11"
|
4
|
+
require "google/apis/iamcredentials_v1"
|
4
5
|
require "google/cloud/storage"
|
5
6
|
|
6
7
|
module ActiveStorage
|
7
8
|
# Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API
|
8
9
|
# documentation that applies to all services.
|
9
10
|
class Service::GCSService < Service
|
11
|
+
class MetadataServerError < ActiveStorage::Error; end
|
12
|
+
class MetadataServerNotFoundError < ActiveStorage::Error; end
|
13
|
+
|
10
14
|
def initialize(public: false, **config)
|
11
15
|
@config = config
|
12
16
|
@public = public
|
@@ -19,7 +23,7 @@ module ActiveStorage
|
|
19
23
|
# binary and attachment when the file's content type requires it. The only way to force them is to
|
20
24
|
# store them as object's metadata.
|
21
25
|
content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
|
22
|
-
bucket.create_file(io, key, md5: checksum, content_type: content_type, content_disposition: content_disposition)
|
26
|
+
bucket.create_file(io, key, md5: checksum, cache_control: @config[:cache_control], content_type: content_type, content_disposition: content_disposition)
|
23
27
|
rescue Google::Cloud::InvalidArgumentError
|
24
28
|
raise ActiveStorage::IntegrityError
|
25
29
|
end
|
@@ -84,7 +88,31 @@ module ActiveStorage
|
|
84
88
|
|
85
89
|
def url_for_direct_upload(key, expires_in:, checksum:, **)
|
86
90
|
instrument :url, key: key do |payload|
|
87
|
-
|
91
|
+
headers = {}
|
92
|
+
version = :v2
|
93
|
+
|
94
|
+
if @config[:cache_control].present?
|
95
|
+
headers["Cache-Control"] = @config[:cache_control]
|
96
|
+
# v2 signing doesn't support non `x-goog-` headers. Only switch to v4 signing
|
97
|
+
# if necessary for back-compat; v4 limits the expiration of the URL to 7 days
|
98
|
+
# whereas v2 has no limit
|
99
|
+
version = :v4
|
100
|
+
end
|
101
|
+
|
102
|
+
args = {
|
103
|
+
content_md5: checksum,
|
104
|
+
expires: expires_in,
|
105
|
+
headers: headers,
|
106
|
+
method: "PUT",
|
107
|
+
version: version,
|
108
|
+
}
|
109
|
+
|
110
|
+
if @config[:iam]
|
111
|
+
args[:issuer] = issuer
|
112
|
+
args[:signer] = signer
|
113
|
+
end
|
114
|
+
|
115
|
+
generated_url = bucket.signed_url(key, **args)
|
88
116
|
|
89
117
|
payload[:url] = generated_url
|
90
118
|
|
@@ -95,15 +123,31 @@ module ActiveStorage
|
|
95
123
|
def headers_for_direct_upload(key, checksum:, filename: nil, disposition: nil, **)
|
96
124
|
content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
|
97
125
|
|
98
|
-
{ "Content-MD5" => checksum, "Content-Disposition" => content_disposition }
|
126
|
+
headers = { "Content-MD5" => checksum, "Content-Disposition" => content_disposition }
|
127
|
+
|
128
|
+
if @config[:cache_control].present?
|
129
|
+
headers["Cache-Control"] = @config[:cache_control]
|
130
|
+
end
|
131
|
+
|
132
|
+
headers
|
99
133
|
end
|
100
134
|
|
101
135
|
private
|
102
136
|
def private_url(key, expires_in:, filename:, content_type:, disposition:, **)
|
103
|
-
|
104
|
-
|
105
|
-
|
137
|
+
args = {
|
138
|
+
expires: expires_in,
|
139
|
+
query: {
|
140
|
+
"response-content-disposition" => content_disposition_with(type: disposition, filename: filename),
|
141
|
+
"response-content-type" => content_type
|
142
|
+
}
|
106
143
|
}
|
144
|
+
|
145
|
+
if @config[:iam]
|
146
|
+
args[:issuer] = issuer
|
147
|
+
args[:signer] = signer
|
148
|
+
end
|
149
|
+
|
150
|
+
file_for(key).signed_url(**args)
|
107
151
|
end
|
108
152
|
|
109
153
|
def public_url(key, **)
|
@@ -137,7 +181,47 @@ module ActiveStorage
|
|
137
181
|
end
|
138
182
|
|
139
183
|
def client
|
140
|
-
@client ||= Google::Cloud::Storage.new(**config.except(:bucket))
|
184
|
+
@client ||= Google::Cloud::Storage.new(**config.except(:bucket, :cache_control, :iam, :gsa_email))
|
185
|
+
end
|
186
|
+
|
187
|
+
def issuer
|
188
|
+
@issuer ||= if @config[:gsa_email]
|
189
|
+
@config[:gsa_email]
|
190
|
+
else
|
191
|
+
uri = URI.parse("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email")
|
192
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
193
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
194
|
+
request["Metadata-Flavor"] = "Google"
|
195
|
+
|
196
|
+
begin
|
197
|
+
response = http.request(request)
|
198
|
+
rescue SocketError
|
199
|
+
raise MetadataServerNotFoundError
|
200
|
+
end
|
201
|
+
|
202
|
+
if response.is_a?(Net::HTTPSuccess)
|
203
|
+
response.body
|
204
|
+
else
|
205
|
+
raise MetadataServerError
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def signer
|
211
|
+
# https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage/Project.html#signed_url-instance_method
|
212
|
+
lambda do |string_to_sign|
|
213
|
+
iam_client = Google::Apis::IamcredentialsV1::IAMCredentialsService.new
|
214
|
+
|
215
|
+
scopes = ["https://www.googleapis.com/auth/iam"]
|
216
|
+
iam_client.authorization = Google::Auth.get_application_default(scopes)
|
217
|
+
|
218
|
+
request = Google::Apis::IamcredentialsV1::SignBlobRequest.new(
|
219
|
+
payload: string_to_sign
|
220
|
+
)
|
221
|
+
resource = "projects/-/serviceAccounts/#{issuer}"
|
222
|
+
response = iam_client.sign_service_account_blob(resource, request)
|
223
|
+
response.signed_blob
|
224
|
+
end
|
141
225
|
end
|
142
226
|
end
|
143
227
|
end
|
@@ -17,7 +17,7 @@ module ActiveStorage
|
|
17
17
|
:url_for_direct_upload, :headers_for_direct_upload, :path_for, to: :primary
|
18
18
|
|
19
19
|
# Stitch together from named services.
|
20
|
-
def self.build(primary:, mirrors:, name:, configurator:, **options)
|
20
|
+
def self.build(primary:, mirrors:, name:, configurator:, **options) # :nodoc:
|
21
21
|
new(
|
22
22
|
primary: configurator.build(primary),
|
23
23
|
mirrors: mirrors.collect { |mirror_name| configurator.build mirror_name }
|
@@ -96,14 +96,14 @@ module ActiveStorage
|
|
96
96
|
end
|
97
97
|
|
98
98
|
private
|
99
|
-
def private_url(key, expires_in:, filename:, disposition:, content_type:, **)
|
99
|
+
def private_url(key, expires_in:, filename:, disposition:, content_type:, **client_opts)
|
100
100
|
object_for(key).presigned_url :get, expires_in: expires_in.to_i,
|
101
101
|
response_content_disposition: content_disposition_with(type: disposition, filename: filename),
|
102
|
-
response_content_type: content_type
|
102
|
+
response_content_type: content_type, **client_opts
|
103
103
|
end
|
104
104
|
|
105
|
-
def public_url(key, **)
|
106
|
-
object_for(key).public_url
|
105
|
+
def public_url(key, **client_opts)
|
106
|
+
object_for(key).public_url(**client_opts)
|
107
107
|
end
|
108
108
|
|
109
109
|
|
@@ -35,8 +35,8 @@ module ActiveStorage
|
|
35
35
|
# can configure the service to use like this:
|
36
36
|
#
|
37
37
|
# ActiveStorage::Blob.service = ActiveStorage::Service.configure(
|
38
|
-
# :
|
39
|
-
# root: Pathname("/foo/
|
38
|
+
# :local,
|
39
|
+
# { local: {service: "Disk", root: Pathname("/tmp/foo/storage") } }
|
40
40
|
# )
|
41
41
|
class Service
|
42
42
|
extend ActiveSupport::Autoload
|
@@ -57,7 +57,7 @@ module ActiveStorage
|
|
57
57
|
# Passes the configurator and all of the service's config as keyword args.
|
58
58
|
#
|
59
59
|
# See MirrorService for an example.
|
60
|
-
def build(configurator:, name:, service: nil, **service_config)
|
60
|
+
def build(configurator:, name:, service: nil, **service_config) # :nodoc:
|
61
61
|
new(**service_config).tap do |service_instance|
|
62
62
|
service_instance.name = name
|
63
63
|
end
|
@@ -13,9 +13,6 @@ 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
|
-
|
19
16
|
def process(file, format:)
|
20
17
|
processor.
|
21
18
|
source(file).
|
@@ -31,14 +28,10 @@ module ActiveStorage
|
|
31
28
|
|
32
29
|
def operations
|
33
30
|
transformations.each_with_object([]) do |(name, argument), list|
|
34
|
-
if ActiveStorage.variant_processor == :mini_magick
|
35
|
-
validate_transformation(name, argument)
|
36
|
-
end
|
37
|
-
|
38
31
|
if name.to_s == "combine_options"
|
39
32
|
raise ArgumentError, <<~ERROR.squish
|
40
33
|
Active Storage's ImageProcessing transformer doesn't support :combine_options,
|
41
|
-
as it always generates a single
|
34
|
+
as it always generates a single command.
|
42
35
|
ERROR
|
43
36
|
end
|
44
37
|
|
@@ -47,64 +40,6 @@ module ActiveStorage
|
|
47
40
|
end
|
48
41
|
end
|
49
42
|
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
|
108
43
|
end
|
109
44
|
end
|
110
45
|
end
|
@@ -31,7 +31,7 @@ module ActiveStorage
|
|
31
31
|
private
|
32
32
|
# Returns an open Tempfile containing a transformed image in the given +format+.
|
33
33
|
# All subclasses implement this method.
|
34
|
-
def process(file, format:)
|
34
|
+
def process(file, format:) # :doc:
|
35
35
|
raise NotImplementedError
|
36
36
|
end
|
37
37
|
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-2021 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
|
@@ -37,6 +37,7 @@ module ActiveStorage
|
|
37
37
|
extend ActiveSupport::Autoload
|
38
38
|
|
39
39
|
autoload :Attached
|
40
|
+
autoload :FixtureSet
|
40
41
|
autoload :Service
|
41
42
|
autoload :Previewer
|
42
43
|
autoload :Analyzer
|
@@ -58,298 +59,8 @@ module ActiveStorage
|
|
58
59
|
mattr_accessor :content_types_to_serve_as_binary, default: []
|
59
60
|
mattr_accessor :content_types_allowed_inline, default: []
|
60
61
|
|
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
|
-
|
352
62
|
mattr_accessor :service_urls_expire_in, default: 5.minutes
|
63
|
+
mattr_accessor :urls_expire_in
|
353
64
|
|
354
65
|
mattr_accessor :routes_prefix, default: "/rails/active_storage"
|
355
66
|
mattr_accessor :draw_routes, default: true
|