carrierwave 2.2.6 → 3.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +137 -67
- data/lib/carrierwave/compatibility/paperclip.rb +4 -2
- data/lib/carrierwave/downloader/base.rb +19 -11
- data/lib/carrierwave/downloader/remote_file.rb +13 -10
- data/lib/carrierwave/locale/en.yml +5 -3
- data/lib/carrierwave/mount.rb +36 -50
- data/lib/carrierwave/mounter.rb +117 -50
- data/lib/carrierwave/orm/activerecord.rb +21 -62
- data/lib/carrierwave/processing/mini_magick.rb +15 -13
- data/lib/carrierwave/processing/rmagick.rb +11 -15
- data/lib/carrierwave/processing/vips.rb +12 -12
- data/lib/carrierwave/sanitized_file.rb +49 -77
- data/lib/carrierwave/storage/abstract.rb +5 -5
- data/lib/carrierwave/storage/file.rb +6 -5
- data/lib/carrierwave/storage/fog.rb +74 -66
- data/lib/carrierwave/test/matchers.rb +11 -7
- data/lib/carrierwave/uploader/cache.rb +18 -10
- data/lib/carrierwave/uploader/callbacks.rb +1 -1
- data/lib/carrierwave/uploader/configuration.rb +10 -4
- data/lib/carrierwave/uploader/{content_type_whitelist.rb → content_type_allowlist.rb} +17 -15
- data/lib/carrierwave/uploader/{content_type_blacklist.rb → content_type_denylist.rb} +19 -14
- data/lib/carrierwave/uploader/dimension.rb +66 -0
- data/lib/carrierwave/uploader/{extension_whitelist.rb → extension_allowlist.rb} +17 -15
- data/lib/carrierwave/uploader/{extension_blacklist.rb → extension_denylist.rb} +18 -13
- data/lib/carrierwave/uploader/file_size.rb +2 -2
- data/lib/carrierwave/uploader/processing.rb +31 -6
- data/lib/carrierwave/uploader/proxy.rb +16 -3
- data/lib/carrierwave/uploader/store.rb +44 -6
- data/lib/carrierwave/uploader/url.rb +1 -1
- data/lib/carrierwave/uploader/versions.rb +154 -136
- data/lib/carrierwave/uploader.rb +10 -8
- data/lib/carrierwave/utilities/file_name.rb +47 -0
- data/lib/carrierwave/utilities/uri.rb +14 -11
- data/lib/carrierwave/utilities.rb +1 -0
- data/lib/carrierwave/validations/active_model.rb +4 -6
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +9 -17
- data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +1 -1
- data/lib/generators/uploader_generator.rb +3 -3
- metadata +32 -44
@@ -24,7 +24,8 @@ module CarrierWave
|
|
24
24
|
# [String] a cache id in the format TIMEINT-PID-COUNTER-RND
|
25
25
|
#
|
26
26
|
def self.generate_cache_id
|
27
|
-
[
|
27
|
+
[
|
28
|
+
Time.now.utc.to_i,
|
28
29
|
SecureRandom.random_number(1_000_000_000_000_000),
|
29
30
|
'%04d' % (CarrierWave::CacheCounter.increment % 10_000),
|
30
31
|
'%04d' % SecureRandom.random_number(10_000)
|
@@ -64,7 +65,7 @@ module CarrierWave
|
|
64
65
|
# It's recommended that you keep cache files in one place only.
|
65
66
|
#
|
66
67
|
def clean_cached_files!(seconds=60*60*24)
|
67
|
-
(cache_storage || storage).new(
|
68
|
+
(cache_storage || storage).new(new).clean_cache!(seconds)
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
@@ -102,7 +103,7 @@ module CarrierWave
|
|
102
103
|
# [String] a cache name, in the format TIMEINT-PID-COUNTER-RND/filename.txt
|
103
104
|
#
|
104
105
|
def cache_name
|
105
|
-
File.join(cache_id,
|
106
|
+
File.join(cache_id, original_filename) if cache_id && original_filename
|
106
107
|
end
|
107
108
|
|
108
109
|
##
|
@@ -110,7 +111,7 @@ module CarrierWave
|
|
110
111
|
#
|
111
112
|
# By default, cache!() uses copy_to(), which operates by copying the file
|
112
113
|
# to the cache, then deleting the original file. If move_to_cache() is
|
113
|
-
#
|
114
|
+
# overridden to return true, then cache!() uses move_to(), which simply
|
114
115
|
# moves the file to the cache. Useful for large files.
|
115
116
|
#
|
116
117
|
# === Parameters
|
@@ -129,6 +130,7 @@ module CarrierWave
|
|
129
130
|
|
130
131
|
self.cache_id = CarrierWave.generate_cache_id unless cache_id
|
131
132
|
|
133
|
+
@identifier = nil
|
132
134
|
@staged = true
|
133
135
|
@filename = new_file.filename
|
134
136
|
self.original_filename = new_file.filename
|
@@ -165,7 +167,7 @@ module CarrierWave
|
|
165
167
|
self.cache_id, self.original_filename = cache_name.to_s.split('/', 2)
|
166
168
|
@staged = true
|
167
169
|
@filename = original_filename
|
168
|
-
@file = cache_storage.retrieve_from_cache!(
|
170
|
+
@file = cache_storage.retrieve_from_cache!(full_original_filename)
|
169
171
|
end
|
170
172
|
end
|
171
173
|
|
@@ -180,20 +182,21 @@ module CarrierWave
|
|
180
182
|
#
|
181
183
|
# [String] the cache path
|
182
184
|
#
|
183
|
-
def cache_path(for_file=
|
185
|
+
def cache_path(for_file=full_original_filename)
|
184
186
|
File.join(*[cache_dir, @cache_id, for_file].compact)
|
185
187
|
end
|
186
188
|
|
189
|
+
protected
|
190
|
+
|
191
|
+
attr_reader :cache_id
|
192
|
+
|
187
193
|
private
|
188
194
|
|
189
195
|
def workfile_path(for_file=original_filename)
|
190
196
|
File.join(CarrierWave.tmp_path, @cache_id, version_name.to_s, for_file)
|
191
197
|
end
|
192
198
|
|
193
|
-
attr_reader :
|
194
|
-
|
195
|
-
# We can override the full_original_filename method in other modules
|
196
|
-
alias_method :full_original_filename, :original_filename
|
199
|
+
attr_reader :original_filename
|
197
200
|
|
198
201
|
def cache_id=(cache_id)
|
199
202
|
# Earlier version used 3 part cache_id. Thus we should allow for
|
@@ -210,6 +213,11 @@ module CarrierWave
|
|
210
213
|
def cache_storage
|
211
214
|
@cache_storage ||= (self.class.cache_storage || self.class.storage).new(self)
|
212
215
|
end
|
216
|
+
|
217
|
+
# We can override the full_original_filename method in other modules
|
218
|
+
def full_original_filename
|
219
|
+
forcing_extension(original_filename)
|
220
|
+
end
|
213
221
|
end # Cache
|
214
222
|
end # Uploader
|
215
223
|
end # CarrierWave
|
@@ -24,6 +24,7 @@ module CarrierWave
|
|
24
24
|
add_config :move_to_store
|
25
25
|
add_config :remove_previously_stored_files_after_update
|
26
26
|
add_config :downloader
|
27
|
+
add_config :force_extension
|
27
28
|
|
28
29
|
# fog
|
29
30
|
add_deprecated_config :fog_provider
|
@@ -44,6 +45,8 @@ module CarrierWave
|
|
44
45
|
add_config :validate_download
|
45
46
|
add_config :mount_on
|
46
47
|
add_config :cache_only
|
48
|
+
add_config :download_retry_count
|
49
|
+
add_config :download_retry_wait_time
|
47
50
|
|
48
51
|
# set default values
|
49
52
|
reset_config
|
@@ -77,7 +80,7 @@ module CarrierWave
|
|
77
80
|
def storage(storage = nil)
|
78
81
|
case storage
|
79
82
|
when Symbol
|
80
|
-
if storage_engine = storage_engines[storage]
|
83
|
+
if (storage_engine = storage_engines[storage])
|
81
84
|
self._storage = eval storage_engine
|
82
85
|
else
|
83
86
|
raise CarrierWave::UnknownStorageError, "Unknown storage: #{storage}"
|
@@ -123,7 +126,7 @@ module CarrierWave
|
|
123
126
|
@#{name} = nil
|
124
127
|
|
125
128
|
def self.#{name}(value=nil)
|
126
|
-
@#{name} = value
|
129
|
+
@#{name} = value unless value.nil?
|
127
130
|
return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
|
128
131
|
name = superclass.#{name}
|
129
132
|
return nil if name.nil? && !instance_variable_defined?(:@#{name})
|
@@ -179,8 +182,8 @@ module CarrierWave
|
|
179
182
|
#
|
180
183
|
def reset_config
|
181
184
|
configure do |config|
|
182
|
-
config.permissions =
|
183
|
-
config.directory_permissions =
|
185
|
+
config.permissions = 0o644
|
186
|
+
config.directory_permissions = 0o755
|
184
187
|
config.storage_engines = {
|
185
188
|
:file => "CarrierWave::Storage::File",
|
186
189
|
:fog => "CarrierWave::Storage::Fog"
|
@@ -200,6 +203,7 @@ module CarrierWave
|
|
200
203
|
config.move_to_store = false
|
201
204
|
config.remove_previously_stored_files_after_update = true
|
202
205
|
config.downloader = CarrierWave::Downloader::Base
|
206
|
+
config.force_extension = false
|
203
207
|
config.ignore_integrity_errors = true
|
204
208
|
config.ignore_processing_errors = true
|
205
209
|
config.ignore_download_errors = true
|
@@ -210,6 +214,8 @@ module CarrierWave
|
|
210
214
|
config.base_path = CarrierWave.base_path
|
211
215
|
config.enable_processing = true
|
212
216
|
config.ensure_multipart_form = true
|
217
|
+
config.download_retry_count = 0
|
218
|
+
config.download_retry_wait_time = 5
|
213
219
|
end
|
214
220
|
end
|
215
221
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module CarrierWave
|
2
2
|
module Uploader
|
3
|
-
module
|
3
|
+
module ContentTypeAllowlist
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
before :cache, :
|
7
|
+
before :cache, :check_content_type_allowlist!
|
8
8
|
end
|
9
9
|
|
10
10
|
##
|
@@ -29,32 +29,34 @@ module CarrierWave
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
def content_type_allowlist
|
32
|
-
if respond_to?(:content_type_whitelist)
|
33
|
-
ActiveSupport::Deprecation.warn "#content_type_whitelist is deprecated, use #content_type_allowlist instead." unless instance_variable_defined?(:@content_type_whitelist_warned)
|
34
|
-
@content_type_whitelist_warned = true
|
35
|
-
content_type_whitelist
|
36
|
-
end
|
37
32
|
end
|
38
33
|
|
39
34
|
private
|
40
35
|
|
41
|
-
def
|
42
|
-
|
36
|
+
def check_content_type_allowlist!(new_file)
|
37
|
+
allowlist = content_type_allowlist
|
38
|
+
if !allowlist && respond_to?(:content_type_whitelist) && content_type_whitelist
|
39
|
+
ActiveSupport::Deprecation.warn "#content_type_whitelist is deprecated, use #content_type_allowlist instead." unless instance_variable_defined?(:@content_type_whitelist_warned)
|
40
|
+
@content_type_whitelist_warned = true
|
41
|
+
allowlist = content_type_whitelist
|
42
|
+
end
|
43
|
+
|
44
|
+
return unless allowlist
|
43
45
|
|
44
46
|
content_type = new_file.content_type
|
45
|
-
if !
|
46
|
-
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.
|
47
|
-
allowed_types: Array(
|
47
|
+
if !allowlisted_content_type?(allowlist, content_type)
|
48
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_allowlist_error", content_type: content_type,
|
49
|
+
allowed_types: Array(allowlist).join(", "), default: :"errors.messages.content_type_whitelist_error")
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
|
-
def
|
52
|
-
Array(
|
53
|
+
def allowlisted_content_type?(allowlist, content_type)
|
54
|
+
Array(allowlist).any? do |item|
|
53
55
|
item = Regexp.quote(item) if item.class != Regexp
|
54
56
|
content_type =~ /\A#{item}/
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
|
-
end #
|
60
|
+
end # ContentTypeAllowlist
|
59
61
|
end # Uploader
|
60
62
|
end # CarrierWave
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module CarrierWave
|
2
2
|
module Uploader
|
3
|
-
module
|
3
|
+
module ContentTypeDenylist
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
before :cache, :
|
7
|
+
before :cache, :check_content_type_denylist!
|
8
8
|
end
|
9
9
|
|
10
10
|
##
|
@@ -29,29 +29,34 @@ module CarrierWave
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
def content_type_denylist
|
32
|
-
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def check_content_type_denylist!(new_file)
|
37
|
+
denylist = content_type_denylist
|
38
|
+
if !denylist && respond_to?(:content_type_blacklist) && content_type_blacklist
|
33
39
|
ActiveSupport::Deprecation.warn "#content_type_blacklist is deprecated, use #content_type_denylist instead." unless instance_variable_defined?(:@content_type_blacklist_warned)
|
34
40
|
@content_type_blacklist_warned = true
|
35
|
-
content_type_blacklist
|
41
|
+
denylist = content_type_blacklist
|
36
42
|
end
|
37
|
-
end
|
38
43
|
|
39
|
-
|
44
|
+
return unless denylist
|
40
45
|
|
41
|
-
|
42
|
-
|
46
|
+
ActiveSupport::Deprecation.warn "Use of #content_type_denylist is deprecated for the security reason, use #content_type_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@content_type_denylist_warned)
|
47
|
+
@content_type_denylist_warned = true
|
43
48
|
|
44
49
|
content_type = new_file.content_type
|
45
|
-
if
|
46
|
-
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.
|
47
|
-
content_type: content_type, default: :"errors.messages.
|
50
|
+
if denylisted_content_type?(denylist, content_type)
|
51
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_denylist_error",
|
52
|
+
content_type: content_type, default: :"errors.messages.content_type_blacklist_error")
|
48
53
|
end
|
49
54
|
end
|
50
55
|
|
51
|
-
def
|
52
|
-
Array(
|
56
|
+
def denylisted_content_type?(denylist, content_type)
|
57
|
+
Array(denylist).any? { |item| content_type =~ /#{item}/ }
|
53
58
|
end
|
54
59
|
|
55
|
-
end #
|
60
|
+
end # ContentTypeDenylist
|
56
61
|
end # Uploader
|
57
62
|
end # CarrierWave
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
module Uploader
|
5
|
+
module Dimension
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
before :cache, :check_dimensions!
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Override this method in your uploader to provide a Range of width which
|
14
|
+
# are allowed to be uploaded.
|
15
|
+
# === Returns
|
16
|
+
#
|
17
|
+
# [NilClass, Range] a width range which are permitted to be uploaded
|
18
|
+
#
|
19
|
+
# === Examples
|
20
|
+
#
|
21
|
+
# def width_range
|
22
|
+
# 1000..2000
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
def width_range; end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Override this method in your uploader to provide a Range of height which
|
29
|
+
# are allowed to be uploaded.
|
30
|
+
# === Returns
|
31
|
+
#
|
32
|
+
# [NilClass, Range] a height range which are permitted to be uploaded
|
33
|
+
#
|
34
|
+
# === Examples
|
35
|
+
#
|
36
|
+
# def height_range
|
37
|
+
# 1000..
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
def height_range; end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def check_dimensions!(new_file)
|
45
|
+
# NOTE: Skip the check for resized images
|
46
|
+
return if version_name.present?
|
47
|
+
return unless width_range || height_range
|
48
|
+
|
49
|
+
unless respond_to?(:width) || respond_to?(:height)
|
50
|
+
raise 'You need to include one of CarrierWave::MiniMagick, CarrierWave::RMagick, or CarrierWave::Vips to perform image dimension validation'
|
51
|
+
end
|
52
|
+
|
53
|
+
if width_range&.begin && width < width_range.begin
|
54
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.min_width_error", :min_width => ActiveSupport::NumberHelper.number_to_delimited(width_range.begin))
|
55
|
+
elsif width_range&.end && width > width_range.end
|
56
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.max_width_error", :max_width => ActiveSupport::NumberHelper.number_to_delimited(width_range.end))
|
57
|
+
elsif height_range&.begin && height < height_range.begin
|
58
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.min_height_error", :min_height => ActiveSupport::NumberHelper.number_to_delimited(height_range.begin))
|
59
|
+
elsif height_range&.end && height > height_range.end
|
60
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.max_height_error", :max_height => ActiveSupport::NumberHelper.number_to_delimited(height_range.end))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end # Dimension
|
65
|
+
end # Uploader
|
66
|
+
end # CarrierWave
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module CarrierWave
|
2
2
|
module Uploader
|
3
|
-
module
|
3
|
+
module ExtensionAllowlist
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
before :cache, :
|
7
|
+
before :cache, :check_extension_allowlist!
|
8
8
|
end
|
9
9
|
|
10
10
|
##
|
@@ -32,30 +32,32 @@ module CarrierWave
|
|
32
32
|
# end
|
33
33
|
#
|
34
34
|
def extension_allowlist
|
35
|
-
if respond_to?(:extension_whitelist)
|
36
|
-
ActiveSupport::Deprecation.warn "#extension_whitelist is deprecated, use #extension_allowlist instead." unless instance_variable_defined?(:@extension_whitelist_warned)
|
37
|
-
@extension_whitelist_warned = true
|
38
|
-
extension_whitelist
|
39
|
-
end
|
40
35
|
end
|
41
36
|
|
42
37
|
private
|
43
38
|
|
44
|
-
def
|
45
|
-
|
39
|
+
def check_extension_allowlist!(new_file)
|
40
|
+
allowlist = extension_allowlist
|
41
|
+
if !allowlist && respond_to?(:extension_whitelist) && extension_whitelist
|
42
|
+
ActiveSupport::Deprecation.warn "#extension_whitelist is deprecated, use #extension_allowlist instead." unless instance_variable_defined?(:@extension_whitelist_warned)
|
43
|
+
@extension_whitelist_warned = true
|
44
|
+
allowlist = extension_whitelist
|
45
|
+
end
|
46
|
+
|
47
|
+
return unless allowlist
|
46
48
|
|
47
49
|
extension = new_file.extension.to_s
|
48
|
-
if !
|
50
|
+
if !allowlisted_extension?(allowlist, extension)
|
49
51
|
# Look for whitelist first, then fallback to allowlist
|
50
|
-
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.
|
51
|
-
allowed_types: Array(
|
52
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_allowlist_error", extension: new_file.extension.inspect,
|
53
|
+
allowed_types: Array(allowlist).join(", "), default: :"errors.messages.extension_whitelist_error")
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
|
-
def
|
57
|
+
def allowlisted_extension?(allowlist, extension)
|
56
58
|
downcase_extension = extension.downcase
|
57
|
-
Array(
|
59
|
+
Array(allowlist).any? { |item| downcase_extension =~ /\A#{item}\z/i }
|
58
60
|
end
|
59
|
-
end #
|
61
|
+
end # ExtensionAllowlist
|
60
62
|
end # Uploader
|
61
63
|
end # CarrierWave
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module CarrierWave
|
2
2
|
module Uploader
|
3
|
-
module
|
3
|
+
module ExtensionDenylist
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
before :cache, :
|
7
|
+
before :cache, :check_extension_denylist!
|
8
8
|
end
|
9
9
|
|
10
10
|
##
|
@@ -32,27 +32,32 @@ module CarrierWave
|
|
32
32
|
# end
|
33
33
|
#
|
34
34
|
def extension_denylist
|
35
|
-
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def check_extension_denylist!(new_file)
|
40
|
+
denylist = extension_denylist
|
41
|
+
if !denylist && respond_to?(:extension_blacklist) && extension_blacklist
|
36
42
|
ActiveSupport::Deprecation.warn "#extension_blacklist is deprecated, use #extension_denylist instead." unless instance_variable_defined?(:@extension_blacklist_warned)
|
37
43
|
@extension_blacklist_warned = true
|
38
|
-
extension_blacklist
|
44
|
+
denylist = extension_blacklist
|
39
45
|
end
|
40
|
-
end
|
41
46
|
|
42
|
-
|
47
|
+
return unless denylist
|
43
48
|
|
44
|
-
|
45
|
-
|
49
|
+
ActiveSupport::Deprecation.warn "Use of #extension_denylist is deprecated for the security reason, use #extension_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@extension_denylist_warned)
|
50
|
+
@extension_denylist_warned = true
|
46
51
|
|
47
52
|
extension = new_file.extension.to_s
|
48
|
-
if
|
49
|
-
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.
|
50
|
-
prohibited_types: Array(extension_denylist).join(", "), default: :"errors.messages.
|
53
|
+
if denylisted_extension?(denylist, extension)
|
54
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_denylist_error", extension: new_file.extension.inspect,
|
55
|
+
prohibited_types: Array(extension_denylist).join(", "), default: :"errors.messages.extension_blacklist_error")
|
51
56
|
end
|
52
57
|
end
|
53
58
|
|
54
|
-
def
|
55
|
-
Array(
|
59
|
+
def denylisted_extension?(denylist, extension)
|
60
|
+
Array(denylist).any? { |item| extension =~ /\A#{item}\z/i }
|
56
61
|
end
|
57
62
|
end
|
58
63
|
end
|
@@ -14,7 +14,7 @@ module CarrierWave
|
|
14
14
|
# are allowed to be uploaded.
|
15
15
|
# === Returns
|
16
16
|
#
|
17
|
-
# [NilClass, Range] a size range which are permitted to be uploaded
|
17
|
+
# [NilClass, Range] a size range (in bytes) which are permitted to be uploaded
|
18
18
|
#
|
19
19
|
# === Examples
|
20
20
|
#
|
@@ -24,7 +24,7 @@ module CarrierWave
|
|
24
24
|
#
|
25
25
|
def size_range; end
|
26
26
|
|
27
|
-
|
27
|
+
private
|
28
28
|
|
29
29
|
def check_size!(new_file)
|
30
30
|
size = new_file.size
|
@@ -18,7 +18,7 @@ module CarrierWave
|
|
18
18
|
# Adds a processor callback which applies operations as a file is uploaded.
|
19
19
|
# The argument may be the name of any method of the uploader, expressed as a symbol,
|
20
20
|
# or a list of such methods, or a hash where the key is a method and the value is
|
21
|
-
# an array of arguments to call the method with
|
21
|
+
# an array of arguments to call the method with. Also accepts an :if or :unless condition
|
22
22
|
#
|
23
23
|
# === Parameters
|
24
24
|
#
|
@@ -31,6 +31,7 @@ module CarrierWave
|
|
31
31
|
# process :sepiatone, :vignette
|
32
32
|
# process :scale => [200, 200]
|
33
33
|
# process :scale => [200, 200], :if => :image?
|
34
|
+
# process :scale => [200, 200], :unless => :disallowed_image_type?
|
34
35
|
# process :sepiatone, :if => :image?
|
35
36
|
#
|
36
37
|
# def sepiatone
|
@@ -49,6 +50,10 @@ module CarrierWave
|
|
49
50
|
# ...
|
50
51
|
# end
|
51
52
|
#
|
53
|
+
# def disallowed_image_type?
|
54
|
+
# ...
|
55
|
+
# end
|
56
|
+
#
|
52
57
|
# end
|
53
58
|
#
|
54
59
|
def process(*args)
|
@@ -57,12 +62,17 @@ module CarrierWave
|
|
57
62
|
hash.merge!(arg)
|
58
63
|
end
|
59
64
|
|
60
|
-
|
65
|
+
condition_type = new_processors.keys.detect { |key| [:if, :unless].include?(key) }
|
66
|
+
condition = new_processors.delete(:if) || new_processors.delete(:unless)
|
61
67
|
new_processors.each do |processor, processor_args|
|
62
|
-
self.processors += [[processor, processor_args, condition]]
|
68
|
+
self.processors += [[processor, processor_args, condition, condition_type]]
|
69
|
+
|
70
|
+
if processor == :convert
|
71
|
+
# Treat :convert specially, since it should trigger the file extension change
|
72
|
+
force_extension processor_args
|
73
|
+
end
|
63
74
|
end
|
64
75
|
end
|
65
|
-
|
66
76
|
end # ClassMethods
|
67
77
|
|
68
78
|
##
|
@@ -72,13 +82,19 @@ module CarrierWave
|
|
72
82
|
return unless enable_processing
|
73
83
|
|
74
84
|
with_callbacks(:process, new_file) do
|
75
|
-
self.class.processors.each do |method, args, condition|
|
76
|
-
if
|
85
|
+
self.class.processors.each do |method, args, condition, condition_type|
|
86
|
+
if condition && condition_type == :if
|
77
87
|
if condition.respond_to?(:call)
|
78
88
|
next unless condition.call(self, :args => args, :method => method, :file => new_file)
|
79
89
|
else
|
80
90
|
next unless self.send(condition, new_file)
|
81
91
|
end
|
92
|
+
elsif condition && condition_type == :unless
|
93
|
+
if condition.respond_to?(:call)
|
94
|
+
next if condition.call(self, :args => args, :method => method, :file => new_file)
|
95
|
+
elsif self.send(condition, new_file)
|
96
|
+
next
|
97
|
+
end
|
82
98
|
end
|
83
99
|
|
84
100
|
if args.is_a? Array
|
@@ -95,6 +111,15 @@ module CarrierWave
|
|
95
111
|
end
|
96
112
|
end
|
97
113
|
|
114
|
+
private
|
115
|
+
|
116
|
+
def forcing_extension(filename)
|
117
|
+
if force_extension && filename
|
118
|
+
Pathname.new(filename).sub_ext(".#{force_extension.to_s.delete_prefix('.')}").to_s
|
119
|
+
else
|
120
|
+
filename
|
121
|
+
end
|
122
|
+
end
|
98
123
|
end # Processing
|
99
124
|
end # Uploader
|
100
125
|
end # CarrierWave
|
@@ -30,7 +30,20 @@ module CarrierWave
|
|
30
30
|
# [String] uniquely identifies a file
|
31
31
|
#
|
32
32
|
def identifier
|
33
|
-
@identifier || storage.try(:identifier)
|
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 the value of #cache_name is used
|
44
|
+
#
|
45
|
+
def temporary_identifier
|
46
|
+
cache_name || @identifier
|
34
47
|
end
|
35
48
|
|
36
49
|
##
|
@@ -40,8 +53,8 @@ module CarrierWave
|
|
40
53
|
#
|
41
54
|
# [String] contents of the file
|
42
55
|
#
|
43
|
-
def read
|
44
|
-
file.try(:read)
|
56
|
+
def read(*args)
|
57
|
+
file.try(:read, *args)
|
45
58
|
end
|
46
59
|
|
47
60
|
##
|