carrierwave 1.2.1 → 2.1.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 +5 -5
- data/README.md +80 -26
- data/lib/carrierwave/downloader/base.rb +83 -0
- data/lib/carrierwave/downloader/remote_file.rb +65 -0
- data/lib/carrierwave/locale/en.yml +1 -1
- data/lib/carrierwave/mount.rb +25 -19
- data/lib/carrierwave/mounter.rb +71 -48
- data/lib/carrierwave/orm/activerecord.rb +14 -8
- data/lib/carrierwave/processing/mini_magick.rb +101 -114
- data/lib/carrierwave/processing/rmagick.rb +18 -4
- data/lib/carrierwave/sanitized_file.rb +37 -22
- data/lib/carrierwave/storage/file.rb +7 -3
- data/lib/carrierwave/storage/fog.rb +83 -20
- data/lib/carrierwave/storage.rb +1 -0
- data/lib/carrierwave/uploader/cache.rb +23 -15
- data/lib/carrierwave/uploader/configuration.rb +29 -14
- data/lib/carrierwave/uploader/content_type_whitelist.rb +1 -1
- data/lib/carrierwave/uploader/download.rb +2 -79
- 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 +13 -2
- data/lib/carrierwave/uploader/url.rb +2 -2
- data/lib/carrierwave/uploader/versions.rb +50 -13
- data/lib/carrierwave/validations/active_model.rb +3 -3
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +24 -0
- data/lib/generators/templates/uploader.rb +0 -2
- metadata +123 -26
- data/lib/carrierwave/uploader/magic_mime_blacklist.rb +0 -94
- data/lib/carrierwave/uploader/magic_mime_whitelist.rb +0 -94
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 84145959d912145a2915ab7adb9ccbd6bf7a971ab00cef83fb7f5092c349c9c5
|
4
|
+
data.tar.gz: 9ba122388fb8ff36563001ea9144e4a1d523b7be78433fed2a971a82588de5c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70f718887e9f4223405d8f273cafaf429395725eead688918d454499a50063fdc748cc519440d2010f783cfa1ec3ba19f54b5e07dc644d195cbe6d59f1c5b6b2
|
7
|
+
data.tar.gz: 50907c92735e096c691a1ee7d440a2b83de736de3016b78c11796d0c558c283774236e5acf18abb552212816a38905986a6ec3ad0d956736f88c79ae99cd9aa6
|
data/README.md
CHANGED
@@ -4,8 +4,8 @@ This gem provides a simple and extremely flexible way to upload files from Ruby
|
|
4
4
|
It works well with Rack based web applications, such as Ruby on Rails.
|
5
5
|
|
6
6
|
[![Build Status](https://travis-ci.org/carrierwaveuploader/carrierwave.svg?branch=master)](http://travis-ci.org/carrierwaveuploader/carrierwave)
|
7
|
-
[![Code Climate](
|
8
|
-
[![
|
7
|
+
[![Code Climate](https://codeclimate.com/github/carrierwaveuploader/carrierwave.svg)](https://codeclimate.com/github/carrierwaveuploader/carrierwave)
|
8
|
+
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=carrierwave&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=carrierwave&package-manager=bundler&version-scheme=semver)
|
9
9
|
|
10
10
|
|
11
11
|
## Information
|
@@ -24,19 +24,19 @@ It works well with Rack based web applications, such as Ruby on Rails.
|
|
24
24
|
Install the latest release:
|
25
25
|
|
26
26
|
```
|
27
|
-
$ gem install carrierwave
|
27
|
+
$ gem install carrierwave
|
28
28
|
```
|
29
29
|
|
30
30
|
In Rails, add it to your Gemfile:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
gem 'carrierwave', '~>
|
33
|
+
gem 'carrierwave', '~> 2.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
|
|
@@ -89,7 +89,7 @@ a migration:
|
|
89
89
|
|
90
90
|
|
91
91
|
rails g migration add_avatar_to_users avatar:string
|
92
|
-
|
92
|
+
rails db:migrate
|
93
93
|
|
94
94
|
Open your model file and mount the uploader:
|
95
95
|
|
@@ -144,12 +144,12 @@ example, create a migration like this:
|
|
144
144
|
#### For databases with ActiveRecord json data type support (e.g. PostgreSQL, MySQL)
|
145
145
|
|
146
146
|
rails g migration add_avatars_to_users avatars:json
|
147
|
-
|
147
|
+
rails db:migrate
|
148
148
|
|
149
149
|
#### For database without ActiveRecord json data type support (e.g. SQLite)
|
150
150
|
|
151
151
|
rails g migration add_avatars_to_users avatars:string
|
152
|
-
|
152
|
+
rails db:migrate
|
153
153
|
|
154
154
|
__Note__: JSON datatype doesn't exists in SQLite adapter, that's why you can use a string datatype which will be serialized in model.
|
155
155
|
|
@@ -163,6 +163,9 @@ class User < ActiveRecord::Base
|
|
163
163
|
end
|
164
164
|
```
|
165
165
|
|
166
|
+
Make sure that you mount the uploader with write (mount_uploaders) with `s` not (mount_uploader)
|
167
|
+
in order to avoid errors when uploading multiple files
|
168
|
+
|
166
169
|
Make sure your file input fields are set up as multiple file fields. For
|
167
170
|
example in Rails you'll want to do something like this:
|
168
171
|
|
@@ -187,6 +190,17 @@ u.avatars[0].current_path # => 'path/to/file.png'
|
|
187
190
|
u.avatars[0].identifier # => 'file.png'
|
188
191
|
```
|
189
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
|
+
|
190
204
|
## Changing the storage directory
|
191
205
|
|
192
206
|
In order to change where uploaded files are put, just override the `store_dir`
|
@@ -252,6 +266,22 @@ class NoJsonUploader < CarrierWave::Uploader::Base
|
|
252
266
|
end
|
253
267
|
```
|
254
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
|
+
|
255
285
|
### Filenames and unicode chars
|
256
286
|
|
257
287
|
Another security issue you should care for is the file names (see
|
@@ -277,7 +307,7 @@ You no longer need to do this manually.
|
|
277
307
|
|
278
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*:
|
279
309
|
|
280
|
-
*Note:* You must have Imagemagick
|
310
|
+
*Note:* You must have Imagemagick installed to do image resizing.
|
281
311
|
|
282
312
|
Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
|
283
313
|
|
@@ -301,8 +331,14 @@ end
|
|
301
331
|
```
|
302
332
|
|
303
333
|
When this uploader is used, an uploaded image would be scaled to be no larger
|
304
|
-
than 800 by 800 pixels.
|
305
|
-
|
334
|
+
than 800 by 800 pixels. The original aspect ratio will be kept.
|
335
|
+
|
336
|
+
A version called `:thumb` is then created, which is scaled
|
337
|
+
to exactly 200 by 200 pixels. The thumbnail uses `resize_to_fill` which makes sure
|
338
|
+
that the width and height specified are filled, only cropping
|
339
|
+
if the aspect ratio requires it.
|
340
|
+
|
341
|
+
The above uploader could be used like this:
|
306
342
|
|
307
343
|
```ruby
|
308
344
|
uploader = AvatarUploader.new
|
@@ -315,6 +351,18 @@ uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
|
|
315
351
|
One important thing to remember is that process is called *before* versions are
|
316
352
|
created. This can cut down on processing cost.
|
317
353
|
|
354
|
+
### Processing Methods: mini_magick
|
355
|
+
|
356
|
+
- `convert` - Changes the image encoding format to the given format, eg. jpg
|
357
|
+
- `resize_to_limit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. Will only resize the image if it is larger than the specified dimensions. The resulting image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
|
358
|
+
- `resize_to_fit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. The image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
|
359
|
+
- `resize_to_fill` - Resize the image to fit within the specified dimensions while retaining the aspect ratio of the original image. If necessary, crop the image in the larger dimension. Optionally, a "gravity" may be specified, for example "Center", or "NorthEast".
|
360
|
+
- `resize_and_pad` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. If necessary, will pad the remaining area with the given color, which defaults to transparent (for gif and png, white for jpeg). Optionally, a "gravity" may be specified, as above.
|
361
|
+
|
362
|
+
See `carrierwave/processing/mini_magick.rb` for details.
|
363
|
+
|
364
|
+
### Nested versions
|
365
|
+
|
318
366
|
It is possible to nest versions within versions:
|
319
367
|
|
320
368
|
```ruby
|
@@ -351,7 +399,7 @@ private
|
|
351
399
|
end
|
352
400
|
|
353
401
|
def is_landscape? picture
|
354
|
-
image = MiniMagick::Image.
|
402
|
+
image = MiniMagick::Image.new(picture.path)
|
355
403
|
image[:width] > image[:height]
|
356
404
|
end
|
357
405
|
|
@@ -625,6 +673,8 @@ describe MyUploader do
|
|
625
673
|
end
|
626
674
|
```
|
627
675
|
|
676
|
+
If you're looking for minitest asserts, checkout [carrierwave_asserts](https://github.com/hcfairbanks/carrierwave_asserts).
|
677
|
+
|
628
678
|
Setting the enable_processing flag on an uploader will prevent any of the versions from processing as well.
|
629
679
|
Processing can be enabled for a single version by setting the processing flag on the version like so:
|
630
680
|
|
@@ -638,7 +688,6 @@ If you want to use fog you must add in your CarrierWave initializer the
|
|
638
688
|
following lines
|
639
689
|
|
640
690
|
```ruby
|
641
|
-
config.fog_provider = 'fog' # 'fog/aws' etc. Defaults to 'fog'
|
642
691
|
config.fog_credentials = { ... } # Provider specific credentials
|
643
692
|
```
|
644
693
|
|
@@ -656,18 +705,18 @@ You can also pass in additional options, as documented fully in lib/carrierwave/
|
|
656
705
|
|
657
706
|
```ruby
|
658
707
|
CarrierWave.configure do |config|
|
659
|
-
config.fog_provider = 'fog/aws' # required
|
660
708
|
config.fog_credentials = {
|
661
709
|
provider: 'AWS', # required
|
662
|
-
aws_access_key_id: 'xxx', # required
|
663
|
-
aws_secret_access_key: 'yyy', # required
|
710
|
+
aws_access_key_id: 'xxx', # required unless using use_iam_profile
|
711
|
+
aws_secret_access_key: 'yyy', # required unless using use_iam_profile
|
712
|
+
use_iam_profile: true, # optional, defaults to false
|
664
713
|
region: 'eu-west-1', # optional, defaults to 'us-east-1'
|
665
714
|
host: 's3.example.com', # optional, defaults to nil
|
666
715
|
endpoint: 'https://s3.example.com:8080' # optional, defaults to nil
|
667
716
|
}
|
668
|
-
config.fog_directory = '
|
669
|
-
config.fog_public = false
|
670
|
-
config.fog_attributes = { cache_control: "public, max-age=#{365.
|
717
|
+
config.fog_directory = 'name_of_bucket' # required
|
718
|
+
config.fog_public = false # optional, defaults to true
|
719
|
+
config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
|
671
720
|
end
|
672
721
|
```
|
673
722
|
|
@@ -681,6 +730,14 @@ end
|
|
681
730
|
|
682
731
|
That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
|
683
732
|
|
733
|
+
**Note**: for Carrierwave to work properly it needs credentials with the following permissions:
|
734
|
+
|
735
|
+
* `s3:ListBucket`
|
736
|
+
* `s3:PutObject`
|
737
|
+
* `s3:GetObject`
|
738
|
+
* `s3:DeleteObject`
|
739
|
+
* `s3:PutObjectAcl`
|
740
|
+
|
684
741
|
## Using Rackspace Cloud Files
|
685
742
|
|
686
743
|
[Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
|
@@ -696,7 +753,6 @@ Using a US-based account:
|
|
696
753
|
|
697
754
|
```ruby
|
698
755
|
CarrierWave.configure do |config|
|
699
|
-
config.fog_provider = "fog/rackspace/storage" # optional, defaults to "fog"
|
700
756
|
config.fog_credentials = {
|
701
757
|
provider: 'Rackspace',
|
702
758
|
rackspace_username: 'xxxxxx',
|
@@ -711,7 +767,6 @@ Using a UK-based account:
|
|
711
767
|
|
712
768
|
```ruby
|
713
769
|
CarrierWave.configure do |config|
|
714
|
-
config.fog_provider = "fog/rackspace/storage" # optional, defaults to "fog"
|
715
770
|
config.fog_credentials = {
|
716
771
|
provider: 'Rackspace',
|
717
772
|
rackspace_username: 'xxxxxx',
|
@@ -760,7 +815,6 @@ Please read the [fog-google README](https://github.com/fog/fog-google/blob/maste
|
|
760
815
|
|
761
816
|
```ruby
|
762
817
|
CarrierWave.configure do |config|
|
763
|
-
config.fog_provider = 'fog/google' # required
|
764
818
|
config.fog_credentials = {
|
765
819
|
provider: 'Google',
|
766
820
|
google_storage_access_key_id: 'xxxxxx',
|
@@ -857,8 +911,8 @@ manipulation methods.
|
|
857
911
|
|
858
912
|
## Using MiniMagick
|
859
913
|
|
860
|
-
MiniMagick is similar to RMagick but performs all the operations using the '
|
861
|
-
|
914
|
+
MiniMagick is similar to RMagick but performs all the operations using the 'convert'
|
915
|
+
CLI which is part of the standard ImageMagick kit. This allows you to have the power
|
862
916
|
of ImageMagick without having to worry about installing all the RMagick libraries.
|
863
917
|
|
864
918
|
See the MiniMagick site for more details:
|
@@ -912,7 +966,7 @@ errors:
|
|
912
966
|
carrierwave_download_error: could not be downloaded
|
913
967
|
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
|
914
968
|
extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
915
|
-
content_type_whitelist_error: "You are not allowed to upload %{content_type} files"
|
969
|
+
content_type_whitelist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
916
970
|
content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
|
917
971
|
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
|
918
972
|
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'ssrf_filter'
|
3
|
+
require 'addressable'
|
4
|
+
require 'carrierwave/downloader/remote_file'
|
5
|
+
|
6
|
+
module CarrierWave
|
7
|
+
module Downloader
|
8
|
+
class Base
|
9
|
+
attr_reader :uploader
|
10
|
+
|
11
|
+
def initialize(uploader)
|
12
|
+
@uploader = uploader
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Downloads a file from given URL and returns a RemoteFile.
|
17
|
+
#
|
18
|
+
# === Parameters
|
19
|
+
#
|
20
|
+
# [url (String)] The URL where the remote file is stored
|
21
|
+
# [remote_headers (Hash)] Request headers
|
22
|
+
#
|
23
|
+
def download(url, remote_headers = {})
|
24
|
+
headers = remote_headers.
|
25
|
+
reverse_merge('User-Agent' => "CarrierWave/#{CarrierWave::VERSION}")
|
26
|
+
uri = process_uri(url.to_s)
|
27
|
+
begin
|
28
|
+
if skip_ssrf_protection?(uri)
|
29
|
+
response = OpenURI.open_uri(process_uri(url.to_s), headers)
|
30
|
+
else
|
31
|
+
request = nil
|
32
|
+
response = SsrfFilter.get(uri, headers: headers) do |req|
|
33
|
+
request = req
|
34
|
+
end
|
35
|
+
response.uri = request.uri
|
36
|
+
response.value
|
37
|
+
end
|
38
|
+
rescue StandardError => e
|
39
|
+
raise CarrierWave::DownloadError, "could not download file: #{e.message}"
|
40
|
+
end
|
41
|
+
CarrierWave::Downloader::RemoteFile.new(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Processes the given URL by parsing and escaping it. Public to allow overriding.
|
46
|
+
#
|
47
|
+
# === Parameters
|
48
|
+
#
|
49
|
+
# [url (String)] The URL where the remote file is stored
|
50
|
+
#
|
51
|
+
def process_uri(uri)
|
52
|
+
uri_parts = uri.split('?')
|
53
|
+
encoded_uri = Addressable::URI.parse(uri_parts.shift).normalize.to_s
|
54
|
+
encoded_uri << '?' << Addressable::URI.encode(uri_parts.join('?')).gsub('%5B', '[').gsub('%5D', ']') if uri_parts.any?
|
55
|
+
URI.parse(encoded_uri)
|
56
|
+
rescue URI::InvalidURIError, Addressable::URI::InvalidURIError
|
57
|
+
raise CarrierWave::DownloadError, "couldn't parse URL: #{uri}"
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# If this returns true, SSRF protection will be bypassed.
|
62
|
+
# You can override this if you want to allow accessing specific local URIs that are not SSRF exploitable.
|
63
|
+
#
|
64
|
+
# === Parameters
|
65
|
+
#
|
66
|
+
# [uri (URI)] The URI where the remote file is stored
|
67
|
+
#
|
68
|
+
# === Examples
|
69
|
+
#
|
70
|
+
# class CarrierWave::Downloader::CustomDownloader < CarrierWave::Downloader::Base
|
71
|
+
# def skip_ssrf_protection?(uri)
|
72
|
+
# uri.hostname == 'localhost' && uri.port == 80
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# my_uploader.downloader = CarrierWave::Downloader::CustomDownloader
|
77
|
+
#
|
78
|
+
def skip_ssrf_protection?(uri)
|
79
|
+
false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Downloader
|
3
|
+
class RemoteFile
|
4
|
+
attr_reader :file, :uri
|
5
|
+
|
6
|
+
def initialize(file)
|
7
|
+
case file
|
8
|
+
when String
|
9
|
+
@file = StringIO.new(file)
|
10
|
+
when Net::HTTPResponse
|
11
|
+
@file = StringIO.new(file.body)
|
12
|
+
@content_type = file.content_type
|
13
|
+
@headers = file
|
14
|
+
@uri = file.uri
|
15
|
+
else
|
16
|
+
@file = file
|
17
|
+
@content_type = file.content_type
|
18
|
+
@headers = file.meta
|
19
|
+
@uri = file.base_uri
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def content_type
|
24
|
+
@content_type || 'application/octet-stream'
|
25
|
+
end
|
26
|
+
|
27
|
+
def headers
|
28
|
+
@headers || {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def original_filename
|
32
|
+
filename = filename_from_header || filename_from_uri
|
33
|
+
mime_type = MiniMime.lookup_by_content_type(content_type)
|
34
|
+
unless File.extname(filename).present? || mime_type.blank?
|
35
|
+
filename = "#{filename}.#{mime_type.extension}"
|
36
|
+
end
|
37
|
+
filename
|
38
|
+
end
|
39
|
+
|
40
|
+
def respond_to?(*args)
|
41
|
+
super || file.respond_to?(*args)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def filename_from_header
|
47
|
+
return nil unless headers['content-disposition']
|
48
|
+
|
49
|
+
match = headers['content-disposition'].match(/filename=(?:"([^"]+)"|([^";]+))/)
|
50
|
+
return nil unless match
|
51
|
+
|
52
|
+
match[1].presence || match[2].presence
|
53
|
+
end
|
54
|
+
|
55
|
+
def filename_from_uri
|
56
|
+
CGI.unescape(File.basename(uri.path))
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(*args, &block)
|
60
|
+
file.send(*args, &block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -6,7 +6,7 @@ en:
|
|
6
6
|
carrierwave_download_error: could not be downloaded
|
7
7
|
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
|
8
8
|
extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
9
|
-
content_type_whitelist_error: "You are not allowed to upload %{content_type} files"
|
9
|
+
content_type_whitelist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
10
10
|
content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
|
11
11
|
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
|
12
12
|
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
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
|