carrierwave 2.2.1 → 3.0.1
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 +4 -4
- data/README.md +137 -67
- data/lib/carrierwave/compatibility/paperclip.rb +4 -2
- data/lib/carrierwave/downloader/base.rb +27 -13
- data/lib/carrierwave/downloader/remote_file.rb +12 -9
- data/lib/carrierwave/locale/en.yml +5 -3
- data/lib/carrierwave/mount.rb +31 -50
- data/lib/carrierwave/mounter.rb +115 -50
- data/lib/carrierwave/orm/activerecord.rb +14 -60
- 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 +75 -67
- 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 +42 -7
- 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 +150 -132
- 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/uploader_generator.rb +3 -3
- metadata +31 -43
- /data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +0 -0
@@ -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 =~ /#{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,19 +82,44 @@ 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
|
98
|
+
end
|
99
|
+
|
100
|
+
if args.is_a? Array
|
101
|
+
kwargs, args = args.partition { |arg| arg.is_a? Hash }
|
102
|
+
end
|
103
|
+
|
104
|
+
if kwargs.present?
|
105
|
+
kwargs = kwargs.reduce(:merge)
|
106
|
+
self.send(method, *args, **kwargs)
|
107
|
+
else
|
108
|
+
self.send(method, *args)
|
82
109
|
end
|
83
|
-
self.send(method, *args)
|
84
110
|
end
|
85
111
|
end
|
86
112
|
end
|
87
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
|
88
123
|
end # Processing
|
89
124
|
end # Uploader
|
90
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 @original_filename is used
|
44
|
+
#
|
45
|
+
def temporary_identifier
|
46
|
+
@original_filename || @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
|
##
|