carrierwave 0.11.2 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of carrierwave might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/README.md +452 -178
- data/lib/carrierwave/compatibility/paperclip.rb +4 -4
- data/lib/carrierwave/downloader/base.rb +101 -0
- data/lib/carrierwave/downloader/remote_file.rb +68 -0
- data/lib/carrierwave/error.rb +1 -0
- data/lib/carrierwave/locale/en.yml +11 -5
- data/lib/carrierwave/mount.rb +212 -182
- data/lib/carrierwave/mounter.rb +255 -0
- data/lib/carrierwave/orm/activerecord.rb +22 -33
- data/lib/carrierwave/processing/mini_magick.rb +140 -84
- data/lib/carrierwave/processing/rmagick.rb +72 -21
- data/lib/carrierwave/processing/vips.rb +284 -0
- data/lib/carrierwave/processing.rb +1 -1
- data/lib/carrierwave/sanitized_file.rb +83 -84
- data/lib/carrierwave/storage/abstract.rb +16 -3
- data/lib/carrierwave/storage/file.rb +71 -3
- data/lib/carrierwave/storage/fog.rb +215 -57
- data/lib/carrierwave/storage.rb +1 -9
- data/lib/carrierwave/test/matchers.rb +88 -19
- data/lib/carrierwave/uploader/cache.rb +75 -45
- data/lib/carrierwave/uploader/callbacks.rb +1 -3
- data/lib/carrierwave/uploader/configuration.rb +80 -16
- data/lib/carrierwave/uploader/content_type_allowlist.rb +62 -0
- data/lib/carrierwave/uploader/content_type_denylist.rb +62 -0
- data/lib/carrierwave/uploader/default_url.rb +3 -5
- data/lib/carrierwave/uploader/dimension.rb +66 -0
- data/lib/carrierwave/uploader/download.rb +4 -74
- data/lib/carrierwave/uploader/extension_allowlist.rb +63 -0
- data/lib/carrierwave/uploader/extension_denylist.rb +64 -0
- data/lib/carrierwave/uploader/file_size.rb +43 -0
- data/lib/carrierwave/uploader/mountable.rb +13 -8
- data/lib/carrierwave/uploader/processing.rb +48 -13
- data/lib/carrierwave/uploader/proxy.rb +20 -9
- data/lib/carrierwave/uploader/remove.rb +0 -2
- data/lib/carrierwave/uploader/serialization.rb +2 -4
- data/lib/carrierwave/uploader/store.rb +59 -28
- data/lib/carrierwave/uploader/url.rb +8 -7
- data/lib/carrierwave/uploader/versions.rb +170 -122
- data/lib/carrierwave/uploader.rb +12 -10
- data/lib/carrierwave/utilities/file_name.rb +47 -0
- data/lib/carrierwave/utilities/uri.rb +14 -12
- data/lib/carrierwave/utilities.rb +1 -3
- data/lib/carrierwave/validations/active_model.rb +7 -11
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +39 -21
- data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +5 -9
- data/lib/generators/uploader_generator.rb +3 -3
- metadata +132 -80
- data/lib/carrierwave/locale/cs.yml +0 -11
- data/lib/carrierwave/locale/de.yml +0 -11
- data/lib/carrierwave/locale/el.yml +0 -11
- data/lib/carrierwave/locale/es.yml +0 -11
- data/lib/carrierwave/locale/fr.yml +0 -11
- data/lib/carrierwave/locale/ja.yml +0 -11
- data/lib/carrierwave/locale/nb.yml +0 -11
- data/lib/carrierwave/locale/nl.yml +0 -11
- data/lib/carrierwave/locale/pl.yml +0 -11
- data/lib/carrierwave/locale/pt-BR.yml +0 -11
- data/lib/carrierwave/locale/pt-PT.yml +0 -11
- data/lib/carrierwave/locale/ru.yml +0 -11
- data/lib/carrierwave/locale/sk.yml +0 -11
- data/lib/carrierwave/locale/tr.yml +0 -11
- data/lib/carrierwave/processing/mime_types.rb +0 -74
- data/lib/carrierwave/uploader/content_type_blacklist.rb +0 -48
- data/lib/carrierwave/uploader/content_type_whitelist.rb +0 -48
- data/lib/carrierwave/uploader/extension_blacklist.rb +0 -47
- data/lib/carrierwave/uploader/extension_whitelist.rb +0 -49
- data/lib/carrierwave/utilities/deprecation.rb +0 -18
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module CarrierWave
|
4
2
|
module Uploader
|
5
3
|
module Proxy
|
@@ -19,20 +17,33 @@ module CarrierWave
|
|
19
17
|
# [String] the path where the file is currently located.
|
20
18
|
#
|
21
19
|
def current_path
|
22
|
-
file.
|
20
|
+
file.try(:path)
|
23
21
|
end
|
24
22
|
|
25
23
|
alias_method :path, :current_path
|
26
24
|
|
27
25
|
##
|
28
|
-
# Returns a string that uniquely identifies the last stored file
|
26
|
+
# Returns a string that uniquely identifies the retrieved or last stored file
|
29
27
|
#
|
30
28
|
# === Returns
|
31
29
|
#
|
32
30
|
# [String] uniquely identifies a file
|
33
31
|
#
|
34
32
|
def identifier
|
35
|
-
|
33
|
+
@identifier || (file && storage.try(:identifier))
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Returns a String which is to be used as a temporary value which gets assigned to the column.
|
38
|
+
# The purpose is to mark the column that it will be updated. Finally before the save it will be
|
39
|
+
# overwritten by the #identifier value, which is usually #filename.
|
40
|
+
#
|
41
|
+
# === Returns
|
42
|
+
#
|
43
|
+
# [String] a temporary_identifier, by default @original_filename is used
|
44
|
+
#
|
45
|
+
def temporary_identifier
|
46
|
+
@original_filename || @identifier
|
36
47
|
end
|
37
48
|
|
38
49
|
##
|
@@ -42,8 +53,8 @@ module CarrierWave
|
|
42
53
|
#
|
43
54
|
# [String] contents of the file
|
44
55
|
#
|
45
|
-
def read
|
46
|
-
file.
|
56
|
+
def read(*args)
|
57
|
+
file.try(:read, *args)
|
47
58
|
end
|
48
59
|
|
49
60
|
##
|
@@ -54,7 +65,7 @@ module CarrierWave
|
|
54
65
|
# [Integer] size of the file
|
55
66
|
#
|
56
67
|
def size
|
57
|
-
file.
|
68
|
+
file.try(:size) || 0
|
58
69
|
end
|
59
70
|
|
60
71
|
##
|
@@ -80,7 +91,7 @@ module CarrierWave
|
|
80
91
|
# [String] content type of the file
|
81
92
|
#
|
82
93
|
def content_type
|
83
|
-
file.
|
94
|
+
file.try(:content_type)
|
84
95
|
end
|
85
96
|
|
86
97
|
end # Proxy
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require "json"
|
4
2
|
require "active_support/core_ext/hash"
|
5
3
|
|
@@ -9,11 +7,11 @@ module CarrierWave
|
|
9
7
|
extend ActiveSupport::Concern
|
10
8
|
|
11
9
|
def serializable_hash(options = nil)
|
12
|
-
{"url" => url}.merge Hash[versions.map { |name, version| [name, { "url" => version.url }] }]
|
10
|
+
{"url" => url}.merge Hash[versions.map { |name, version| [name.to_s, { "url" => version.url }] }]
|
13
11
|
end
|
14
12
|
|
15
13
|
def as_json(options=nil)
|
16
|
-
|
14
|
+
serializable_hash
|
17
15
|
end
|
18
16
|
|
19
17
|
def to_json(options=nil)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module CarrierWave
|
4
2
|
module Uploader
|
5
3
|
module Store
|
@@ -9,6 +7,15 @@ module CarrierWave
|
|
9
7
|
include CarrierWave::Uploader::Configuration
|
10
8
|
include CarrierWave::Uploader::Cache
|
11
9
|
|
10
|
+
included do
|
11
|
+
prepend Module.new {
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@file, @filename, @cache_id, @identifier, @deduplication_index = nil
|
15
|
+
end
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
12
19
|
##
|
13
20
|
# Override this in your Uploader to change the filename.
|
14
21
|
#
|
@@ -27,9 +34,26 @@ module CarrierWave
|
|
27
34
|
@filename
|
28
35
|
end
|
29
36
|
|
37
|
+
##
|
38
|
+
# Returns a filename which doesn't conflict with already-stored files.
|
39
|
+
#
|
40
|
+
# === Returns
|
41
|
+
#
|
42
|
+
# [String] the filename with suffix added for deduplication
|
43
|
+
#
|
44
|
+
def deduplicated_filename
|
45
|
+
return unless filename
|
46
|
+
return filename unless @deduplication_index
|
47
|
+
|
48
|
+
parts = filename.split('.')
|
49
|
+
basename = parts.shift
|
50
|
+
basename.sub!(/ ?\(\d+\)\z/, '')
|
51
|
+
([basename.to_s + (@deduplication_index > 1 ? "(#{@deduplication_index})" : '')] + parts).join('.')
|
52
|
+
end
|
53
|
+
|
30
54
|
##
|
31
55
|
# Calculates the path where the file should be stored. If +for_file+ is given, it will be
|
32
|
-
# used as the
|
56
|
+
# used as the identifier, otherwise +CarrierWave::Uploader#identifier+ is assumed.
|
33
57
|
#
|
34
58
|
# === Parameters
|
35
59
|
#
|
@@ -39,7 +63,7 @@ module CarrierWave
|
|
39
63
|
#
|
40
64
|
# [String] the store path
|
41
65
|
#
|
42
|
-
def store_path(for_file=
|
66
|
+
def store_path(for_file=identifier)
|
43
67
|
File.join([store_dir, full_filename(for_file)].compact)
|
44
68
|
end
|
45
69
|
|
@@ -53,32 +77,18 @@ module CarrierWave
|
|
53
77
|
# [new_file (File, IOString, Tempfile)] any kind of file object
|
54
78
|
#
|
55
79
|
def store!(new_file=nil)
|
56
|
-
cache!(new_file) if new_file &&
|
57
|
-
if @file
|
80
|
+
cache!(new_file) if new_file && !cached?
|
81
|
+
if !cache_only && @file && @cache_id
|
58
82
|
with_callbacks(:store, new_file) do
|
59
83
|
new_file = storage.store!(@file)
|
60
|
-
|
61
|
-
|
84
|
+
if delete_tmp_file_after_storage
|
85
|
+
@file.delete unless move_to_store
|
86
|
+
cache_storage.delete_dir!(cache_path(nil))
|
87
|
+
end
|
62
88
|
@file = new_file
|
63
|
-
@
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
##
|
69
|
-
# Deletes a cache id (tmp dir in cache)
|
70
|
-
#
|
71
|
-
def delete_cache_id
|
72
|
-
if @cache_id
|
73
|
-
path = File.expand_path(File.join(cache_dir, @cache_id), CarrierWave.root)
|
74
|
-
begin
|
75
|
-
Dir.rmdir(path)
|
76
|
-
rescue Errno::ENOENT
|
77
|
-
# Ignore: path does not exist
|
78
|
-
rescue Errno::ENOTDIR
|
79
|
-
# Ignore: path is not a dir
|
80
|
-
rescue Errno::ENOTEMPTY, Errno::EEXIST
|
81
|
-
# Ignore: dir is not empty
|
89
|
+
@identifier = storage.identifier
|
90
|
+
@cache_id = @deduplication_index = nil
|
91
|
+
@staged = false
|
82
92
|
end
|
83
93
|
end
|
84
94
|
end
|
@@ -93,13 +103,34 @@ module CarrierWave
|
|
93
103
|
def retrieve_from_store!(identifier)
|
94
104
|
with_callbacks(:retrieve_from_store, identifier) do
|
95
105
|
@file = storage.retrieve!(identifier)
|
106
|
+
@identifier = identifier
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Look for an identifier which doesn't collide with the given already-stored identifiers.
|
112
|
+
# It is done by adding a index number as the suffix.
|
113
|
+
# For example, if there's 'image.jpg' and the @deduplication_index is set to 2,
|
114
|
+
# The stored file will be named as 'image(2).jpg'.
|
115
|
+
#
|
116
|
+
# === Parameters
|
117
|
+
#
|
118
|
+
# [current_identifiers (Array[String])] List of identifiers for already-stored files
|
119
|
+
#
|
120
|
+
def deduplicate(current_identifiers)
|
121
|
+
@deduplication_index = nil
|
122
|
+
return unless current_identifiers.include?(identifier)
|
123
|
+
|
124
|
+
(1..current_identifiers.size + 1).each do |i|
|
125
|
+
@deduplication_index = i
|
126
|
+
break unless current_identifiers.include?(identifier)
|
96
127
|
end
|
97
128
|
end
|
98
129
|
|
99
130
|
private
|
100
131
|
|
101
132
|
def full_filename(for_file)
|
102
|
-
for_file
|
133
|
+
forcing_extension(for_file)
|
103
134
|
end
|
104
135
|
|
105
136
|
def storage
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module CarrierWave
|
4
2
|
module Uploader
|
5
3
|
module Url
|
@@ -17,12 +15,15 @@ module CarrierWave
|
|
17
15
|
# [String] the location where this file is accessible via a url
|
18
16
|
#
|
19
17
|
def url(options = {})
|
20
|
-
if file.respond_to?(:url)
|
21
|
-
file.method(:url).arity
|
22
|
-
|
23
|
-
|
18
|
+
if file.respond_to?(:url)
|
19
|
+
tmp_url = file.method(:url).arity.zero? ? file.url : file.url(options)
|
20
|
+
return tmp_url if tmp_url.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
if file.respond_to?(:path)
|
24
|
+
path = encode_path(file.path.sub(File.expand_path(root), ''))
|
24
25
|
|
25
|
-
if host = asset_host
|
26
|
+
if (host = asset_host)
|
26
27
|
if host.respond_to? :call
|
27
28
|
"#{host.call(file)}#{path}"
|
28
29
|
else
|
@@ -1,26 +1,113 @@
|
|
1
|
-
|
1
|
+
require "active_support/core_ext/object/deep_dup"
|
2
2
|
|
3
3
|
module CarrierWave
|
4
4
|
module Uploader
|
5
5
|
module Versions
|
6
|
+
class Builder
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
@options = {}
|
10
|
+
@blocks = []
|
11
|
+
@klass = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def configure(options, &block)
|
15
|
+
@options.merge!(options)
|
16
|
+
@blocks << block if block
|
17
|
+
@klass = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def build(superclass)
|
21
|
+
return @klass if @klass
|
22
|
+
@klass = Class.new(superclass)
|
23
|
+
superclass.const_set("#{@name.to_s.camelize}VersionUploader", @klass)
|
24
|
+
|
25
|
+
@klass.version_names += [@name]
|
26
|
+
@klass.versions = {}
|
27
|
+
@klass.processors = []
|
28
|
+
@klass.version_options = @options
|
29
|
+
@klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
30
|
+
# Define the enable_processing method for versions so they get the
|
31
|
+
# value from the parent class unless explicitly overwritten
|
32
|
+
def self.enable_processing(value=nil)
|
33
|
+
self.enable_processing = value if value
|
34
|
+
if defined?(@enable_processing) && !@enable_processing.nil?
|
35
|
+
@enable_processing
|
36
|
+
else
|
37
|
+
superclass.enable_processing
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Regardless of what is set in the parent uploader, do not enforce the
|
42
|
+
# move_to_cache config option on versions because it moves the original
|
43
|
+
# file to the version's target file.
|
44
|
+
#
|
45
|
+
# If you want to enforce this setting on versions, override this method
|
46
|
+
# in each version:
|
47
|
+
#
|
48
|
+
# version :thumb do
|
49
|
+
# def move_to_cache
|
50
|
+
# true
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
def move_to_cache
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
# Need to rely on the parent version's identifier, as versions don't have its own one.
|
59
|
+
def identifier
|
60
|
+
parent_version.identifier
|
61
|
+
end
|
62
|
+
RUBY
|
63
|
+
@blocks.each { |block| @klass.class_eval(&block) }
|
64
|
+
@klass
|
65
|
+
end
|
66
|
+
|
67
|
+
def deep_dup
|
68
|
+
other = dup
|
69
|
+
other.instance_variable_set(:@blocks, @blocks.dup)
|
70
|
+
other
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_missing(name, *args)
|
74
|
+
super
|
75
|
+
rescue NoMethodError => e
|
76
|
+
raise e.exception <<~ERROR
|
77
|
+
#{e.message}
|
78
|
+
If you're trying to configure a version, do it inside a block like `version(:thumb) { self.#{name} #{args.map(&:inspect).join(', ')} }`.
|
79
|
+
ERROR
|
80
|
+
end
|
81
|
+
|
82
|
+
def respond_to_missing?(*)
|
83
|
+
super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
6
87
|
extend ActiveSupport::Concern
|
7
88
|
|
8
89
|
include CarrierWave::Uploader::Callbacks
|
9
90
|
|
10
91
|
included do
|
11
|
-
class_attribute :versions, :version_names, :instance_reader => false, :instance_writer => false
|
92
|
+
class_attribute :versions, :version_names, :version_options, :instance_reader => false, :instance_writer => false
|
12
93
|
|
13
94
|
self.versions = {}
|
14
95
|
self.version_names = []
|
15
96
|
|
16
|
-
attr_accessor :
|
97
|
+
attr_accessor :parent_version
|
17
98
|
|
18
|
-
after :cache, :assign_parent_cache_id
|
19
99
|
after :cache, :cache_versions!
|
20
100
|
after :store, :store_versions!
|
21
101
|
after :remove, :remove_versions!
|
22
102
|
after :retrieve_from_cache, :retrieve_versions_from_cache!
|
23
103
|
after :retrieve_from_store, :retrieve_versions_from_store!
|
104
|
+
|
105
|
+
prepend Module.new {
|
106
|
+
def initialize(*)
|
107
|
+
super
|
108
|
+
@versions = nil
|
109
|
+
end
|
110
|
+
}
|
24
111
|
end
|
25
112
|
|
26
113
|
module ClassMethods
|
@@ -46,78 +133,33 @@ module CarrierWave
|
|
46
133
|
# process :scale => [200, 200]
|
47
134
|
# end
|
48
135
|
#
|
136
|
+
# version :square, :unless => :invalid_image_type? do
|
137
|
+
# process :scale => [100, 100]
|
138
|
+
# end
|
139
|
+
#
|
49
140
|
# end
|
50
141
|
#
|
51
142
|
def version(name, options = {}, &block)
|
52
143
|
name = name.to_sym
|
53
|
-
|
54
|
-
|
55
|
-
versions[name][:uploader].class_eval(&block) if block
|
56
|
-
versions[name]
|
57
|
-
end
|
58
|
-
|
59
|
-
def recursively_apply_block_to_versions(&block)
|
60
|
-
versions.each do |name, version|
|
61
|
-
version[:uploader].class_eval(&block)
|
62
|
-
version[:uploader].recursively_apply_block_to_versions(&block)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def build_version(name, options)
|
69
|
-
uploader = Class.new(self)
|
70
|
-
const_set("Uploader#{uploader.object_id}".gsub('-', '_'), uploader)
|
71
|
-
uploader.version_names += [name]
|
72
|
-
uploader.versions = {}
|
73
|
-
uploader.processors = []
|
74
|
-
|
75
|
-
uploader.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
76
|
-
# Define the enable_processing method for versions so they get the
|
77
|
-
# value from the parent class unless explicitly overwritten
|
78
|
-
def self.enable_processing(value=nil)
|
79
|
-
self.enable_processing = value if value
|
80
|
-
if !@enable_processing.nil?
|
81
|
-
@enable_processing
|
82
|
-
else
|
83
|
-
superclass.enable_processing
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Regardless of what is set in the parent uploader, do not enforce the
|
88
|
-
# move_to_cache config option on versions because it moves the original
|
89
|
-
# file to the version's target file.
|
90
|
-
#
|
91
|
-
# If you want to enforce this setting on versions, override this method
|
92
|
-
# in each version:
|
93
|
-
#
|
94
|
-
# version :thumb do
|
95
|
-
# def move_to_cache
|
96
|
-
# true
|
97
|
-
# end
|
98
|
-
# end
|
99
|
-
#
|
100
|
-
def move_to_cache
|
101
|
-
false
|
102
|
-
end
|
103
|
-
RUBY
|
144
|
+
versions[name] ||= Builder.new(name)
|
145
|
+
versions[name].configure(options, &block)
|
104
146
|
|
105
|
-
class_eval <<-RUBY
|
147
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
106
148
|
def #{name}
|
107
149
|
versions[:#{name}]
|
108
150
|
end
|
109
151
|
RUBY
|
110
152
|
|
111
|
-
|
112
|
-
current_version = {
|
113
|
-
name => {
|
114
|
-
:uploader => uploader,
|
115
|
-
:options => options
|
116
|
-
}
|
117
|
-
}
|
118
|
-
self.versions = versions.merge(current_version)
|
153
|
+
versions[name]
|
119
154
|
end
|
120
155
|
|
156
|
+
private
|
157
|
+
|
158
|
+
def inherited(subclass)
|
159
|
+
# To prevent subclass version changes affecting superclass versions
|
160
|
+
subclass.versions = versions.deep_dup
|
161
|
+
super
|
162
|
+
end
|
121
163
|
end # ClassMethods
|
122
164
|
|
123
165
|
##
|
@@ -131,7 +173,8 @@ module CarrierWave
|
|
131
173
|
return @versions if @versions
|
132
174
|
@versions = {}
|
133
175
|
self.class.versions.each do |name, version|
|
134
|
-
@versions[name] = version
|
176
|
+
@versions[name] = version.build(self.class).new(model, mounted_as)
|
177
|
+
@versions[name].parent_version = self
|
135
178
|
end
|
136
179
|
@versions
|
137
180
|
end
|
@@ -153,25 +196,44 @@ module CarrierWave
|
|
153
196
|
#
|
154
197
|
# === Returns
|
155
198
|
#
|
156
|
-
# [Boolean] True when the version exists according to its :if condition
|
199
|
+
# [Boolean] True when the version exists according to its :if or :unless condition
|
157
200
|
#
|
158
201
|
def version_exists?(name)
|
159
202
|
name = name.to_sym
|
160
203
|
|
161
|
-
return false unless
|
204
|
+
return false unless versions.has_key?(name)
|
205
|
+
|
206
|
+
if_condition = versions[name].class.version_options[:if]
|
207
|
+
unless_condition = versions[name].class.version_options[:unless]
|
162
208
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
209
|
+
if if_condition
|
210
|
+
if if_condition.respond_to?(:call)
|
211
|
+
if_condition.call(self, :version => name, :file => file)
|
212
|
+
else
|
213
|
+
send(if_condition, file)
|
214
|
+
end
|
215
|
+
elsif unless_condition
|
216
|
+
if unless_condition.respond_to?(:call)
|
217
|
+
!unless_condition.call(self, :version => name, :file => file)
|
167
218
|
else
|
168
|
-
send(
|
219
|
+
!send(unless_condition, file)
|
169
220
|
end
|
170
221
|
else
|
171
222
|
true
|
172
223
|
end
|
173
224
|
end
|
174
225
|
|
226
|
+
##
|
227
|
+
# Copies the parent's cache_id when caching a version file.
|
228
|
+
# This behavior is not essential but it makes easier to understand
|
229
|
+
# that the cached files are generated by the single upload attempt.
|
230
|
+
#
|
231
|
+
def cache!(*args)
|
232
|
+
self.cache_id = parent_version.cache_id if parent_version
|
233
|
+
|
234
|
+
super
|
235
|
+
end
|
236
|
+
|
175
237
|
##
|
176
238
|
# When given a version name as a parameter, will return the url for that version
|
177
239
|
# This also works with nested versions.
|
@@ -212,26 +274,26 @@ module CarrierWave
|
|
212
274
|
# Recreate versions and reprocess them. This can be used to recreate
|
213
275
|
# versions if their parameters somehow have changed.
|
214
276
|
#
|
215
|
-
def recreate_versions!(*
|
216
|
-
#
|
217
|
-
#
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
if versions.any?
|
223
|
-
file = sanitized_file if !cached?
|
224
|
-
store_versions!(file, versions)
|
225
|
-
else
|
226
|
-
cache! if !cached?
|
227
|
-
store!
|
277
|
+
def recreate_versions!(*names)
|
278
|
+
# As well as specified versions, we need to reprocess versions
|
279
|
+
# that are the source of another version.
|
280
|
+
|
281
|
+
self.cache_id = CarrierWave.generate_cache_id
|
282
|
+
derived_versions.each do |name, v|
|
283
|
+
v.cache!(file) if names.empty? || !(v.descendant_version_names & names).empty?
|
228
284
|
end
|
285
|
+
active_versions.each do |name, v|
|
286
|
+
v.store! if names.empty? || names.include?(name)
|
287
|
+
end
|
288
|
+
ensure
|
289
|
+
@cache_id = nil
|
229
290
|
end
|
230
291
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
292
|
+
protected
|
293
|
+
|
294
|
+
def descendant_version_names
|
295
|
+
[version_name] + derived_versions.flat_map do |name, version|
|
296
|
+
version.descendant_version_names
|
235
297
|
end
|
236
298
|
end
|
237
299
|
|
@@ -241,6 +303,20 @@ module CarrierWave
|
|
241
303
|
end
|
242
304
|
end
|
243
305
|
|
306
|
+
private
|
307
|
+
|
308
|
+
def derived_versions
|
309
|
+
active_versions.reject do |name, v|
|
310
|
+
v.class.version_options[:from_version]
|
311
|
+
end.to_a + active_sibling_versions.select do |name, v|
|
312
|
+
v.class.version_options[:from_version] == self.class.version_names.last
|
313
|
+
end.to_a
|
314
|
+
end
|
315
|
+
|
316
|
+
def active_sibling_versions
|
317
|
+
parent_version&.active_versions || []
|
318
|
+
end
|
319
|
+
|
244
320
|
def full_filename(for_file)
|
245
321
|
[version_name, super(for_file)].compact.join('_')
|
246
322
|
end
|
@@ -250,39 +326,11 @@ module CarrierWave
|
|
250
326
|
end
|
251
327
|
|
252
328
|
def cache_versions!(new_file)
|
253
|
-
|
254
|
-
# initialized, so get the actual file based off of the current state of
|
255
|
-
# our file
|
256
|
-
processed_parent = SanitizedFile.new :tempfile => self.file,
|
257
|
-
:filename => new_file.original_filename
|
258
|
-
|
259
|
-
active_versions.each do |name, v|
|
260
|
-
next if v.cached?
|
261
|
-
|
262
|
-
v.send(:cache_id=, cache_id)
|
263
|
-
# If option :from_version is present, create cache using cached file from
|
264
|
-
# version indicated
|
265
|
-
if self.class.versions[name][:options] && self.class.versions[name][:options][:from_version]
|
266
|
-
# Maybe the reference version has not been cached yet
|
267
|
-
unless versions[self.class.versions[name][:options][:from_version]].cached?
|
268
|
-
versions[self.class.versions[name][:options][:from_version]].cache!(processed_parent)
|
269
|
-
end
|
270
|
-
processed_version = SanitizedFile.new :tempfile => versions[self.class.versions[name][:options][:from_version]],
|
271
|
-
:filename => new_file.original_filename
|
272
|
-
v.cache!(processed_version)
|
273
|
-
else
|
274
|
-
v.cache!(processed_parent)
|
275
|
-
end
|
276
|
-
end
|
329
|
+
derived_versions.each { |name, v| v.cache!(new_file) }
|
277
330
|
end
|
278
331
|
|
279
|
-
def store_versions!(new_file
|
280
|
-
|
281
|
-
active = Hash[active_versions]
|
282
|
-
versions.each { |v| active[v].try(:store!, new_file) } unless active.empty?
|
283
|
-
else
|
284
|
-
active_versions.each { |name, v| v.store!(new_file) }
|
285
|
-
end
|
332
|
+
def store_versions!(new_file)
|
333
|
+
active_versions.each { |name, v| v.store!(new_file) }
|
286
334
|
end
|
287
335
|
|
288
336
|
def remove_versions!
|
@@ -290,11 +338,11 @@ module CarrierWave
|
|
290
338
|
end
|
291
339
|
|
292
340
|
def retrieve_versions_from_cache!(cache_name)
|
293
|
-
|
341
|
+
active_versions.each { |name, v| v.retrieve_from_cache!(cache_name) }
|
294
342
|
end
|
295
343
|
|
296
344
|
def retrieve_versions_from_store!(identifier)
|
297
|
-
|
345
|
+
active_versions.each { |name, v| v.retrieve_from_store!(identifier) }
|
298
346
|
end
|
299
347
|
|
300
348
|
end # Versions
|
data/lib/carrierwave/uploader.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require "carrierwave/uploader/configuration"
|
4
2
|
require "carrierwave/uploader/callbacks"
|
5
3
|
require "carrierwave/uploader/proxy"
|
@@ -9,10 +7,12 @@ require "carrierwave/uploader/cache"
|
|
9
7
|
require "carrierwave/uploader/store"
|
10
8
|
require "carrierwave/uploader/download"
|
11
9
|
require "carrierwave/uploader/remove"
|
12
|
-
require "carrierwave/uploader/
|
13
|
-
require "carrierwave/uploader/
|
14
|
-
require "carrierwave/uploader/
|
15
|
-
require "carrierwave/uploader/
|
10
|
+
require "carrierwave/uploader/extension_allowlist"
|
11
|
+
require "carrierwave/uploader/extension_denylist"
|
12
|
+
require "carrierwave/uploader/content_type_allowlist"
|
13
|
+
require "carrierwave/uploader/content_type_denylist"
|
14
|
+
require "carrierwave/uploader/file_size"
|
15
|
+
require "carrierwave/uploader/dimension"
|
16
16
|
require "carrierwave/uploader/processing"
|
17
17
|
require "carrierwave/uploader/versions"
|
18
18
|
require "carrierwave/uploader/default_url"
|
@@ -53,10 +53,12 @@ module CarrierWave
|
|
53
53
|
include CarrierWave::Uploader::Store
|
54
54
|
include CarrierWave::Uploader::Download
|
55
55
|
include CarrierWave::Uploader::Remove
|
56
|
-
include CarrierWave::Uploader::
|
57
|
-
include CarrierWave::Uploader::
|
58
|
-
include CarrierWave::Uploader::
|
59
|
-
include CarrierWave::Uploader::
|
56
|
+
include CarrierWave::Uploader::ExtensionAllowlist
|
57
|
+
include CarrierWave::Uploader::ExtensionDenylist
|
58
|
+
include CarrierWave::Uploader::ContentTypeAllowlist
|
59
|
+
include CarrierWave::Uploader::ContentTypeDenylist
|
60
|
+
include CarrierWave::Uploader::FileSize
|
61
|
+
include CarrierWave::Uploader::Dimension
|
60
62
|
include CarrierWave::Uploader::Processing
|
61
63
|
include CarrierWave::Uploader::Versions
|
62
64
|
include CarrierWave::Uploader::DefaultUrl
|