activestorage 6.0.3.3 → 6.1.1

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.

Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +152 -149
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +35 -3
  5. data/app/controllers/active_storage/base_controller.rb +11 -0
  6. data/app/controllers/active_storage/blobs/proxy_controller.rb +14 -0
  7. data/app/controllers/active_storage/{blobs_controller.rb → blobs/redirect_controller.rb} +2 -2
  8. data/app/controllers/active_storage/direct_uploads_controller.rb +1 -1
  9. data/app/controllers/active_storage/disk_controller.rb +8 -20
  10. data/app/controllers/active_storage/representations/proxy_controller.rb +19 -0
  11. data/app/controllers/active_storage/{representations_controller.rb → representations/redirect_controller.rb} +2 -2
  12. data/app/controllers/concerns/active_storage/file_server.rb +18 -0
  13. data/app/controllers/concerns/active_storage/set_blob.rb +1 -1
  14. data/app/controllers/concerns/active_storage/set_current.rb +2 -2
  15. data/app/controllers/concerns/active_storage/set_headers.rb +12 -0
  16. data/app/jobs/active_storage/mirror_job.rb +15 -0
  17. data/app/models/active_storage/attachment.rb +18 -10
  18. data/app/models/active_storage/blob.rb +114 -59
  19. data/app/models/active_storage/blob/analyzable.rb +6 -2
  20. data/app/models/active_storage/blob/identifiable.rb +7 -6
  21. data/app/models/active_storage/blob/representable.rb +34 -4
  22. data/app/models/active_storage/preview.rb +31 -10
  23. data/app/models/active_storage/record.rb +7 -0
  24. data/app/models/active_storage/variant.rb +28 -41
  25. data/app/models/active_storage/variant_record.rb +8 -0
  26. data/app/models/active_storage/variant_with_record.rb +54 -0
  27. data/app/models/active_storage/variation.rb +25 -20
  28. data/config/routes.rb +58 -8
  29. data/db/migrate/20170806125915_create_active_storage_tables.rb +14 -5
  30. data/db/update_migrate/20190112182829_add_service_name_to_active_storage_blobs.rb +17 -0
  31. data/db/update_migrate/20191206030411_create_active_storage_variant_records.rb +11 -0
  32. data/lib/active_storage.rb +5 -2
  33. data/lib/active_storage/analyzer.rb +6 -0
  34. data/lib/active_storage/analyzer/image_analyzer.rb +3 -0
  35. data/lib/active_storage/analyzer/null_analyzer.rb +4 -0
  36. data/lib/active_storage/analyzer/video_analyzer.rb +14 -3
  37. data/lib/active_storage/attached/changes/create_many.rb +1 -0
  38. data/lib/active_storage/attached/changes/create_one.rb +17 -4
  39. data/lib/active_storage/attached/many.rb +4 -3
  40. data/lib/active_storage/attached/model.rb +77 -16
  41. data/lib/active_storage/attached/one.rb +4 -3
  42. data/lib/active_storage/engine.rb +25 -27
  43. data/lib/active_storage/gem_version.rb +3 -3
  44. data/lib/active_storage/log_subscriber.rb +6 -0
  45. data/lib/active_storage/previewer.rb +3 -2
  46. data/lib/active_storage/previewer/mupdf_previewer.rb +3 -3
  47. data/lib/active_storage/previewer/poppler_pdf_previewer.rb +3 -3
  48. data/lib/active_storage/previewer/video_previewer.rb +2 -2
  49. data/lib/active_storage/service.rb +36 -7
  50. data/lib/active_storage/service/azure_storage_service.rb +40 -35
  51. data/lib/active_storage/service/configurator.rb +3 -1
  52. data/lib/active_storage/service/disk_service.rb +36 -31
  53. data/lib/active_storage/service/gcs_service.rb +18 -16
  54. data/lib/active_storage/service/mirror_service.rb +31 -7
  55. data/lib/active_storage/service/registry.rb +32 -0
  56. data/lib/active_storage/service/s3_service.rb +53 -23
  57. data/lib/active_storage/transformers/image_processing_transformer.rb +13 -7
  58. data/lib/active_storage/transformers/transformer.rb +0 -3
  59. metadata +56 -20
  60. data/db/update_migrate/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb +0 -9
  61. data/lib/active_storage/downloading.rb +0 -47
  62. 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(**config, configurator: self)
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
- { "Content-MD5" => checksum }
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 +download+, +exists?+,
8
- # and +url+.
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, :path_for, to: :primary
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 { |name| configurator.build name }
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
- service.upload key, io.tap(&:rewind), checksum: checksum, **options
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, :upload_options
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.delete(: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
- object_for(key).put(upload_options.merge(body: io, content_md5: checksum, content_type: content_type))
22
- rescue Aws::S3::Errors::BadDigest
23
- raise ActiveStorage::IntegrityError
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.read.force_encoding(Encoding::BINARY)
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: ['content-length']
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
- { "Content-Type" => content_type, "Content-MD5" => checksum }
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.read.force_encoding(Encoding::BINARY)
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
- require "image_processing"
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
- ActiveSupport::Deprecation.warn <<~WARNING.squish
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. Passing :combine_options will
28
- not be supported in Rails 6.1.
29
- WARNING
34
+ as it always generates a single ImageMagick command.
35
+ ERROR
36
+ end
30
37
 
31
- list.concat argument.keep_if { |key, value| value.present? }.to_a
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.3.3
4
+ version: 6.1.1
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-09-09 00:00:00.000000000 Z
11
+ date: 2021-01-07 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.1
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.1
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.3.3
33
+ version: 6.1.1
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.3.3
40
+ version: 6.1.1
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.3.3
47
+ version: 6.1.1
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.3.3
54
+ version: 6.1.1
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.3.3
61
+ version: 6.1.1
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.3.3
68
+ version: 6.1.1
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/blobs_controller.rb
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/representations_controller.rb
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/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb
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.3.3/activestorage/CHANGELOG.md
155
- documentation_uri: https://api.rubyonrails.org/v6.0.3.3/
190
+ changelog_uri: https://github.com/rails/rails/blob/v6.1.1/activestorage/CHANGELOG.md
191
+ documentation_uri: https://api.rubyonrails.org/v6.1.1/
156
192
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
157
- source_code_uri: https://github.com/rails/rails/tree/v6.0.3.3/activestorage
158
- post_install_message:
193
+ source_code_uri: https://github.com/rails/rails/tree/v6.1.1/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.2
174
- signing_key:
209
+ rubygems_version: 3.2.3
210
+ signing_key:
175
211
  specification_version: 4
176
212
  summary: Local and cloud file storage framework.
177
213
  test_files: []