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
@@ -6,24 +6,30 @@ class Shrine
|
|
6
6
|
#
|
7
7
|
# [doc/plugins/default_storage.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/default_storage.md
|
8
8
|
module DefaultStorage
|
9
|
-
def self.configure(uploader, opts
|
10
|
-
uploader.opts[:
|
11
|
-
uploader.opts[:
|
9
|
+
def self.configure(uploader, **opts)
|
10
|
+
uploader.opts[:default_storage] ||= {}
|
11
|
+
uploader.opts[:default_storage].merge!(opts)
|
12
12
|
end
|
13
13
|
|
14
14
|
module AttacherMethods
|
15
|
-
def initialize(
|
16
|
-
|
17
|
-
|
18
|
-
options[:cache] = cache
|
19
|
-
end
|
15
|
+
def initialize(**options)
|
16
|
+
super(**shrine_class.opts[:default_storage], **options)
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def cache_key
|
20
|
+
if @cache.respond_to?(:call)
|
21
|
+
@cache.call(record, name)
|
22
|
+
else
|
23
|
+
@cache
|
24
24
|
end
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
+
def store_key
|
28
|
+
if @store.respond_to?(:call)
|
29
|
+
@store.call(record, name)
|
30
|
+
else
|
31
|
+
@store
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
@@ -6,18 +6,14 @@ class Shrine
|
|
6
6
|
#
|
7
7
|
# [doc/plugins/default_url.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/default_url.md
|
8
8
|
module DefaultUrl
|
9
|
-
def self.configure(uploader, opts
|
10
|
-
uploader.opts[:
|
11
|
-
|
12
|
-
if block
|
13
|
-
uploader.opts[:default_url] = block
|
14
|
-
Shrine.deprecation("Passing a block to default_url plugin is deprecated and will probably be removed in future versions of Shrine. Use `Attacher.default_url { ... }` instead.")
|
15
|
-
end
|
9
|
+
def self.configure(uploader, **opts)
|
10
|
+
uploader.opts[:default_url] ||= {}
|
11
|
+
uploader.opts[:default_url].merge!(opts)
|
16
12
|
end
|
17
13
|
|
18
14
|
module AttacherClassMethods
|
19
15
|
def default_url(&block)
|
20
|
-
shrine_class.opts[:
|
16
|
+
shrine_class.opts[:default_url][:block] = block
|
21
17
|
end
|
22
18
|
end
|
23
19
|
|
@@ -29,25 +25,19 @@ class Shrine
|
|
29
25
|
private
|
30
26
|
|
31
27
|
def default_url(**options)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
if default_url_host
|
39
|
-
[default_url_host, url].join
|
40
|
-
else
|
41
|
-
url
|
42
|
-
end
|
28
|
+
return unless default_url_block
|
29
|
+
|
30
|
+
url = instance_exec(options, &default_url_block)
|
31
|
+
|
32
|
+
[*default_url_host, url].join
|
43
33
|
end
|
44
34
|
|
45
35
|
def default_url_block
|
46
|
-
shrine_class.opts[:
|
36
|
+
shrine_class.opts[:default_url][:block]
|
47
37
|
end
|
48
38
|
|
49
39
|
def default_url_host
|
50
|
-
shrine_class.opts[:
|
40
|
+
shrine_class.opts[:default_url][:host]
|
51
41
|
end
|
52
42
|
end
|
53
43
|
end
|
@@ -1,34 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
module Plugins
|
5
|
-
# Documentation lives in [doc/plugins/default_url_options.md] on GitHub.
|
6
|
-
#
|
7
|
-
# [doc/plugins/default_url_options.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/default_url_options.md
|
8
|
-
module DefaultUrlOptions
|
9
|
-
def self.configure(uploader, options = {})
|
10
|
-
uploader.opts[:default_url_options] ||= {}
|
11
|
-
uploader.opts[:default_url_options].merge!(options)
|
12
|
-
end
|
3
|
+
Shrine.deprecation("The default_url_options plugin has been renamed to url_options, so `plugin :default_url_options` should be replaced with `plugin :url_options`. The default_url_options alias will be removed in Shrine 4.")
|
13
4
|
|
14
|
-
|
15
|
-
def url(**options)
|
16
|
-
default_options = default_url_options
|
17
|
-
default_options = default_options.call(self, options) if default_options.respond_to?(:call)
|
18
|
-
default_options ||= {}
|
5
|
+
require "shrine/plugins/url_options"
|
19
6
|
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def default_url_options
|
26
|
-
options = shrine_class.opts[:default_url_options]
|
27
|
-
options[storage_key.to_sym]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
register_plugin(:default_url_options, DefaultUrlOptions)
|
33
|
-
end
|
34
|
-
end
|
7
|
+
Shrine::Plugins.register_plugin(:default_url_options, Shrine::Plugins::UrlOptions)
|
@@ -1,33 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
Shrine.deprecation("The delete_raw 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/delete_raw.md] on GitHub.
|
6
8
|
#
|
7
9
|
# [doc/plugins/delete_raw.md]: https://github.com/shrinerb/shrine/blob/master/doc/plugins/delete_raw.md
|
8
10
|
module DeleteRaw
|
9
|
-
def self.configure(uploader, opts
|
10
|
-
uploader.opts[:
|
11
|
+
def self.configure(uploader, **opts)
|
12
|
+
uploader.opts[:delete_raw] ||= {}
|
13
|
+
uploader.opts[:delete_raw].merge!(opts)
|
11
14
|
end
|
12
15
|
|
13
16
|
module InstanceMethods
|
14
17
|
private
|
15
18
|
|
16
19
|
# Deletes the file that was uploaded, unless it's an UploadedFile.
|
17
|
-
def
|
18
|
-
super
|
19
|
-
if io.respond_to?(:path) && io.path && delete_raw? && context[:delete] != false
|
20
|
-
begin
|
21
|
-
File.delete(io.path)
|
22
|
-
rescue Errno::ENOENT
|
23
|
-
# file might already be deleted by the moving plugin
|
24
|
-
end
|
25
|
-
end
|
20
|
+
def _upload(io, delete: delete_raw?, **options)
|
21
|
+
super(io, delete: delete, **options)
|
26
22
|
end
|
27
23
|
|
28
24
|
def delete_raw?
|
29
|
-
opts[:
|
30
|
-
opts[:
|
25
|
+
opts[:delete_raw][:storages].nil? ||
|
26
|
+
opts[:delete_raw][:storages].include?(storage_key)
|
31
27
|
end
|
32
28
|
end
|
33
29
|
end
|
@@ -5,6 +5,7 @@ require "content_disposition"
|
|
5
5
|
|
6
6
|
require "openssl"
|
7
7
|
require "tempfile"
|
8
|
+
require "pathname"
|
8
9
|
|
9
10
|
class Shrine
|
10
11
|
module Plugins
|
@@ -20,25 +21,21 @@ class Shrine
|
|
20
21
|
}.inspect}"
|
21
22
|
end
|
22
23
|
|
23
|
-
def self.load_dependencies(uploader,
|
24
|
+
def self.load_dependencies(uploader, **)
|
24
25
|
uploader.plugin :rack_response
|
25
26
|
uploader.plugin :_urlsafe_serialization
|
26
27
|
end
|
27
28
|
|
28
|
-
def self.configure(uploader,
|
29
|
-
uploader.opts[:
|
30
|
-
uploader.opts[:
|
29
|
+
def self.configure(uploader, log_subscriber: LOG_SUBSCRIBER, **opts)
|
30
|
+
uploader.opts[:derivation_endpoint] ||= { options: {}, derivations: {} }
|
31
|
+
uploader.opts[:derivation_endpoint][:options].merge!(opts)
|
31
32
|
|
32
|
-
uploader.opts[:
|
33
|
-
|
34
|
-
unless uploader.opts[:derivation_endpoint_options][:secret_key]
|
33
|
+
unless uploader.opts[:derivation_endpoint][:options][:secret_key]
|
35
34
|
fail Error, "must provide :secret_key option to derivation_endpoint plugin"
|
36
35
|
end
|
37
36
|
|
38
37
|
# instrumentation plugin integration
|
39
|
-
if uploader.respond_to?(:subscribe)
|
40
|
-
uploader.subscribe(:derivation, &uploader.opts[:derivation_endpoint_options][:log_subscriber])
|
41
|
-
end
|
38
|
+
uploader.subscribe(:derivation, &log_subscriber) if uploader.respond_to?(:subscribe)
|
42
39
|
end
|
43
40
|
|
44
41
|
module ClassMethods
|
@@ -76,15 +73,15 @@ class Shrine
|
|
76
73
|
# Registers a derivation block, which is called when the corresponding
|
77
74
|
# derivation URL is requested.
|
78
75
|
def derivation(name, &block)
|
79
|
-
derivations[name] = block
|
76
|
+
derivations[name.to_sym] = block
|
80
77
|
end
|
81
78
|
|
82
79
|
def derivations
|
83
|
-
opts[:
|
80
|
+
opts[:derivation_endpoint][:derivations]
|
84
81
|
end
|
85
82
|
|
86
83
|
def derivation_options
|
87
|
-
opts[:
|
84
|
+
opts[:derivation_endpoint][:options]
|
88
85
|
end
|
89
86
|
end
|
90
87
|
|
@@ -127,7 +124,7 @@ class Shrine
|
|
127
124
|
attr_reader :name, :args, :source, :options
|
128
125
|
|
129
126
|
def initialize(name:, args:, source:, options:)
|
130
|
-
@name = name
|
127
|
+
@name = name.to_sym
|
131
128
|
@args = args
|
132
129
|
@source = source
|
133
130
|
@options = options
|
@@ -163,16 +160,22 @@ class Shrine
|
|
163
160
|
|
164
161
|
# Uploads the derivation result to a dedicated destination on the specified
|
165
162
|
# Shrine storage.
|
166
|
-
def upload(file = nil)
|
167
|
-
Derivation::Upload.new(self).call(file)
|
163
|
+
def upload(file = nil, **options)
|
164
|
+
Derivation::Upload.new(self).call(file, **options)
|
168
165
|
end
|
169
166
|
|
170
|
-
# Returns a Shrine::UploadedFile object pointing to the uploaded
|
171
|
-
#
|
167
|
+
# Returns a Shrine::UploadedFile object pointing to the uploaded derivative
|
168
|
+
# if it exists.
|
172
169
|
def retrieve
|
173
170
|
Derivation::Retrieve.new(self).call
|
174
171
|
end
|
175
172
|
|
173
|
+
# Returns opened Shrine::UploadedFile object pointing to the uploaded
|
174
|
+
# derivative if it exists.
|
175
|
+
def opened
|
176
|
+
Derivation::Opened.new(self).call
|
177
|
+
end
|
178
|
+
|
176
179
|
# Deletes the derivation result from the storage.
|
177
180
|
def delete
|
178
181
|
Derivation::Delete.new(self).call
|
@@ -189,12 +192,10 @@ class Shrine
|
|
189
192
|
option :cache_control, default: -> { default_cache_control }
|
190
193
|
option :disposition, default: -> { "inline" }
|
191
194
|
option :download, default: -> { true }
|
192
|
-
option :download_errors, default: -> { [] }
|
193
195
|
option :download_options, default: -> { {} }
|
194
196
|
option :expires_in
|
195
197
|
option :filename, default: -> { default_filename }
|
196
198
|
option :host
|
197
|
-
option :include_uploaded_file, default: -> { false }
|
198
199
|
option :metadata, default: -> { [] }
|
199
200
|
option :prefix
|
200
201
|
option :secret_key
|
@@ -260,7 +261,7 @@ class Shrine
|
|
260
261
|
|
261
262
|
# The source uploaded file storage is the default derivative storage.
|
262
263
|
def default_upload_storage
|
263
|
-
source.storage_key
|
264
|
+
source.storage_key
|
264
265
|
end
|
265
266
|
|
266
267
|
# Allows caching for 1 year or until the URL expires.
|
@@ -399,10 +400,10 @@ class Shrine
|
|
399
400
|
|
400
401
|
begin
|
401
402
|
status, headers, body = derivation.response(request.env)
|
402
|
-
rescue Derivation::NotFound
|
403
|
-
error!(404, "Unknown derivation \"#{name}\"")
|
404
403
|
rescue Derivation::SourceNotFound
|
405
404
|
error!(404, "Source file not found")
|
405
|
+
rescue Derivation::NotFound
|
406
|
+
error!(404, "Unknown derivation \"#{name}\"")
|
406
407
|
end
|
407
408
|
|
408
409
|
# tell clients to cache the derivation result if it was successful
|
@@ -504,28 +505,21 @@ class Shrine
|
|
504
505
|
# uploads the result. If the derivation result is already uploaded, uses
|
505
506
|
# the `rack_response` plugin to generate a Rack response triple.
|
506
507
|
def upload_response(env)
|
507
|
-
uploaded_file = derivation.retrieve
|
508
|
+
uploaded_file = upload_redirect ? derivation.retrieve : derivation.opened
|
508
509
|
|
509
510
|
unless uploaded_file
|
510
511
|
derivative = derivation.generate
|
511
|
-
uploaded_file = derivation.upload(derivative)
|
512
|
+
uploaded_file = derivation.upload(derivative, delete: upload_redirect)
|
512
513
|
end
|
513
514
|
|
514
515
|
if upload_redirect
|
515
|
-
# we don't need the local derivation result here
|
516
|
-
if derivative
|
517
|
-
derivative.close
|
518
|
-
File.delete(derivative.path)
|
519
|
-
end
|
520
|
-
|
521
516
|
redirect_url = uploaded_file.url(upload_redirect_url_options)
|
522
517
|
|
523
518
|
[302, { "Location" => redirect_url }, []]
|
524
519
|
else
|
525
|
-
if derivative
|
520
|
+
if derivative
|
526
521
|
file_response(derivative, env)
|
527
522
|
else
|
528
|
-
uploaded_file.open(**upload_open_options)
|
529
523
|
uploaded_file.to_rack_response(
|
530
524
|
type: type,
|
531
525
|
disposition: disposition,
|
@@ -544,8 +538,10 @@ class Shrine
|
|
544
538
|
if Rack.release > "2"
|
545
539
|
server.serving(Rack::Request.new(env), path)
|
546
540
|
else
|
541
|
+
# :nocov:
|
547
542
|
server.path = path
|
548
543
|
server.serving(env)
|
544
|
+
# :nocov:
|
549
545
|
end
|
550
546
|
end
|
551
547
|
|
@@ -572,9 +568,7 @@ class Shrine
|
|
572
568
|
end
|
573
569
|
|
574
570
|
class Derivation::Generate < Derivation::Command
|
575
|
-
delegate :name, :args, :source,
|
576
|
-
:download, :download_errors, :download_options,
|
577
|
-
:include_uploaded_file
|
571
|
+
delegate :name, :args, :source, :download, :download_options
|
578
572
|
|
579
573
|
def call(file = nil)
|
580
574
|
derivative = generate(file)
|
@@ -589,22 +583,16 @@ class Shrine
|
|
589
583
|
# file.
|
590
584
|
def generate(file)
|
591
585
|
if download
|
592
|
-
with_downloaded(file)
|
593
|
-
if include_uploaded_file
|
594
|
-
derive(file, source, *args)
|
595
|
-
else
|
596
|
-
derive(file, *args)
|
597
|
-
end
|
598
|
-
end
|
586
|
+
with_downloaded(file) { |file| derive(file, *args) }
|
599
587
|
else
|
600
|
-
derive(
|
588
|
+
derive(*args)
|
601
589
|
end
|
602
590
|
end
|
603
591
|
|
604
592
|
# Calls the derivation block.
|
605
593
|
def derive(*args)
|
606
594
|
instrument_derivation do
|
607
|
-
|
595
|
+
derivation.instance_exec(*args, &derivation_block)
|
608
596
|
end
|
609
597
|
end
|
610
598
|
|
@@ -624,51 +612,35 @@ class Shrine
|
|
624
612
|
# Massages the derivation result, ensuring it's opened in binary mode,
|
625
613
|
# rewinded and flushed to disk.
|
626
614
|
def normalize(derivative)
|
627
|
-
|
628
|
-
derivative
|
629
|
-
|
630
|
-
derivative.close
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
derivative = derivative.open
|
636
|
-
else
|
637
|
-
fail Error, "unexpected derivation result: #{derivation.inspect} (expected File, Tempfile, String, or Pathname object)"
|
638
|
-
end
|
615
|
+
derivative =
|
616
|
+
case derivative
|
617
|
+
when Tempfile then derivative.tap(&:open)
|
618
|
+
when File then File.open(derivative.tap(&:close))
|
619
|
+
when String, Pathname then File.open(derivative)
|
620
|
+
else
|
621
|
+
fail Error, "unexpected derivation result: #{derivation.inspect} (expected File, Tempfile, String, or Pathname object)"
|
622
|
+
end
|
639
623
|
|
640
624
|
derivative.binmode
|
641
625
|
derivative
|
642
626
|
end
|
643
627
|
|
644
628
|
def with_downloaded(file, &block)
|
645
|
-
if file
|
646
|
-
|
647
|
-
|
648
|
-
download_source(&block)
|
649
|
-
end
|
629
|
+
return yield(file) if file
|
630
|
+
|
631
|
+
download_source(&block)
|
650
632
|
end
|
651
633
|
|
652
634
|
# Downloads the source uploaded file from the storage.
|
653
|
-
def download_source
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
raise Derivation::SourceNotFound, "source file \"#{source.id}\" was not found on storage :#{source.storage_key}"
|
658
|
-
end
|
659
|
-
|
660
|
-
yield file
|
661
|
-
ensure
|
662
|
-
file.close! if file
|
635
|
+
def download_source(&block)
|
636
|
+
source.download(**download_options, &block)
|
637
|
+
rescue Shrine::FileNotFound
|
638
|
+
raise Derivation::SourceNotFound, "source file \"#{source.id}\" was not found on storage :#{source.storage_key}"
|
663
639
|
end
|
664
640
|
|
665
641
|
def derivation_block
|
666
642
|
shrine_class.derivations[name] or fail Derivation::NotFound, "derivation #{name.inspect} is not defined"
|
667
643
|
end
|
668
|
-
|
669
|
-
def uploader
|
670
|
-
source.uploader
|
671
|
-
end
|
672
644
|
end
|
673
645
|
|
674
646
|
class Derivation::Upload < Derivation::Command
|
@@ -677,59 +649,48 @@ class Shrine
|
|
677
649
|
# Uploads the derivation result to the dedicated location on the storage.
|
678
650
|
# If a file object is given, uploads that to the storage, otherwise calls
|
679
651
|
# the derivation block and uploads the result.
|
680
|
-
def call(derivative = nil)
|
681
|
-
with_derivative(derivative) do |uploadable|
|
682
|
-
uploader.upload uploadable,
|
683
|
-
location: upload_location,
|
684
|
-
upload_options: upload_options
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
private
|
689
|
-
|
690
|
-
def with_derivative(derivative)
|
652
|
+
def call(derivative = nil, **options)
|
691
653
|
if derivative
|
692
|
-
|
693
|
-
# we want to keep the provided file open and rewinded
|
694
|
-
File.open(derivative.path, binmode: true) do |file|
|
695
|
-
yield file
|
696
|
-
end
|
697
|
-
ensure
|
698
|
-
# close the file handler if the file was deleted during upload
|
699
|
-
derivative.close if !File.exist?(derivative.path)
|
700
|
-
end
|
654
|
+
upload(derivative, **options)
|
701
655
|
else
|
702
|
-
|
703
|
-
begin
|
704
|
-
file = derivation.generate
|
705
|
-
yield file
|
706
|
-
ensure
|
707
|
-
file.close
|
708
|
-
File.delete(file.path)
|
709
|
-
end
|
656
|
+
upload(derivation.generate, delete: true, **options)
|
710
657
|
end
|
711
658
|
end
|
712
659
|
|
713
|
-
|
714
|
-
|
660
|
+
private
|
661
|
+
|
662
|
+
def upload(io, **options)
|
663
|
+
shrine_class.upload io, upload_storage,
|
664
|
+
location: upload_location,
|
665
|
+
upload_options: upload_options,
|
666
|
+
**options
|
715
667
|
end
|
716
668
|
end
|
717
669
|
|
718
670
|
class Derivation::Retrieve < Derivation::Command
|
719
|
-
delegate :
|
671
|
+
delegate :upload_storage, :upload_location
|
720
672
|
|
721
|
-
# Returns a Shrine::UploadedFile object pointing to the uploaded
|
722
|
-
#
|
673
|
+
# Returns a Shrine::UploadedFile object pointing to the uploaded derivative
|
674
|
+
# if it exists on the storage.
|
723
675
|
def call
|
724
|
-
uploaded_file = shrine_class
|
725
|
-
"storage" => upload_storage.to_s,
|
726
|
-
"id" => upload_location,
|
727
|
-
)
|
728
|
-
|
676
|
+
uploaded_file = shrine_class.uploaded_file(storage: upload_storage, id: upload_location)
|
729
677
|
uploaded_file if uploaded_file.exists?
|
730
678
|
end
|
731
679
|
end
|
732
680
|
|
681
|
+
class Derivation::Opened < Derivation::Command
|
682
|
+
delegate :upload_storage, :upload_location, :upload_open_options
|
683
|
+
|
684
|
+
# Returns opened Shrine::UploadedFile object pointing to the uploaded if
|
685
|
+
# it exists on the storage.
|
686
|
+
def call
|
687
|
+
uploaded_file = shrine_class.uploaded_file(storage: upload_storage, id: upload_location)
|
688
|
+
uploaded_file.open(**upload_open_options)
|
689
|
+
uploaded_file
|
690
|
+
rescue Shrine::FileNotFound
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
733
694
|
class Derivation::Delete < Derivation::Command
|
734
695
|
delegate :upload_location, :upload_storage
|
735
696
|
|