shrine 2.19.4 → 3.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of shrine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +299 -11
- data/README.md +9 -3
- data/doc/advantages.md +1 -1
- data/doc/carrierwave.md +4 -4
- data/doc/creating_persistence_plugins.md +172 -0
- data/doc/creating_plugins.md +1 -1
- data/doc/creating_storages.md +3 -1
- data/doc/design.md +2 -2
- data/doc/direct_s3.md +0 -22
- data/doc/paperclip.md +3 -3
- data/doc/plugins/activerecord.md +211 -42
- data/doc/plugins/atomic_helpers.md +153 -0
- data/doc/plugins/column.md +90 -0
- data/doc/plugins/derivation_endpoint.md +54 -62
- data/doc/plugins/derivatives.md +752 -0
- data/doc/plugins/entity.md +204 -0
- data/doc/plugins/infer_extension.md +8 -8
- data/doc/plugins/instrumentation.md +33 -13
- data/doc/plugins/keep_files.md +5 -15
- data/doc/plugins/model.md +157 -0
- data/doc/plugins/presign_endpoint.md +2 -1
- data/doc/plugins/refresh_metadata.md +44 -7
- data/doc/plugins/sequel.md +190 -33
- data/doc/plugins/{default_url_options.md → url_options.md} +5 -5
- data/doc/processing.md +1 -1
- data/doc/release_notes/1.1.0.md +2 -2
- data/doc/release_notes/2.15.0.md +1 -1
- data/doc/storage/s3.md +2 -2
- data/doc/testing.md +1 -1
- data/lib/shrine.rb +72 -138
- data/lib/shrine/attacher.rb +272 -176
- data/lib/shrine/attachment.rb +2 -42
- data/lib/shrine/plugins/activerecord.rb +103 -26
- data/lib/shrine/plugins/add_metadata.rb +9 -10
- data/lib/shrine/plugins/atomic_helpers.rb +111 -0
- data/lib/shrine/plugins/attacher_options.rb +55 -0
- data/lib/shrine/plugins/backgrounding.rb +147 -115
- data/lib/shrine/plugins/cached_attachment_data.rb +6 -9
- data/lib/shrine/plugins/column.rb +104 -0
- data/lib/shrine/plugins/data_uri.rb +35 -38
- data/lib/shrine/plugins/default_storage.rb +18 -12
- data/lib/shrine/plugins/default_url.rb +11 -21
- data/lib/shrine/plugins/default_url_options.rb +3 -30
- data/lib/shrine/plugins/delete_raw.rb +9 -13
- data/lib/shrine/plugins/derivation_endpoint.rb +75 -114
- data/lib/shrine/plugins/derivatives.rb +576 -0
- data/lib/shrine/plugins/determine_mime_type.rb +3 -15
- data/lib/shrine/plugins/download_endpoint.rb +83 -131
- data/lib/shrine/plugins/dynamic_storage.rb +4 -8
- data/lib/shrine/plugins/entity.rb +128 -0
- data/lib/shrine/plugins/form_assign.rb +107 -0
- data/lib/shrine/plugins/included.rb +4 -3
- data/lib/shrine/plugins/infer_extension.rb +10 -17
- data/lib/shrine/plugins/instrumentation.rb +45 -25
- data/lib/shrine/plugins/keep_files.rb +2 -12
- data/lib/shrine/plugins/metadata_attributes.rb +15 -14
- data/lib/shrine/plugins/model.rb +137 -0
- data/lib/shrine/plugins/module_include.rb +2 -0
- data/lib/shrine/plugins/presign_endpoint.rb +1 -15
- data/lib/shrine/plugins/pretty_location.rb +5 -5
- data/lib/shrine/plugins/processing.rb +21 -6
- data/lib/shrine/plugins/rack_file.rb +1 -39
- data/lib/shrine/plugins/rack_response.rb +14 -7
- data/lib/shrine/plugins/recache.rb +5 -2
- data/lib/shrine/plugins/refresh_metadata.rb +12 -8
- data/lib/shrine/plugins/remote_url.rb +44 -53
- data/lib/shrine/plugins/remove_attachment.rb +7 -2
- data/lib/shrine/plugins/remove_invalid.rb +8 -4
- data/lib/shrine/plugins/restore_cached_data.rb +12 -4
- data/lib/shrine/plugins/sequel.rb +115 -27
- data/lib/shrine/plugins/signature.rb +2 -7
- data/lib/shrine/plugins/store_dimensions.rb +13 -27
- data/lib/shrine/plugins/upload_endpoint.rb +14 -15
- data/lib/shrine/plugins/upload_options.rb +9 -8
- data/lib/shrine/plugins/url_options.rb +33 -0
- data/lib/shrine/plugins/validation.rb +87 -0
- data/lib/shrine/plugins/validation_helpers.rb +33 -54
- data/lib/shrine/plugins/versions.rb +106 -84
- data/lib/shrine/storage/file_system.rb +32 -57
- data/lib/shrine/storage/linter.rb +9 -1
- data/lib/shrine/storage/memory.rb +42 -0
- data/lib/shrine/storage/s3.rb +38 -146
- data/lib/shrine/uploaded_file.rb +22 -29
- data/lib/shrine/version.rb +4 -4
- data/shrine.gemspec +2 -3
- metadata +27 -54
- data/doc/plugins/backup.md +0 -31
- data/doc/plugins/copy.md +0 -24
- data/doc/plugins/delete_promoted.md +0 -12
- data/doc/plugins/direct_upload.md +0 -172
- data/doc/plugins/hooks.md +0 -58
- data/doc/plugins/logging.md +0 -42
- data/doc/plugins/migration_helpers.md +0 -60
- data/doc/plugins/moving.md +0 -19
- data/doc/plugins/multi_delete.md +0 -20
- data/doc/plugins/parallelize.md +0 -16
- data/doc/plugins/parsed_json.md +0 -23
- data/lib/shrine/plugins/background_helpers.rb +0 -5
- data/lib/shrine/plugins/backup.rb +0 -90
- data/lib/shrine/plugins/copy.rb +0 -50
- data/lib/shrine/plugins/delete_promoted.rb +0 -20
- data/lib/shrine/plugins/direct_upload.rb +0 -217
- data/lib/shrine/plugins/hooks.rb +0 -90
- data/lib/shrine/plugins/logging.rb +0 -142
- data/lib/shrine/plugins/migration_helpers.rb +0 -70
- data/lib/shrine/plugins/moving.rb +0 -57
- data/lib/shrine/plugins/multi_delete.rb +0 -32
- data/lib/shrine/plugins/parallelize.rb +0 -78
- data/lib/shrine/plugins/parsed_json.rb +0 -29
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
Shrine.deprecation("The module_include plugin is deprecated and will be removed in Shrine 4. Override core classes directly instead.")
|
4
|
+
|
3
5
|
class Shrine
|
4
6
|
module Plugins
|
5
7
|
# Documentation lives in [doc/plugins/module_include.md] on GitHub.
|
@@ -140,17 +140,7 @@ class Shrine
|
|
140
140
|
data = storage.presign(location, options)
|
141
141
|
end
|
142
142
|
|
143
|
-
|
144
|
-
{ fields: {}, headers: {} }.merge(data.to_h)
|
145
|
-
else
|
146
|
-
Shrine.deprecation("Returning a custom object in Storage#presign is deprecated, presign_endpoint will not support it in Shrine 3. Storage#presign should return a Hash instead.")
|
147
|
-
|
148
|
-
url = data.url
|
149
|
-
fields = data.fields
|
150
|
-
headers = data.headers if data.respond_to?(:headers)
|
151
|
-
|
152
|
-
{ url: url, fields: fields.to_h, headers: headers.to_h }
|
153
|
-
end
|
143
|
+
{ fields: {}, headers: {} }.merge(data.to_h)
|
154
144
|
end
|
155
145
|
|
156
146
|
# Transforms the presign hash into a JSON response. It returns a Rack
|
@@ -185,8 +175,4 @@ class Shrine
|
|
185
175
|
@shrine_class.find_storage(@storage_key)
|
186
176
|
end
|
187
177
|
end
|
188
|
-
|
189
|
-
# backwards compatibility
|
190
|
-
Plugins::PresignEndpoint.const_set(:App, PresignEndpoint)
|
191
|
-
Plugins::PresignEndpoint.deprecate_constant(:App)
|
192
178
|
end
|
@@ -6,24 +6,24 @@ class Shrine
|
|
6
6
|
#
|
7
7
|
# [doc/plugins/pretty_location.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/pretty_location.md
|
8
8
|
module PrettyLocation
|
9
|
-
def self.configure(uploader, opts
|
9
|
+
def self.configure(uploader, **opts)
|
10
10
|
uploader.opts[:pretty_location] ||= { identifier: :id }
|
11
11
|
uploader.opts[:pretty_location].merge!(opts)
|
12
12
|
end
|
13
13
|
|
14
14
|
module InstanceMethods
|
15
|
-
def generate_location(io,
|
16
|
-
pretty_location(io,
|
15
|
+
def generate_location(io, **options)
|
16
|
+
pretty_location(io, options)
|
17
17
|
end
|
18
18
|
|
19
|
-
def pretty_location(io, name: nil, record: nil, version: nil, identifier: nil, metadata: {}, **)
|
19
|
+
def pretty_location(io, name: nil, record: nil, version: nil, derivative: nil, identifier: nil, metadata: {}, **)
|
20
20
|
if record
|
21
21
|
namespace = record_namespace(record)
|
22
22
|
identifier ||= record_identifier(record)
|
23
23
|
end
|
24
24
|
|
25
25
|
basename = basic_location(io, metadata: metadata)
|
26
|
-
basename =
|
26
|
+
basename = [*(version || derivative), basename].join("-")
|
27
27
|
|
28
28
|
[*namespace, *identifier, *name, basename].join("/")
|
29
29
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
Shrine.deprecation("The processing plugin is deprecated and will be removed in Shrine 4. If you were using it with versions plugin, use the new derivatives plugin instead.")
|
4
|
+
|
3
5
|
class Shrine
|
4
6
|
module Plugins
|
5
7
|
# Documentation lives in [doc/plugins/processing.md] on GitHub.
|
@@ -13,19 +15,32 @@ class Shrine
|
|
13
15
|
module ClassMethods
|
14
16
|
def process(action, &block)
|
15
17
|
opts[:processing][action] ||= []
|
16
|
-
opts[:processing][action]
|
18
|
+
opts[:processing][action] << block
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
22
|
module InstanceMethods
|
21
|
-
def
|
22
|
-
|
23
|
+
def upload(io, process: true, **options)
|
24
|
+
if process
|
25
|
+
input = process(io, **options)
|
26
|
+
else
|
27
|
+
input = io
|
28
|
+
end
|
29
|
+
|
30
|
+
super(input, **options)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
23
34
|
|
24
|
-
|
25
|
-
|
35
|
+
def process(io, **options)
|
36
|
+
pipeline = processing_pipeline(options[:action])
|
37
|
+
pipeline.inject(io) do |input, processor|
|
38
|
+
instance_exec(input, options, &processor) || input
|
26
39
|
end
|
40
|
+
end
|
27
41
|
|
28
|
-
|
42
|
+
def processing_pipeline(key)
|
43
|
+
opts[:processing][key] || []
|
29
44
|
end
|
30
45
|
end
|
31
46
|
end
|
@@ -23,46 +23,12 @@ class Shrine
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
module InstanceMethods
|
27
|
-
# If `io` is a Rack uploaded file hash, converts it to an IO-like
|
28
|
-
# object and calls `super`.
|
29
|
-
def upload(io, context = {})
|
30
|
-
super(convert_rack_file(io), context)
|
31
|
-
end
|
32
|
-
|
33
|
-
# If `io` is a Rack uploaded file hash, converts it to an IO-like
|
34
|
-
# object and calls `super`.
|
35
|
-
def store(io, context = {})
|
36
|
-
super(convert_rack_file(io), context)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
# If given a Rack uploaded file hash, returns a
|
42
|
-
# `Shrine::Plugins::RackFile::UploadedFile` IO-like object wrapping that
|
43
|
-
# hash, otherwise returns the value unchanged.
|
44
|
-
def convert_rack_file(value)
|
45
|
-
if rack_file?(value)
|
46
|
-
Shrine.deprecation("Passing a Rack uploaded file hash to Shrine#upload is deprecated, use Shrine.rack_file to convert the Rack file hash into an IO object.")
|
47
|
-
self.class.rack_file(value)
|
48
|
-
else
|
49
|
-
value
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns whether a given value is a Rack uploaded file hash, by
|
54
|
-
# checking whether it's a hash with `:tempfile` and `:name` keys.
|
55
|
-
def rack_file?(value)
|
56
|
-
value.is_a?(Hash) && value.key?(:tempfile) && value.key?(:name)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
26
|
module AttacherMethods
|
61
27
|
# Checks whether a file is a Rack file hash, and in that case wraps the
|
62
28
|
# hash in an IO-like object.
|
63
29
|
def assign(value, **options)
|
64
30
|
if rack_file?(value)
|
65
|
-
assign
|
31
|
+
assign shrine_class.rack_file(value), **options
|
66
32
|
else
|
67
33
|
super
|
68
34
|
end
|
@@ -101,8 +67,4 @@ class Shrine
|
|
101
67
|
extend Forwardable
|
102
68
|
delegate [:read, :size, :rewind, :eof?, :close] => :@tempfile
|
103
69
|
end
|
104
|
-
|
105
|
-
# backwards compatibility
|
106
|
-
Plugins::RackFile.const_set(:UploadedFile, RackFile)
|
107
|
-
Plugins::RackFile.deprecate_constant(:UploadedFile)
|
108
70
|
end
|
@@ -101,16 +101,23 @@ class Shrine
|
|
101
101
|
FileBody.new(file, range: range)
|
102
102
|
end
|
103
103
|
|
104
|
-
#
|
104
|
+
# Retrieves a range value parsed from HTTP "Range" header.
|
105
105
|
def parse_content_range(range_header)
|
106
|
-
|
107
|
-
ranges = Rack::Utils.get_byte_ranges(range_header, file.size)
|
108
|
-
else
|
109
|
-
ranges = Rack::Utils.byte_ranges({ "HTTP_RANGE" => range_header }, file.size)
|
110
|
-
end
|
111
|
-
|
106
|
+
ranges = get_byte_ranges(range_header)
|
112
107
|
ranges.first if ranges && ranges.one?
|
113
108
|
end
|
109
|
+
|
110
|
+
if Rack.release >= "2.0"
|
111
|
+
def get_byte_ranges(range_header)
|
112
|
+
Rack::Utils.get_byte_ranges(range_header, file.size)
|
113
|
+
end
|
114
|
+
else
|
115
|
+
# :nocov:
|
116
|
+
def get_byte_ranges(range_header)
|
117
|
+
Rack::Utils.byte_ranges({ "HTTP_RANGE" => range_header }, file.size)
|
118
|
+
end
|
119
|
+
# :nocov:
|
120
|
+
end
|
114
121
|
end
|
115
122
|
|
116
123
|
# Implements the interface of a Rack response body object.
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
Shrine.deprecation("The recache plugin is deprecated and will be removed in Shrine 4. If you were using it with versions plugin, use the new derivatives plugin instead.")
|
4
|
+
|
3
5
|
class Shrine
|
4
6
|
module Plugins
|
5
7
|
# Documentation lives in [doc/plugins/recache.md] on GitHub.
|
@@ -14,8 +16,9 @@ class Shrine
|
|
14
16
|
|
15
17
|
def recache
|
16
18
|
if cached?
|
17
|
-
|
18
|
-
|
19
|
+
result = upload(file, cache_key, action: :recache)
|
20
|
+
|
21
|
+
set(result)
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
@@ -6,16 +6,20 @@ class Shrine
|
|
6
6
|
#
|
7
7
|
# [doc/plugins/refresh_metadata.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/refresh_metadata.md
|
8
8
|
module RefreshMetadata
|
9
|
+
module AttacherMethods
|
10
|
+
def refresh_metadata!(**options)
|
11
|
+
file.refresh_metadata!(**context, **options)
|
12
|
+
set(file)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
9
16
|
module FileMethods
|
10
|
-
def refresh_metadata!(**
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
else
|
15
|
-
open { uploader.send(:get_metadata, self, metadata: true, **context) }
|
16
|
-
end
|
17
|
+
def refresh_metadata!(**options)
|
18
|
+
return open { refresh_metadata!(**options) } unless opened?
|
19
|
+
|
20
|
+
refreshed_metadata = uploader.send(:get_metadata, self, metadata: true, **options)
|
17
21
|
|
18
|
-
@
|
22
|
+
@metadata = @metadata.merge(refreshed_metadata)
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
@@ -8,6 +8,8 @@ class Shrine
|
|
8
8
|
#
|
9
9
|
# [doc/plugins/remote_url.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/remote_url.md
|
10
10
|
module RemoteUrl
|
11
|
+
class DownloadError < Error; end
|
12
|
+
|
11
13
|
LOG_SUBSCRIBER = -> (event) do
|
12
14
|
Shrine.logger.info "Remote URL (#{event.duration}ms) – #{{
|
13
15
|
remote_url: event[:remote_url],
|
@@ -16,8 +18,20 @@ class Shrine
|
|
16
18
|
}.inspect}"
|
17
19
|
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
+
DOWNLOADER = -> (url, options) do
|
22
|
+
begin
|
23
|
+
Down.download(url, options)
|
24
|
+
rescue Down::Error => error
|
25
|
+
raise DownloadError, error.message
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.load_dependencies(uploader, *)
|
30
|
+
uploader.plugin :validation
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.configure(uploader, log_subscriber: LOG_SUBSCRIBER, **opts)
|
34
|
+
uploader.opts[:remote_url] ||= { downloader: DOWNLOADER }
|
21
35
|
uploader.opts[:remote_url].merge!(opts)
|
22
36
|
|
23
37
|
unless uploader.opts[:remote_url].key?(:max_size)
|
@@ -25,8 +39,24 @@ class Shrine
|
|
25
39
|
end
|
26
40
|
|
27
41
|
# instrumentation plugin integration
|
28
|
-
if uploader.respond_to?(:subscribe)
|
29
|
-
|
42
|
+
uploader.subscribe(:remote_url, &log_subscriber) if uploader.respond_to?(:subscribe)
|
43
|
+
end
|
44
|
+
|
45
|
+
module AttachmentMethods
|
46
|
+
def included(klass)
|
47
|
+
super
|
48
|
+
|
49
|
+
return unless options[:type] == :model
|
50
|
+
|
51
|
+
name = attachment_name
|
52
|
+
|
53
|
+
define_method :"#{name}_remote_url=" do |url|
|
54
|
+
send(:"#{name}_attacher").assign_remote_url(url)
|
55
|
+
end
|
56
|
+
|
57
|
+
define_method :"#{name}_remote_url" do
|
58
|
+
# form builders require the reader method
|
59
|
+
end
|
30
60
|
end
|
31
61
|
end
|
32
62
|
|
@@ -52,20 +82,6 @@ class Shrine
|
|
52
82
|
end
|
53
83
|
end
|
54
84
|
|
55
|
-
module AttachmentMethods
|
56
|
-
def initialize(name, **options)
|
57
|
-
super
|
58
|
-
|
59
|
-
define_method :"#{name}_remote_url=" do |url|
|
60
|
-
send(:"#{name}_attacher").remote_url = url
|
61
|
-
end
|
62
|
-
|
63
|
-
define_method :"#{name}_remote_url" do
|
64
|
-
send(:"#{name}_attacher").remote_url
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
85
|
module AttacherMethods
|
70
86
|
# Downloads the remote file and assigns it. If download failed, sets
|
71
87
|
# the error message and assigns the url to an instance variable so that
|
@@ -73,45 +89,20 @@ class Shrine
|
|
73
89
|
def assign_remote_url(url, downloader: {}, **options)
|
74
90
|
return if url == "" || url.nil?
|
75
91
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if downloaded_file
|
83
|
-
assign(downloaded_file, **options)
|
84
|
-
else
|
85
|
-
message = download_error_message(url, download_error)
|
86
|
-
errors.replace [message]
|
87
|
-
@remote_url = url
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Alias for #assign_remote_url.
|
92
|
-
def remote_url=(url)
|
93
|
-
assign_remote_url(url)
|
94
|
-
end
|
95
|
-
|
96
|
-
# Form builders require the reader as well.
|
97
|
-
def remote_url
|
98
|
-
@remote_url
|
92
|
+
downloaded_file = shrine_class.remote_url(url, downloader)
|
93
|
+
attach_cached(downloaded_file, **options)
|
94
|
+
rescue DownloadError => error
|
95
|
+
errors.clear << remote_url_error_message(url, error)
|
96
|
+
false
|
99
97
|
end
|
100
98
|
|
101
99
|
private
|
102
100
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
end
|
109
|
-
else
|
110
|
-
message = "download failed"
|
111
|
-
message = "#{message}: #{error.message}" if error
|
112
|
-
end
|
113
|
-
|
114
|
-
message
|
101
|
+
# Generates an error message for failed remote URL download.
|
102
|
+
def remote_url_error_message(url, error)
|
103
|
+
message = shrine_class.opts[:remote_url][:error_message]
|
104
|
+
message = message.call *[url, error].take(message.arity.abs) if message.respond_to?(:call)
|
105
|
+
message || "download failed: #{error.message}"
|
115
106
|
end
|
116
107
|
end
|
117
108
|
end
|
@@ -7,9 +7,13 @@ class Shrine
|
|
7
7
|
# [doc/plugins/remove_attachment.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/remove_attachment.md
|
8
8
|
module RemoveAttachment
|
9
9
|
module AttachmentMethods
|
10
|
-
def
|
10
|
+
def included(klass)
|
11
11
|
super
|
12
12
|
|
13
|
+
return unless options[:type] == :model
|
14
|
+
|
15
|
+
name = attachment_name
|
16
|
+
|
13
17
|
define_method :"remove_#{name}=" do |value|
|
14
18
|
send(:"#{name}_attacher").remove = value
|
15
19
|
end
|
@@ -24,7 +28,8 @@ class Shrine
|
|
24
28
|
# We remove the attachment if the value evaluates to true.
|
25
29
|
def remove=(value)
|
26
30
|
@remove = value
|
27
|
-
|
31
|
+
|
32
|
+
change(nil) if remove?
|
28
33
|
end
|
29
34
|
|
30
35
|
def remove
|
@@ -6,14 +6,18 @@ class Shrine
|
|
6
6
|
#
|
7
7
|
# [doc/plugins/remove_invalid.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/remove_invalid.md
|
8
8
|
module RemoveInvalid
|
9
|
+
def self.load_dependencies(uploader)
|
10
|
+
uploader.plugin :validation
|
11
|
+
end
|
12
|
+
|
9
13
|
module AttacherMethods
|
10
|
-
def validate
|
14
|
+
def validate(*)
|
11
15
|
super
|
12
16
|
ensure
|
13
17
|
if errors.any? && changed?
|
14
|
-
|
15
|
-
|
16
|
-
remove_instance_variable(:@
|
18
|
+
destroy(background: true)
|
19
|
+
set @previous.file
|
20
|
+
remove_instance_variable(:@previous)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
@@ -6,16 +6,24 @@ class Shrine
|
|
6
6
|
#
|
7
7
|
# [doc/plugins/restore_cached_data.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/restore_cached_data.md
|
8
8
|
module RestoreCachedData
|
9
|
-
def self.load_dependencies(uploader
|
9
|
+
def self.load_dependencies(uploader)
|
10
10
|
uploader.plugin :refresh_metadata
|
11
11
|
end
|
12
12
|
|
13
13
|
module AttacherMethods
|
14
14
|
private
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
16
|
+
def cached(value, **options)
|
17
|
+
cached_file = super
|
18
|
+
|
19
|
+
# TODO: Remove this conditional when we remove the versions plugin
|
20
|
+
if cached_file.is_a?(Hash) || cached_file.is_a?(Array)
|
21
|
+
uploaded_file(cached_file) { |file| file.refresh_metadata!(**context, **options) }
|
22
|
+
else
|
23
|
+
cached_file.refresh_metadata!(**context, **options)
|
24
|
+
end
|
25
|
+
|
26
|
+
cached_file
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|