carrierwave 1.3.4 → 2.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 +42 -12
- data/lib/carrierwave/downloader/base.rb +50 -0
- data/lib/carrierwave/downloader/remote_file.rb +42 -0
- data/lib/carrierwave/mount.rb +25 -19
- data/lib/carrierwave/mounter.rb +70 -48
- data/lib/carrierwave/orm/activerecord.rb +14 -8
- data/lib/carrierwave/processing/mini_magick.rb +100 -117
- data/lib/carrierwave/processing/rmagick.rb +5 -11
- data/lib/carrierwave/sanitized_file.rb +30 -15
- data/lib/carrierwave/storage/file.rb +2 -2
- data/lib/carrierwave/storage/fog.rb +20 -7
- data/lib/carrierwave/storage.rb +1 -0
- data/lib/carrierwave/uploader/cache.rb +23 -15
- data/lib/carrierwave/uploader/configuration.rb +28 -15
- data/lib/carrierwave/uploader/download.rb +2 -123
- data/lib/carrierwave/uploader/mountable.rb +6 -0
- data/lib/carrierwave/uploader/proxy.rb +2 -2
- data/lib/carrierwave/uploader/serialization.rb +1 -1
- data/lib/carrierwave/uploader/store.rb +5 -3
- data/lib/carrierwave/uploader/url.rb +2 -2
- data/lib/carrierwave/uploader/versions.rb +42 -12
- data/lib/carrierwave/uploader.rb +0 -9
- data/lib/carrierwave/validations/active_model.rb +3 -3
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +4 -0
- metadata +68 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d930fb9703b4bdb5ec81e14a01a5f07a260f39b52caed16978f193ddfd73159
|
4
|
+
data.tar.gz: 83facb0af8dd50905b36510986a0215d3e6a03b765e83b6b063a6bc8ad7bbaf0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa813176c7dca0e42e9e131d405eeec2324741c7dff79fc4ceed9c5d16dabb52d967f6e40a025fe431412d91e1cfcb9fd043655271de7d615938f89f9f075179
|
7
|
+
data.tar.gz: 16877c3b9ce32913719f0329b300bae18991de3d642702eed202639a2f9ecb0613e41c766f0ae9adf97d2d64247f86cb3cbdb47f75112542ba01dd82b3653539
|
data/README.md
CHANGED
@@ -30,13 +30,13 @@ $ gem install carrierwave
|
|
30
30
|
In Rails, add it to your Gemfile:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
gem 'carrierwave', '
|
33
|
+
gem 'carrierwave', '>= 2.0.0.rc', '< 3.0'
|
34
34
|
```
|
35
35
|
|
36
36
|
Finally, restart the server to apply the changes.
|
37
37
|
|
38
|
-
As of version
|
39
|
-
or higher. If you're on Rails
|
38
|
+
As of version 2.0, CarrierWave requires Rails 5.0 or higher and Ruby 2.2
|
39
|
+
or higher. If you're on Rails 4, you should use 1.x.
|
40
40
|
|
41
41
|
## Getting Started
|
42
42
|
|
@@ -190,6 +190,17 @@ u.avatars[0].current_path # => 'path/to/file.png'
|
|
190
190
|
u.avatars[0].identifier # => 'file.png'
|
191
191
|
```
|
192
192
|
|
193
|
+
If you want to preserve existing files on uploading new one, you can go like:
|
194
|
+
|
195
|
+
```erb
|
196
|
+
<% user.avatars.each do |avatar| %>
|
197
|
+
<%= hidden_field :user, :avatars, multiple: true, value: avatar.identifier %>
|
198
|
+
<% end %>
|
199
|
+
<%= form.file_field :avatars, multiple: true %>
|
200
|
+
```
|
201
|
+
|
202
|
+
Sorting avatars is supported as well by reordering `hidden_field`, an example using jQuery UI Sortable is available [here](https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Add%2C-remove-and-reorder-images-using-multiple-file-upload).
|
203
|
+
|
193
204
|
## Changing the storage directory
|
194
205
|
|
195
206
|
In order to change where uploaded files are put, just override the `store_dir`
|
@@ -255,6 +266,22 @@ class NoJsonUploader < CarrierWave::Uploader::Base
|
|
255
266
|
end
|
256
267
|
```
|
257
268
|
|
269
|
+
### CVE-2016-3714 (ImageTragick)
|
270
|
+
This version of CarrierWave has the ability to mitigate CVE-2016-3714. However, you **MUST** set a content_type_whitelist in your uploaders for this protection to be effective, and you **MUST** either disable ImageMagick's default SVG delegate or use the RSVG delegate for SVG processing.
|
271
|
+
|
272
|
+
|
273
|
+
A valid whitelist that will restrict your uploader to images only, and mitigate the CVE is:
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
class MyUploader < CarrierWave::Uploader::Base
|
277
|
+
def content_type_whitelist
|
278
|
+
[/image\//]
|
279
|
+
end
|
280
|
+
end
|
281
|
+
```
|
282
|
+
|
283
|
+
**WARNING**: A `content_type_whitelist` is the only form of whitelist or blacklist supported by CarrierWave that can effectively mitigate against CVE-2016-3714. Use of `extension_whitelist` will not inspect the file headers, and thus still leaves your application open to the vulnerability.
|
284
|
+
|
258
285
|
### Filenames and unicode chars
|
259
286
|
|
260
287
|
Another security issue you should care for is the file names (see
|
@@ -280,7 +307,7 @@ You no longer need to do this manually.
|
|
280
307
|
|
281
308
|
Often you'll want to add different versions of the same file. The classic example is image thumbnails. There is built in support for this*:
|
282
309
|
|
283
|
-
*Note:* You must have Imagemagick
|
310
|
+
*Note:* You must have Imagemagick installed to do image resizing.
|
284
311
|
|
285
312
|
Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
|
286
313
|
|
@@ -362,7 +389,7 @@ private
|
|
362
389
|
end
|
363
390
|
|
364
391
|
def is_landscape? picture
|
365
|
-
image = MiniMagick::Image.
|
392
|
+
image = MiniMagick::Image.new(picture.path)
|
366
393
|
image[:width] > image[:height]
|
367
394
|
end
|
368
395
|
|
@@ -651,7 +678,6 @@ If you want to use fog you must add in your CarrierWave initializer the
|
|
651
678
|
following lines
|
652
679
|
|
653
680
|
```ruby
|
654
|
-
config.fog_provider = 'fog' # 'fog/aws' etc. Defaults to 'fog'
|
655
681
|
config.fog_credentials = { ... } # Provider specific credentials
|
656
682
|
```
|
657
683
|
|
@@ -669,7 +695,6 @@ You can also pass in additional options, as documented fully in lib/carrierwave/
|
|
669
695
|
|
670
696
|
```ruby
|
671
697
|
CarrierWave.configure do |config|
|
672
|
-
config.fog_provider = 'fog/aws' # required
|
673
698
|
config.fog_credentials = {
|
674
699
|
provider: 'AWS', # required
|
675
700
|
aws_access_key_id: 'xxx', # required unless using use_iam_profile
|
@@ -695,6 +720,14 @@ end
|
|
695
720
|
|
696
721
|
That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
|
697
722
|
|
723
|
+
**Note**: for Carrierwave to work properly it needs credentials with the following permissions:
|
724
|
+
|
725
|
+
* `s3:ListBucket`
|
726
|
+
* `s3:PutObject`
|
727
|
+
* `s3:GetObject`
|
728
|
+
* `s3:DeleteObject`
|
729
|
+
* `s3:PutObjectAcl`
|
730
|
+
|
698
731
|
## Using Rackspace Cloud Files
|
699
732
|
|
700
733
|
[Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
|
@@ -710,7 +743,6 @@ Using a US-based account:
|
|
710
743
|
|
711
744
|
```ruby
|
712
745
|
CarrierWave.configure do |config|
|
713
|
-
config.fog_provider = "fog/rackspace/storage" # optional, defaults to "fog"
|
714
746
|
config.fog_credentials = {
|
715
747
|
provider: 'Rackspace',
|
716
748
|
rackspace_username: 'xxxxxx',
|
@@ -725,7 +757,6 @@ Using a UK-based account:
|
|
725
757
|
|
726
758
|
```ruby
|
727
759
|
CarrierWave.configure do |config|
|
728
|
-
config.fog_provider = "fog/rackspace/storage" # optional, defaults to "fog"
|
729
760
|
config.fog_credentials = {
|
730
761
|
provider: 'Rackspace',
|
731
762
|
rackspace_username: 'xxxxxx',
|
@@ -774,7 +805,6 @@ Please read the [fog-google README](https://github.com/fog/fog-google/blob/maste
|
|
774
805
|
|
775
806
|
```ruby
|
776
807
|
CarrierWave.configure do |config|
|
777
|
-
config.fog_provider = 'fog/google' # required
|
778
808
|
config.fog_credentials = {
|
779
809
|
provider: 'Google',
|
780
810
|
google_storage_access_key_id: 'xxxxxx',
|
@@ -871,8 +901,8 @@ manipulation methods.
|
|
871
901
|
|
872
902
|
## Using MiniMagick
|
873
903
|
|
874
|
-
MiniMagick is similar to RMagick but performs all the operations using the '
|
875
|
-
|
904
|
+
MiniMagick is similar to RMagick but performs all the operations using the 'convert'
|
905
|
+
CLI which is part of the standard ImageMagick kit. This allows you to have the power
|
876
906
|
of ImageMagick without having to worry about installing all the RMagick libraries.
|
877
907
|
|
878
908
|
See the MiniMagick site for more details:
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'addressable'
|
3
|
+
require 'carrierwave/downloader/remote_file'
|
4
|
+
|
5
|
+
module CarrierWave
|
6
|
+
module Downloader
|
7
|
+
class Base
|
8
|
+
attr_reader :uploader
|
9
|
+
|
10
|
+
def initialize(uploader)
|
11
|
+
@uploader = uploader
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Downloads a file from given URL and returns a RemoteFile.
|
16
|
+
#
|
17
|
+
# === Parameters
|
18
|
+
#
|
19
|
+
# [url (String)] The URL where the remote file is stored
|
20
|
+
# [remote_headers (Hash)] Request headers
|
21
|
+
#
|
22
|
+
def download(url, remote_headers = {})
|
23
|
+
headers = remote_headers.
|
24
|
+
reverse_merge('User-Agent' => "CarrierWave/#{CarrierWave::VERSION}")
|
25
|
+
begin
|
26
|
+
file = OpenURI.open_uri(process_uri(url.to_s), headers)
|
27
|
+
rescue StandardError => e
|
28
|
+
raise CarrierWave::DownloadError, "could not download file: #{e.message}"
|
29
|
+
end
|
30
|
+
CarrierWave::Downloader::RemoteFile.new(file)
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Processes the given URL by parsing and escaping it. Public to allow overriding.
|
35
|
+
#
|
36
|
+
# === Parameters
|
37
|
+
#
|
38
|
+
# [url (String)] The URL where the remote file is stored
|
39
|
+
#
|
40
|
+
def process_uri(uri)
|
41
|
+
uri_parts = uri.split('?')
|
42
|
+
encoded_uri = Addressable::URI.parse(uri_parts.shift).normalize.to_s
|
43
|
+
encoded_uri << '?' << URI.encode(uri_parts.join('?')) if uri_parts.any?
|
44
|
+
URI.parse(encoded_uri)
|
45
|
+
rescue URI::InvalidURIError, Addressable::URI::InvalidURIError
|
46
|
+
raise CarrierWave::DownloadError, "couldn't parse URL: #{uri}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Downloader
|
3
|
+
class RemoteFile
|
4
|
+
attr_reader :file
|
5
|
+
|
6
|
+
def initialize(file)
|
7
|
+
@file = file.is_a?(String) ? StringIO.new(file) : file
|
8
|
+
end
|
9
|
+
|
10
|
+
def original_filename
|
11
|
+
filename = filename_from_header || filename_from_uri
|
12
|
+
mime_type = MiniMime.lookup_by_content_type(file.content_type)
|
13
|
+
unless File.extname(filename).present? || mime_type.blank?
|
14
|
+
filename = "#{filename}.#{mime_type.extension}"
|
15
|
+
end
|
16
|
+
filename
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to?(*args)
|
20
|
+
super || file.respond_to?(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def filename_from_header
|
26
|
+
if file.meta.include? 'content-disposition'
|
27
|
+
match = file.meta['content-disposition'].match(/filename=(?:"([^"]+)"|([^";]+))/)
|
28
|
+
match[1].presence || match[2].presence
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def filename_from_uri
|
33
|
+
CGI.unescape(File.basename(file.base_uri.path))
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing(*args, &block)
|
37
|
+
file.send(*args, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/lib/carrierwave/mount.rb
CHANGED
@@ -174,17 +174,26 @@ module CarrierWave
|
|
174
174
|
return if frozen?
|
175
175
|
mounter = _mounter(:#{column})
|
176
176
|
|
177
|
-
if mounter.remove?
|
178
|
-
|
179
|
-
elsif mounter.identifiers.first
|
180
|
-
write_uploader(mounter.serialization_column, mounter.identifiers.first)
|
181
|
-
end
|
177
|
+
mounter.clear! if mounter.remove?
|
178
|
+
write_uploader(mounter.serialization_column, mounter.identifiers.first)
|
182
179
|
end
|
183
180
|
|
184
181
|
def #{column}_identifier
|
185
182
|
_mounter(:#{column}).read_identifiers[0]
|
186
183
|
end
|
187
184
|
|
185
|
+
def #{column}_integrity_error
|
186
|
+
#{column}_integrity_errors.last
|
187
|
+
end
|
188
|
+
|
189
|
+
def #{column}_processing_error
|
190
|
+
#{column}_processing_errors.last
|
191
|
+
end
|
192
|
+
|
193
|
+
def #{column}_download_error
|
194
|
+
#{column}_download_errors.last
|
195
|
+
end
|
196
|
+
|
188
197
|
def store_previous_changes_for_#{column}
|
189
198
|
attribute_changes = ::ActiveRecord.version.to_s.to_f >= 5.1 ? saved_changes : changes
|
190
199
|
@_previous_changes_for_#{column} = attribute_changes[_mounter(:#{column}).serialization_column]
|
@@ -240,9 +249,9 @@ module CarrierWave
|
|
240
249
|
# [store_images!] Stores all files that have been assigned with +images=+
|
241
250
|
# [remove_images!] Removes the uploaded file from the filesystem.
|
242
251
|
#
|
243
|
-
# [
|
244
|
-
# [
|
245
|
-
# [
|
252
|
+
# [image_integrity_errors] Returns error objects of files which failed to pass integrity check
|
253
|
+
# [image_processing_errors] Returns error objects of files which failed to be processed
|
254
|
+
# [image_download_errors] Returns error objects of files which failed to be downloaded
|
246
255
|
#
|
247
256
|
# [image_identifiers] Reads out the identifiers of the files
|
248
257
|
#
|
@@ -329,11 +338,8 @@ module CarrierWave
|
|
329
338
|
return if frozen?
|
330
339
|
mounter = _mounter(:#{column})
|
331
340
|
|
332
|
-
if mounter.remove?
|
333
|
-
|
334
|
-
elsif mounter.identifiers.any?
|
335
|
-
write_uploader(mounter.serialization_column, mounter.identifiers)
|
336
|
-
end
|
341
|
+
mounter.clear! if mounter.remove?
|
342
|
+
write_uploader(mounter.serialization_column, mounter.identifiers.presence)
|
337
343
|
end
|
338
344
|
|
339
345
|
def #{column}_identifiers
|
@@ -395,16 +401,16 @@ module CarrierWave
|
|
395
401
|
_mounter(:#{column}).store!
|
396
402
|
end
|
397
403
|
|
398
|
-
def #{column}
|
399
|
-
_mounter(:#{column}).
|
404
|
+
def #{column}_integrity_errors
|
405
|
+
_mounter(:#{column}).integrity_errors
|
400
406
|
end
|
401
407
|
|
402
|
-
def #{column}
|
403
|
-
_mounter(:#{column}).
|
408
|
+
def #{column}_processing_errors
|
409
|
+
_mounter(:#{column}).processing_errors
|
404
410
|
end
|
405
411
|
|
406
|
-
def #{column}
|
407
|
-
_mounter(:#{column}).
|
412
|
+
def #{column}_download_errors
|
413
|
+
_mounter(:#{column}).download_errors
|
408
414
|
end
|
409
415
|
|
410
416
|
def mark_remove_#{column}_false
|
data/lib/carrierwave/mounter.rb
CHANGED
@@ -3,14 +3,17 @@ module CarrierWave
|
|
3
3
|
# this is an internal class, used by CarrierWave::Mount so that
|
4
4
|
# we don't pollute the model with a lot of methods.
|
5
5
|
class Mounter #:nodoc:
|
6
|
-
attr_reader :column, :record, :remote_urls, :
|
7
|
-
:
|
6
|
+
attr_reader :column, :record, :remote_urls, :integrity_errors,
|
7
|
+
:processing_errors, :download_errors
|
8
8
|
attr_accessor :remove, :remote_request_headers
|
9
9
|
|
10
10
|
def initialize(record, column, options={})
|
11
11
|
@record = record
|
12
12
|
@column = column
|
13
13
|
@options = record.class.uploader_options[column]
|
14
|
+
@download_errors = []
|
15
|
+
@processing_errors = []
|
16
|
+
@integrity_errors = []
|
14
17
|
end
|
15
18
|
|
16
19
|
def uploader_class
|
@@ -38,21 +41,30 @@ module CarrierWave
|
|
38
41
|
end
|
39
42
|
|
40
43
|
def cache(new_files)
|
41
|
-
return if
|
44
|
+
return if !new_files.is_a?(Array) && new_files.blank?
|
45
|
+
old_uploaders = uploaders
|
42
46
|
@uploaders = new_files.map do |new_file|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
47
|
+
handle_error do
|
48
|
+
if new_file.is_a?(String)
|
49
|
+
if (uploader = old_uploaders.detect { |uploader| uploader.identifier == new_file })
|
50
|
+
uploader.staged = true
|
51
|
+
uploader
|
52
|
+
else
|
53
|
+
begin
|
54
|
+
uploader = blank_uploader
|
55
|
+
uploader.retrieve_from_cache!(new_file)
|
56
|
+
uploader
|
57
|
+
rescue CarrierWave::InvalidParameter
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
else
|
62
|
+
uploader = blank_uploader
|
63
|
+
uploader.cache!(new_file)
|
64
|
+
uploader
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end.compact
|
56
68
|
end
|
57
69
|
|
58
70
|
def cache_names
|
@@ -60,45 +72,36 @@ module CarrierWave
|
|
60
72
|
end
|
61
73
|
|
62
74
|
def cache_names=(cache_names)
|
63
|
-
return if
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
75
|
+
return if cache_names.blank?
|
76
|
+
clear_unstaged
|
77
|
+
cache_names.map do |cache_name|
|
78
|
+
begin
|
79
|
+
uploader = blank_uploader
|
80
|
+
uploader.retrieve_from_cache!(cache_name)
|
81
|
+
@uploaders << uploader
|
82
|
+
rescue CarrierWave::InvalidParameter
|
83
|
+
# ignore
|
84
|
+
end
|
68
85
|
end
|
69
|
-
rescue CarrierWave::InvalidParameter
|
70
86
|
end
|
71
87
|
|
72
88
|
def remote_urls=(urls)
|
73
|
-
return if
|
89
|
+
return if urls.blank? || urls.all?(&:blank?)
|
74
90
|
|
75
91
|
@remote_urls = urls
|
76
|
-
@download_error = nil
|
77
|
-
@integrity_error = nil
|
78
92
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
93
|
+
clear_unstaged
|
94
|
+
urls.zip(remote_request_headers || []).map do |url, header|
|
95
|
+
handle_error do
|
96
|
+
uploader = blank_uploader
|
97
|
+
uploader.download!(url, header || {})
|
98
|
+
@uploaders << uploader
|
99
|
+
end
|
83
100
|
end
|
84
|
-
|
85
|
-
rescue CarrierWave::DownloadError => e
|
86
|
-
@download_error = e
|
87
|
-
raise e unless option(:ignore_download_errors)
|
88
|
-
rescue CarrierWave::ProcessingError => e
|
89
|
-
@processing_error = e
|
90
|
-
raise e unless option(:ignore_processing_errors)
|
91
|
-
rescue CarrierWave::IntegrityError => e
|
92
|
-
@integrity_error = e
|
93
|
-
raise e unless option(:ignore_integrity_errors)
|
94
101
|
end
|
95
102
|
|
96
103
|
def store!
|
97
|
-
|
98
|
-
remove!
|
99
|
-
else
|
100
|
-
uploaders.reject(&:blank?).each(&:store!)
|
101
|
-
end
|
104
|
+
uploaders.reject(&:blank?).each(&:store!)
|
102
105
|
end
|
103
106
|
|
104
107
|
def urls(*args)
|
@@ -110,7 +113,7 @@ module CarrierWave
|
|
110
113
|
end
|
111
114
|
|
112
115
|
def remove?
|
113
|
-
remove.present? &&
|
116
|
+
remove.present? && remove !~ /\A0|false$\z/
|
114
117
|
end
|
115
118
|
|
116
119
|
def remove!
|
@@ -118,6 +121,10 @@ module CarrierWave
|
|
118
121
|
@uploaders = []
|
119
122
|
end
|
120
123
|
|
124
|
+
def clear!
|
125
|
+
@uploaders = []
|
126
|
+
end
|
127
|
+
|
121
128
|
def serialization_column
|
122
129
|
option(:mount_on) || column
|
123
130
|
end
|
@@ -146,9 +153,7 @@ module CarrierWave
|
|
146
153
|
end.path
|
147
154
|
end
|
148
155
|
before.each do |uploader|
|
149
|
-
if uploader.remove_previously_stored_files_after_update
|
150
|
-
uploader.remove!
|
151
|
-
end
|
156
|
+
uploader.remove! if uploader.remove_previously_stored_files_after_update && !after_paths.include?(uploader.path)
|
152
157
|
end
|
153
158
|
end
|
154
159
|
|
@@ -161,5 +166,22 @@ module CarrierWave
|
|
161
166
|
self.uploader_options[name] ||= record.class.uploader_option(column, name)
|
162
167
|
end
|
163
168
|
|
169
|
+
def clear_unstaged
|
170
|
+
@uploaders ||= []
|
171
|
+
@uploaders.keep_if(&:staged)
|
172
|
+
end
|
173
|
+
|
174
|
+
def handle_error
|
175
|
+
yield
|
176
|
+
rescue CarrierWave::DownloadError => e
|
177
|
+
@download_errors << e
|
178
|
+
raise e unless option(:ignore_download_errors)
|
179
|
+
rescue CarrierWave::ProcessingError => e
|
180
|
+
@processing_errors << e
|
181
|
+
raise e unless option(:ignore_processing_errors)
|
182
|
+
rescue CarrierWave::IntegrityError => e
|
183
|
+
@integrity_errors << e
|
184
|
+
raise e unless option(:ignore_integrity_errors)
|
185
|
+
end
|
164
186
|
end # Mounter
|
165
187
|
end # CarrierWave
|
@@ -12,7 +12,9 @@ module CarrierWave
|
|
12
12
|
def mount_uploader(column, uploader=nil, options={}, &block)
|
13
13
|
super
|
14
14
|
|
15
|
-
|
15
|
+
mod = Module.new
|
16
|
+
prepend mod
|
17
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
16
18
|
def remote_#{column}_url=(url)
|
17
19
|
column = _mounter(:#{column}).serialization_column
|
18
20
|
__send__(:"\#{column}_will_change!")
|
@@ -27,7 +29,9 @@ module CarrierWave
|
|
27
29
|
def mount_uploaders(column, uploader=nil, options={}, &block)
|
28
30
|
super
|
29
31
|
|
30
|
-
|
32
|
+
mod = Module.new
|
33
|
+
prepend mod
|
34
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
31
35
|
def remote_#{column}_urls=(url)
|
32
36
|
column = _mounter(:#{column}).serialization_column
|
33
37
|
__send__(:"\#{column}_will_change!")
|
@@ -52,15 +56,16 @@ module CarrierWave
|
|
52
56
|
validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
|
53
57
|
validates_download_of column if uploader_option(column.to_sym, :validate_download)
|
54
58
|
|
55
|
-
after_save :"store_#{column}!"
|
56
59
|
before_save :"write_#{column}_identifier"
|
60
|
+
after_save :"store_previous_changes_for_#{column}"
|
57
61
|
after_commit :"remove_#{column}!", :on => :destroy
|
58
62
|
after_commit :"mark_remove_#{column}_false", :on => :update
|
59
|
-
|
60
|
-
after_save :"store_previous_changes_for_#{column}"
|
61
63
|
after_commit :"remove_previously_stored_#{column}", :on => :update
|
64
|
+
after_commit :"store_#{column}!", :on => [:create, :update]
|
62
65
|
|
63
|
-
|
66
|
+
mod = Module.new
|
67
|
+
prepend mod
|
68
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
64
69
|
def #{column}=(new_file)
|
65
70
|
column = _mounter(:#{column}).serialization_column
|
66
71
|
if !(new_file.blank? && __send__(:#{column}).blank?)
|
@@ -72,8 +77,9 @@ module CarrierWave
|
|
72
77
|
|
73
78
|
def remove_#{column}=(value)
|
74
79
|
column = _mounter(:#{column}).serialization_column
|
75
|
-
|
76
|
-
|
80
|
+
result = super
|
81
|
+
__send__(:"\#{column}_will_change!") if _mounter(:#{column}).remove?
|
82
|
+
result
|
77
83
|
end
|
78
84
|
|
79
85
|
def remove_#{column}!
|