carrierwave 3.0.0.beta → 3.0.0.rc
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 +104 -64
- data/lib/carrierwave/compatibility/paperclip.rb +4 -2
- data/lib/carrierwave/downloader/base.rb +12 -11
- data/lib/carrierwave/downloader/remote_file.rb +5 -6
- data/lib/carrierwave/locale/en.yml +4 -0
- data/lib/carrierwave/mount.rb +31 -82
- data/lib/carrierwave/mounter.rb +115 -50
- data/lib/carrierwave/orm/activerecord.rb +8 -59
- data/lib/carrierwave/processing/mini_magick.rb +13 -11
- data/lib/carrierwave/processing/rmagick.rb +7 -11
- data/lib/carrierwave/processing/vips.rb +9 -9
- data/lib/carrierwave/sanitized_file.rb +47 -37
- data/lib/carrierwave/storage/abstract.rb +5 -5
- data/lib/carrierwave/storage/file.rb +4 -3
- data/lib/carrierwave/storage/fog.rb +69 -50
- data/lib/carrierwave/test/matchers.rb +11 -7
- data/lib/carrierwave/uploader/cache.rb +17 -9
- data/lib/carrierwave/uploader/callbacks.rb +1 -1
- data/lib/carrierwave/uploader/configuration.rb +8 -4
- data/lib/carrierwave/uploader/dimension.rb +66 -0
- data/lib/carrierwave/uploader/file_size.rb +2 -2
- data/lib/carrierwave/uploader/processing.rb +21 -7
- data/lib/carrierwave/uploader/proxy.rb +16 -3
- data/lib/carrierwave/uploader/store.rb +43 -6
- data/lib/carrierwave/uploader/url.rb +1 -1
- data/lib/carrierwave/uploader/versions.rb +126 -134
- data/lib/carrierwave/uploader.rb +2 -0
- data/lib/carrierwave/utilities/file_name.rb +2 -2
- data/lib/carrierwave/utilities/uri.rb +14 -11
- data/lib/carrierwave/validations/active_model.rb +4 -6
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +8 -7
- data/lib/generators/uploader_generator.rb +3 -3
- metadata +18 -3
- /data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +0 -0
@@ -162,7 +162,7 @@ module CarrierWave
|
|
162
162
|
end
|
163
163
|
|
164
164
|
class File
|
165
|
-
DEFAULT_S3_REGION = 'us-east-1'
|
165
|
+
DEFAULT_S3_REGION = 'us-east-1'.freeze
|
166
166
|
|
167
167
|
include CarrierWave::Utilities::Uri
|
168
168
|
include CarrierWave::Utilities::FileName
|
@@ -198,27 +198,27 @@ module CarrierWave
|
|
198
198
|
# [NilClass] no authenticated url available
|
199
199
|
#
|
200
200
|
def authenticated_url(options = {})
|
201
|
-
if ['AWS', 'Google', 'Rackspace', 'OpenStack', 'AzureRM', 'Aliyun', 'backblaze'].include?(
|
201
|
+
if ['AWS', 'Google', 'Rackspace', 'OpenStack', 'AzureRM', 'Aliyun', 'backblaze'].include?(fog_provider)
|
202
202
|
# avoid a get by using local references
|
203
203
|
local_directory = connection.directories.new(:key => @uploader.fog_directory)
|
204
204
|
local_file = local_directory.files.new(:key => path)
|
205
205
|
expire_at = options[:expire_at] || ::Fog::Time.now.since(@uploader.fog_authenticated_url_expiration.to_i)
|
206
|
-
case
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
else
|
212
|
-
warn "Options hash not supported in #{local_file.class}. You may need to upgrade your Fog provider."
|
213
|
-
local_file.url(expire_at)
|
214
|
-
end
|
215
|
-
when 'Rackspace', 'OpenStack'
|
216
|
-
connection.get_object_https_url(@uploader.fog_directory, path, expire_at, options)
|
217
|
-
when 'Aliyun'
|
218
|
-
expire_at = expire_at - Time.now
|
219
|
-
local_file.url(expire_at)
|
206
|
+
case fog_provider
|
207
|
+
when 'AWS', 'Google'
|
208
|
+
# Older versions of fog-google do not support options as a parameter
|
209
|
+
if url_options_supported?(local_file)
|
210
|
+
local_file.url(expire_at, options)
|
220
211
|
else
|
212
|
+
warn "Options hash not supported in #{local_file.class}. You may need to upgrade your Fog provider."
|
221
213
|
local_file.url(expire_at)
|
214
|
+
end
|
215
|
+
when 'Rackspace', 'OpenStack'
|
216
|
+
connection.get_object_https_url(@uploader.fog_directory, path, expire_at, options)
|
217
|
+
when 'Aliyun'
|
218
|
+
expire_at -= Time.now
|
219
|
+
local_file.url(expire_at)
|
220
|
+
else
|
221
|
+
local_file.url(expire_at)
|
222
222
|
end
|
223
223
|
end
|
224
224
|
end
|
@@ -285,16 +285,16 @@ module CarrierWave
|
|
285
285
|
#
|
286
286
|
# [String] contents of file
|
287
287
|
def read
|
288
|
-
file_body = file
|
288
|
+
file_body = file&.body
|
289
289
|
|
290
290
|
return if file_body.nil?
|
291
291
|
return file_body unless file_body.is_a?(::File)
|
292
292
|
|
293
|
-
# Fog::Storage::XXX::File#body could return the source file which was
|
294
|
-
read_source_file
|
293
|
+
# Fog::Storage::XXX::File#body could return the source file which was uploaded to the remote server.
|
294
|
+
return read_source_file if ::File.exist?(file_body.path)
|
295
295
|
|
296
296
|
# If the source file doesn't exist, the remote content is read
|
297
|
-
@file = nil
|
297
|
+
@file = nil
|
298
298
|
file.body
|
299
299
|
end
|
300
300
|
|
@@ -332,7 +332,7 @@ module CarrierWave
|
|
332
332
|
fog_file = new_file.to_file
|
333
333
|
@content_type ||= new_file.content_type
|
334
334
|
@file = directory.files.create({
|
335
|
-
:body => fog_file
|
335
|
+
:body => fog_file || new_file.read,
|
336
336
|
:content_type => @content_type,
|
337
337
|
:key => path,
|
338
338
|
:public => @uploader.fog_public
|
@@ -353,7 +353,7 @@ module CarrierWave
|
|
353
353
|
#
|
354
354
|
def public_url
|
355
355
|
encoded_path = encode_path(path)
|
356
|
-
if host = @uploader.asset_host
|
356
|
+
if (host = @uploader.asset_host)
|
357
357
|
if host.respond_to? :call
|
358
358
|
"#{host.call(self)}/#{encoded_path}"
|
359
359
|
else
|
@@ -370,21 +370,22 @@ module CarrierWave
|
|
370
370
|
protocol = @uploader.fog_use_ssl_for_aws ? "https" : "http"
|
371
371
|
|
372
372
|
subdomain_regex = /^(?:[a-z]|\d(?!\d{0,2}(?:\d{1,3}){3}$))(?:[a-z0-9\.]|(?![\-])|\-(?![\.])){1,61}[a-z0-9]$/
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
373
|
+
# To use the virtual-hosted style, the bucket name needs to be representable as a subdomain
|
374
|
+
use_virtual_hosted_style = @uploader.fog_directory.to_s =~ subdomain_regex && !(protocol == 'https' && @uploader.fog_directory =~ /\./)
|
375
|
+
|
376
|
+
region = @uploader.fog_credentials[:region].to_s
|
377
|
+
regional_host = case region
|
378
|
+
when DEFAULT_S3_REGION, ''
|
379
|
+
's3.amazonaws.com'
|
380
|
+
else
|
381
|
+
"s3.#{region}.amazonaws.com"
|
382
|
+
end
|
383
|
+
|
384
|
+
if use_virtual_hosted_style
|
385
|
+
regional_host = 's3-accelerate.amazonaws.com' if @uploader.fog_aws_accelerate
|
386
|
+
"#{protocol}://#{@uploader.fog_directory}.#{regional_host}/#{encoded_path}"
|
379
387
|
else # directory is not a valid subdomain, so use path style for access
|
380
|
-
|
381
|
-
host = case region
|
382
|
-
when DEFAULT_S3_REGION, ''
|
383
|
-
's3.amazonaws.com'
|
384
|
-
else
|
385
|
-
"s3.#{region}.amazonaws.com"
|
386
|
-
end
|
387
|
-
"#{protocol}://#{host}/#{@uploader.fog_directory}/#{encoded_path}"
|
388
|
+
"#{protocol}://#{regional_host}/#{@uploader.fog_directory}/#{encoded_path}"
|
388
389
|
end
|
389
390
|
end
|
390
391
|
when 'Google'
|
@@ -424,7 +425,7 @@ module CarrierWave
|
|
424
425
|
# [NilClass] no file name available
|
425
426
|
#
|
426
427
|
def filename(options = {})
|
427
|
-
return unless file_url = url(options)
|
428
|
+
return unless (file_url = url(options))
|
428
429
|
CGI.unescape(file_url.split('?').first).gsub(/.*\/(.*?$)/, '\1')
|
429
430
|
end
|
430
431
|
|
@@ -444,6 +445,25 @@ module CarrierWave
|
|
444
445
|
CarrierWave::Storage::Fog::File.new(@uploader, @base, new_path)
|
445
446
|
end
|
446
447
|
|
448
|
+
##
|
449
|
+
# Return the local file
|
450
|
+
#
|
451
|
+
# === Returns
|
452
|
+
#
|
453
|
+
# [File] The local file as Ruby's File class
|
454
|
+
# or
|
455
|
+
# [NilClass] When there's no file, or the file is remotely stored
|
456
|
+
#
|
457
|
+
def to_file
|
458
|
+
return nil unless file.body.is_a? ::File
|
459
|
+
|
460
|
+
if file.body.closed?
|
461
|
+
::File.open(file.body.path) # Reopen if it's already closed
|
462
|
+
else
|
463
|
+
file.body
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
447
467
|
private
|
448
468
|
|
449
469
|
##
|
@@ -465,12 +485,10 @@ module CarrierWave
|
|
465
485
|
# [Fog::#{provider}::Directory] containing directory
|
466
486
|
#
|
467
487
|
def directory
|
468
|
-
@directory ||=
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
)
|
473
|
-
end
|
488
|
+
@directory ||= connection.directories.new(
|
489
|
+
:key => @uploader.fog_directory,
|
490
|
+
:public => @uploader.fog_public
|
491
|
+
)
|
474
492
|
end
|
475
493
|
|
476
494
|
##
|
@@ -492,9 +510,10 @@ module CarrierWave
|
|
492
510
|
end
|
493
511
|
|
494
512
|
def acl_header
|
495
|
-
|
513
|
+
case fog_provider
|
514
|
+
when 'AWS'
|
496
515
|
{ 'x-amz-acl' => @uploader.fog_public ? 'public-read' : 'private' }
|
497
|
-
|
516
|
+
when "Google"
|
498
517
|
@uploader.fog_public ? { destination_predefined_acl: "publicRead" } : {}
|
499
518
|
else
|
500
519
|
{}
|
@@ -505,14 +524,14 @@ module CarrierWave
|
|
505
524
|
@uploader.fog_credentials[:provider].to_s
|
506
525
|
end
|
507
526
|
|
508
|
-
def read_source_file
|
509
|
-
|
527
|
+
def read_source_file
|
528
|
+
source_file = to_file
|
529
|
+
return unless source_file
|
510
530
|
|
511
531
|
begin
|
512
|
-
|
513
|
-
file_body.read
|
532
|
+
source_file.read
|
514
533
|
ensure
|
515
|
-
|
534
|
+
source_file.close
|
516
535
|
end
|
517
536
|
end
|
518
537
|
|
@@ -45,11 +45,11 @@ module CarrierWave
|
|
45
45
|
def matches?(actual)
|
46
46
|
@actual = actual
|
47
47
|
# Satisfy expectation here. Return false or raise an error if it's not met.
|
48
|
-
(File.stat(@actual.path).mode &
|
48
|
+
(File.stat(@actual.path).mode & 0o777) == @expected
|
49
49
|
end
|
50
50
|
|
51
51
|
def failure_message
|
52
|
-
"expected #{@actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode &
|
52
|
+
"expected #{@actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0o777).to_s(8)}"
|
53
53
|
end
|
54
54
|
|
55
55
|
def failure_message_when_negated
|
@@ -76,11 +76,11 @@ module CarrierWave
|
|
76
76
|
def matches?(actual)
|
77
77
|
@actual = actual
|
78
78
|
# Satisfy expectation here. Return false or raise an error if it's not met.
|
79
|
-
(File.stat(File.dirname
|
79
|
+
(File.stat(File.dirname(@actual.path)).mode & 0o777) == @expected
|
80
80
|
end
|
81
81
|
|
82
82
|
def failure_message
|
83
|
-
"expected #{File.dirname @actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode &
|
83
|
+
"expected #{File.dirname @actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0o777).to_s(8)}"
|
84
84
|
end
|
85
85
|
|
86
86
|
def failure_message_when_negated
|
@@ -341,9 +341,11 @@ module CarrierWave
|
|
341
341
|
begin
|
342
342
|
require 'rmagick'
|
343
343
|
rescue LoadError
|
344
|
-
|
345
|
-
|
346
|
-
|
344
|
+
begin
|
345
|
+
require 'RMagick'
|
346
|
+
rescue LoadError
|
347
|
+
puts "WARNING: Failed to require rmagick, image processing may fail!"
|
348
|
+
end
|
347
349
|
end
|
348
350
|
end
|
349
351
|
MagickWrapper.new(filename)
|
@@ -353,6 +355,7 @@ module CarrierWave
|
|
353
355
|
|
354
356
|
class MagickWrapper # :nodoc:
|
355
357
|
attr_reader :image
|
358
|
+
|
356
359
|
def width
|
357
360
|
image.columns
|
358
361
|
end
|
@@ -372,6 +375,7 @@ module CarrierWave
|
|
372
375
|
|
373
376
|
class MiniMagickWrapper # :nodoc:
|
374
377
|
attr_reader :image
|
378
|
+
|
375
379
|
def width
|
376
380
|
image[:width]
|
377
381
|
end
|
@@ -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
|
##
|
@@ -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
|
@@ -45,6 +46,7 @@ module CarrierWave
|
|
45
46
|
add_config :mount_on
|
46
47
|
add_config :cache_only
|
47
48
|
add_config :download_retry_count
|
49
|
+
add_config :download_retry_wait_time
|
48
50
|
|
49
51
|
# set default values
|
50
52
|
reset_config
|
@@ -78,7 +80,7 @@ module CarrierWave
|
|
78
80
|
def storage(storage = nil)
|
79
81
|
case storage
|
80
82
|
when Symbol
|
81
|
-
if storage_engine = storage_engines[storage]
|
83
|
+
if (storage_engine = storage_engines[storage])
|
82
84
|
self._storage = eval storage_engine
|
83
85
|
else
|
84
86
|
raise CarrierWave::UnknownStorageError, "Unknown storage: #{storage}"
|
@@ -124,7 +126,7 @@ module CarrierWave
|
|
124
126
|
@#{name} = nil
|
125
127
|
|
126
128
|
def self.#{name}(value=nil)
|
127
|
-
@#{name} = value
|
129
|
+
@#{name} = value unless value.nil?
|
128
130
|
return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
|
129
131
|
name = superclass.#{name}
|
130
132
|
return nil if name.nil? && !instance_variable_defined?(:@#{name})
|
@@ -180,8 +182,8 @@ module CarrierWave
|
|
180
182
|
#
|
181
183
|
def reset_config
|
182
184
|
configure do |config|
|
183
|
-
config.permissions =
|
184
|
-
config.directory_permissions =
|
185
|
+
config.permissions = 0o644
|
186
|
+
config.directory_permissions = 0o755
|
185
187
|
config.storage_engines = {
|
186
188
|
:file => "CarrierWave::Storage::File",
|
187
189
|
:fog => "CarrierWave::Storage::Fog"
|
@@ -201,6 +203,7 @@ module CarrierWave
|
|
201
203
|
config.move_to_store = false
|
202
204
|
config.remove_previously_stored_files_after_update = true
|
203
205
|
config.downloader = CarrierWave::Downloader::Base
|
206
|
+
config.force_extension = false
|
204
207
|
config.ignore_integrity_errors = true
|
205
208
|
config.ignore_processing_errors = true
|
206
209
|
config.ignore_download_errors = true
|
@@ -212,6 +215,7 @@ module CarrierWave
|
|
212
215
|
config.enable_processing = true
|
213
216
|
config.ensure_multipart_form = true
|
214
217
|
config.download_retry_count = 0
|
218
|
+
config.download_retry_wait_time = 5
|
215
219
|
end
|
216
220
|
end
|
217
221
|
end
|
@@ -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
|
@@ -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
|
@@ -66,6 +66,11 @@ module CarrierWave
|
|
66
66
|
condition = new_processors.delete(:if) || new_processors.delete(:unless)
|
67
67
|
new_processors.each do |processor, processor_args|
|
68
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
|
69
74
|
end
|
70
75
|
end
|
71
76
|
end # ClassMethods
|
@@ -78,18 +83,18 @@ module CarrierWave
|
|
78
83
|
|
79
84
|
with_callbacks(:process, new_file) do
|
80
85
|
self.class.processors.each do |method, args, condition, condition_type|
|
81
|
-
if
|
86
|
+
if condition && condition_type == :if
|
82
87
|
if condition.respond_to?(:call)
|
83
88
|
next unless condition.call(self, :args => args, :method => method, :file => new_file)
|
84
89
|
else
|
85
90
|
next unless self.send(condition, new_file)
|
86
91
|
end
|
87
|
-
elsif
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
93
98
|
end
|
94
99
|
|
95
100
|
if args.is_a? Array
|
@@ -106,6 +111,15 @@ module CarrierWave
|
|
106
111
|
end
|
107
112
|
end
|
108
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
|
109
123
|
end # Processing
|
110
124
|
end # Uploader
|
111
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
|
##
|