carrierwave 2.2.6 → 3.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +137 -67
- data/lib/carrierwave/compatibility/paperclip.rb +4 -2
- data/lib/carrierwave/downloader/base.rb +19 -11
- data/lib/carrierwave/downloader/remote_file.rb +13 -10
- data/lib/carrierwave/locale/en.yml +5 -3
- data/lib/carrierwave/mount.rb +36 -50
- data/lib/carrierwave/mounter.rb +117 -50
- data/lib/carrierwave/orm/activerecord.rb +21 -62
- data/lib/carrierwave/processing/mini_magick.rb +15 -13
- data/lib/carrierwave/processing/rmagick.rb +11 -15
- data/lib/carrierwave/processing/vips.rb +12 -12
- data/lib/carrierwave/sanitized_file.rb +49 -77
- data/lib/carrierwave/storage/abstract.rb +5 -5
- data/lib/carrierwave/storage/file.rb +6 -5
- data/lib/carrierwave/storage/fog.rb +74 -66
- data/lib/carrierwave/test/matchers.rb +11 -7
- data/lib/carrierwave/uploader/cache.rb +18 -10
- data/lib/carrierwave/uploader/callbacks.rb +1 -1
- data/lib/carrierwave/uploader/configuration.rb +10 -4
- data/lib/carrierwave/uploader/{content_type_whitelist.rb → content_type_allowlist.rb} +17 -15
- data/lib/carrierwave/uploader/{content_type_blacklist.rb → content_type_denylist.rb} +19 -14
- data/lib/carrierwave/uploader/dimension.rb +66 -0
- data/lib/carrierwave/uploader/{extension_whitelist.rb → extension_allowlist.rb} +17 -15
- data/lib/carrierwave/uploader/{extension_blacklist.rb → extension_denylist.rb} +18 -13
- data/lib/carrierwave/uploader/file_size.rb +2 -2
- data/lib/carrierwave/uploader/processing.rb +31 -6
- data/lib/carrierwave/uploader/proxy.rb +16 -3
- data/lib/carrierwave/uploader/store.rb +44 -6
- data/lib/carrierwave/uploader/url.rb +1 -1
- data/lib/carrierwave/uploader/versions.rb +154 -136
- data/lib/carrierwave/uploader.rb +10 -8
- data/lib/carrierwave/utilities/file_name.rb +47 -0
- data/lib/carrierwave/utilities/uri.rb +14 -11
- data/lib/carrierwave/utilities.rb +1 -0
- data/lib/carrierwave/validations/active_model.rb +4 -6
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +9 -17
- data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +1 -1
- data/lib/generators/uploader_generator.rb +3 -3
- metadata +32 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0521a369826478de3de2fa97eecc3c3b4cde957eae650f01e9a84064c7a942f
|
4
|
+
data.tar.gz: e9691718fd62655b3990754a334fe7f7637c6e4e9186fb5084aa0da227058bf1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee8a2cbafe89e7f29b898940a2e9fbc391a015ea0a91fc04d00da62ea2ecd8b83721c4f0dc873551255117a59c9b61ac8b57902dc1fbec54f29817acff3f8746
|
7
|
+
data.tar.gz: 4bcd521bc40e84509b779312f5a6eab363bca8e9871c179fb6340044e46cf44397a58b4ba3133caaed71845b3a9630f74cd6da8356f835c2cc7ce17fa4e9be0c
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ It works well with Rack based web applications, such as Ruby on Rails.
|
|
10
10
|
|
11
11
|
## Information
|
12
12
|
|
13
|
-
* RDoc documentation [available on RubyDoc.info](
|
13
|
+
* RDoc documentation [available on RubyDoc.info](https://rubydoc.info/gems/carrierwave)
|
14
14
|
* Source code [available on GitHub](http://github.com/carrierwaveuploader/carrierwave)
|
15
15
|
* More information, known limitations, and how-tos [available on the wiki](https://github.com/carrierwaveuploader/carrierwave/wiki)
|
16
16
|
|
@@ -30,13 +30,19 @@ $ gem install carrierwave
|
|
30
30
|
In Rails, add it to your Gemfile:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
gem 'carrierwave', '~>
|
33
|
+
gem 'carrierwave', '~> 3.0'
|
34
34
|
```
|
35
35
|
|
36
36
|
Finally, restart the server to apply the changes.
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
## Upgrading from 2.x or earlier
|
39
|
+
|
40
|
+
CarrierWave 3.0 comes with a change in the way of handling the file extension on conversion. This results in following issues if you use `process convert: :format` to change the file format:
|
41
|
+
|
42
|
+
- If you have it on the uploader itself (not within a version), the file extension of the cached file will change. That means if you serve both CarrierWave 2.x and 3.x simultaneously on the same workload (e.g. using blue-green deployment), a cache file stored by 2.x can't be retrieved by 3.x and vice versa.
|
43
|
+
- If you have it within a version, the file extension of the stored file will change. You need to perform `#recreate_versions!` to make it usable again.
|
44
|
+
|
45
|
+
To preserve the 2.x behavior, you can set `force_extension false` right after calling `process convert: :format`. See [#2659](https://github.com/carrierwaveuploader/carrierwave/pull/2659) for the detail.
|
40
46
|
|
41
47
|
## Getting Started
|
42
48
|
|
@@ -227,6 +233,20 @@ class MyUploader < CarrierWave::Uploader::Base
|
|
227
233
|
end
|
228
234
|
```
|
229
235
|
|
236
|
+
## Changing the filename
|
237
|
+
|
238
|
+
To change the filename of uploaded files, you can override `#filename` method in the uploader.
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
class MyUploader < CarrierWave::Uploader::Base
|
242
|
+
def filename
|
243
|
+
"image.#{file.extension}" # If you upload 'file.jpg', you'll get 'image.jpg'
|
244
|
+
end
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
248
|
+
Some old documentations (like [this](https://stackoverflow.com/a/5865117)) may instruct you to safeguard the filename value with `if original_filename`, but it's no longer necessary with CarrierWave 3.0 or later.
|
249
|
+
|
230
250
|
## Securing uploads
|
231
251
|
|
232
252
|
Certain files might be dangerous if uploaded to the wrong location, such as PHP
|
@@ -305,17 +325,8 @@ You no longer need to do this manually.
|
|
305
325
|
|
306
326
|
## Adding versions
|
307
327
|
|
308
|
-
Often you'll want to add different versions of the same file. The classic example is image thumbnails
|
309
|
-
|
310
|
-
*Note:* You must have Imagemagick installed to do image resizing.
|
311
|
-
|
312
|
-
Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
|
313
|
-
|
314
|
-
To install Imagemagick on OSX with homebrew type the following:
|
315
|
-
|
316
|
-
```
|
317
|
-
$ brew install imagemagick
|
318
|
-
```
|
328
|
+
Often you'll want to add different versions of the same file. The classic example is generating image thumbnails while preserving the original file to be used for high-quality representation.
|
329
|
+
In this section we'll explore how CarrierWave supports working with multiple versions. The image manipulation itself is covered in [another section](#manipulating-images).
|
319
330
|
|
320
331
|
```ruby
|
321
332
|
class MyUploader < CarrierWave::Uploader::Base
|
@@ -351,17 +362,7 @@ uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
|
|
351
362
|
One important thing to remember is that process is called *before* versions are
|
352
363
|
created. This can cut down on processing cost.
|
353
364
|
|
354
|
-
###
|
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
|
-
### conditional process
|
365
|
+
### Conditional processing
|
365
366
|
|
366
367
|
If you want to use conditional process, you can only use `if` statement.
|
367
368
|
|
@@ -445,8 +446,27 @@ class MyUploader < CarrierWave::Uploader::Base
|
|
445
446
|
end
|
446
447
|
```
|
447
448
|
|
448
|
-
|
449
|
-
|
449
|
+
### Customizing version filenames
|
450
|
+
|
451
|
+
CarrierWave supports [customization of filename](#changing-the-filename) by overriding an uploader's
|
452
|
+
#filename method, but this doesn't work for versions because of the limitation on how CarrierWave
|
453
|
+
re-constructs the filename on retrieval of the stored file.
|
454
|
+
Instead, you can override `#full_filename` with providing a version-aware name.
|
455
|
+
|
456
|
+
```ruby
|
457
|
+
class MyUploader < CarrierWave::Uploader::Base
|
458
|
+
version :thumb do
|
459
|
+
def full_filename(for_file)
|
460
|
+
'thumb.png'
|
461
|
+
end
|
462
|
+
process convert: 'png'
|
463
|
+
end
|
464
|
+
end
|
465
|
+
```
|
466
|
+
|
467
|
+
Please note that `#full_filename` mustn't be constructed based on a dynamic value
|
468
|
+
that can change from the time of store and time of retrieval, since it will result in
|
469
|
+
being unable to retrieve a file previously stored.
|
450
470
|
|
451
471
|
## Making uploads work across form redisplays
|
452
472
|
|
@@ -531,6 +551,17 @@ failures automatically with attribute validation errors. If you aren't, or you
|
|
531
551
|
disable CarrierWave's `validate_download` option, you'll need to handle those
|
532
552
|
errors yourself.
|
533
553
|
|
554
|
+
### Retry option for download from remote location
|
555
|
+
If you want to retry the download from the Remote URL, enable the download_retry_count option, an error occurs during download, it will try to execute the specified number of times.
|
556
|
+
This option is effective when the remote destination is unstable.
|
557
|
+
|
558
|
+
```rb
|
559
|
+
CarrierWave.configure do |config|
|
560
|
+
config.download_retry_count = 3 # Default 0
|
561
|
+
config.download_retry_wait_time = 3 # Default 5
|
562
|
+
end
|
563
|
+
```
|
564
|
+
|
534
565
|
## Providing a default URL
|
535
566
|
|
536
567
|
In many cases, especially when working with images, it might be a good idea to
|
@@ -832,7 +863,6 @@ Please read the [fog-google README](https://github.com/fog/fog-google/blob/maste
|
|
832
863
|
For Google Storage JSON API (recommended):
|
833
864
|
```ruby
|
834
865
|
CarrierWave.configure do |config|
|
835
|
-
config.fog_provider = 'fog/google'
|
836
866
|
config.fog_credentials = {
|
837
867
|
provider: 'Google',
|
838
868
|
google_project: 'my-project',
|
@@ -846,7 +876,6 @@ end
|
|
846
876
|
For Google Storage XML API:
|
847
877
|
```ruby
|
848
878
|
CarrierWave.configure do |config|
|
849
|
-
config.fog_provider = 'fog/google'
|
850
879
|
config.fog_credentials = {
|
851
880
|
provider: 'Google',
|
852
881
|
google_storage_access_key_id: 'xxxxxx',
|
@@ -905,67 +934,81 @@ CarrierWave.configure do |config|
|
|
905
934
|
end
|
906
935
|
```
|
907
936
|
|
908
|
-
##
|
937
|
+
## Manipulating images
|
909
938
|
|
910
939
|
If you're uploading images, you'll probably want to manipulate them in some way,
|
911
|
-
you might want to create thumbnail images for example.
|
912
|
-
small library to make manipulating images with RMagick easier, you'll need to
|
913
|
-
include it in your Uploader:
|
940
|
+
you might want to create thumbnail images for example.
|
914
941
|
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
942
|
+
### Using MiniMagick
|
943
|
+
|
944
|
+
MiniMagick performs all the operations using the 'convert' CLI which is part of the standard ImageMagick kit.
|
945
|
+
This allows you to have the power of ImageMagick without having to worry about installing
|
946
|
+
all the RMagick libraries, it often results in higher memory footprint.
|
947
|
+
|
948
|
+
See the MiniMagick site for more details:
|
949
|
+
|
950
|
+
https://github.com/minimagick/minimagick
|
951
|
+
|
952
|
+
To install Imagemagick on OSX with homebrew type the following:
|
953
|
+
|
954
|
+
```
|
955
|
+
$ brew install imagemagick
|
919
956
|
```
|
920
957
|
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
958
|
+
And the ImageMagick command line options for more for what's on offer:
|
959
|
+
|
960
|
+
http://www.imagemagick.org/script/command-line-options.php
|
961
|
+
|
962
|
+
Currently, the MiniMagick carrierwave processor provides exactly the same methods as
|
963
|
+
for the RMagick processor.
|
927
964
|
|
928
965
|
```ruby
|
929
966
|
class AvatarUploader < CarrierWave::Uploader::Base
|
930
|
-
include CarrierWave::
|
967
|
+
include CarrierWave::MiniMagick
|
931
968
|
|
932
969
|
process resize_to_fill: [200, 200]
|
933
|
-
process convert: 'png'
|
934
|
-
|
935
|
-
def filename
|
936
|
-
super.chomp(File.extname(super)) + '.png' if original_filename.present?
|
937
|
-
end
|
938
970
|
end
|
939
971
|
```
|
940
972
|
|
941
|
-
|
942
|
-
manipulation methods.
|
973
|
+
#### List of available processing methods:
|
943
974
|
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
975
|
+
- `convert` - Changes the image encoding format to the given format(eg. jpg). This operation is treated specially to trigger the change of the file extension, so it matches with the format of the resulting file.
|
976
|
+
- `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.
|
977
|
+
- `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.
|
978
|
+
- `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".
|
979
|
+
- `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.
|
949
980
|
|
950
|
-
See
|
981
|
+
See `carrierwave/processing/mini_magick.rb` for details.
|
951
982
|
|
952
|
-
|
983
|
+
### Using RMagick
|
953
984
|
|
954
|
-
|
985
|
+
CarrierWave also comes with support for RMagick, a well-known image processing library.
|
986
|
+
To use it, you'll need to include this in your Uploader:
|
955
987
|
|
956
|
-
|
988
|
+
```ruby
|
989
|
+
class AvatarUploader < CarrierWave::Uploader::Base
|
990
|
+
include CarrierWave::RMagick
|
991
|
+
end
|
992
|
+
```
|
957
993
|
|
958
|
-
|
959
|
-
|
994
|
+
The RMagick module gives you a few methods, like
|
995
|
+
`CarrierWave::RMagick#resize_to_fill` which manipulate the image file in some
|
996
|
+
way. You can set a `process` callback, which will call that method any time a
|
997
|
+
file is uploaded.
|
998
|
+
There is a demonstration of convert here.
|
960
999
|
|
961
1000
|
```ruby
|
962
1001
|
class AvatarUploader < CarrierWave::Uploader::Base
|
963
|
-
include CarrierWave::
|
1002
|
+
include CarrierWave::RMagick
|
964
1003
|
|
965
1004
|
process resize_to_fill: [200, 200]
|
1005
|
+
process convert: 'png'
|
966
1006
|
end
|
967
1007
|
```
|
968
1008
|
|
1009
|
+
Check out the manipulate! method, which makes it easy for you to write your own
|
1010
|
+
manipulation methods.
|
1011
|
+
|
969
1012
|
## Migrating from Paperclip
|
970
1013
|
|
971
1014
|
If you are using Paperclip, you can use the provided compatibility module:
|
@@ -1000,10 +1043,13 @@ errors:
|
|
1000
1043
|
extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
1001
1044
|
content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
1002
1045
|
content_type_denylist_error: "You are not allowed to upload %{content_type} files"
|
1003
|
-
|
1004
|
-
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
1046
|
+
processing_error: "Failed to manipulate, maybe it is not an image?"
|
1005
1047
|
min_size_error: "File size should be greater than %{min_size}"
|
1006
1048
|
max_size_error: "File size should be less than %{max_size}"
|
1049
|
+
min_width_error: "Image width should be greater than %{min_width}px"
|
1050
|
+
max_width_error: "Image width should be less than %{max_width}px"
|
1051
|
+
min_height_error: "Image height should be greater than %{min_height}px"
|
1052
|
+
max_height_error: "Image height should be less than %{max_height}px"
|
1007
1053
|
```
|
1008
1054
|
|
1009
1055
|
The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
|
@@ -1066,6 +1112,30 @@ class User
|
|
1066
1112
|
end
|
1067
1113
|
```
|
1068
1114
|
|
1115
|
+
## Uploader Callbacks
|
1116
|
+
|
1117
|
+
In addition to the ActiveRecord callbacks described above, uploaders also have callbacks.
|
1118
|
+
|
1119
|
+
```ruby
|
1120
|
+
class MyUploader < ::CarrierWave::Uploader::Base
|
1121
|
+
before :remove, :log_removal
|
1122
|
+
private
|
1123
|
+
def log_removal
|
1124
|
+
::Rails.logger.info(format('Deleting file on S3: %s', @file))
|
1125
|
+
end
|
1126
|
+
end
|
1127
|
+
```
|
1128
|
+
|
1129
|
+
Uploader callbacks can be `before` or `after` the following events:
|
1130
|
+
|
1131
|
+
```
|
1132
|
+
cache
|
1133
|
+
process
|
1134
|
+
remove
|
1135
|
+
retrieve_from_cache
|
1136
|
+
store
|
1137
|
+
```
|
1138
|
+
|
1069
1139
|
## Contributing to CarrierWave
|
1070
1140
|
|
1071
1141
|
See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
|
@@ -1074,7 +1144,7 @@ See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/ma
|
|
1074
1144
|
|
1075
1145
|
The MIT License (MIT)
|
1076
1146
|
|
1077
|
-
Copyright (c) 2008
|
1147
|
+
Copyright (c) 2008 Jonas Nicklas
|
1078
1148
|
|
1079
1149
|
Permission is hereby granted, free of charge, to any person obtaining
|
1080
1150
|
a copy of this software and associated documentation files (the
|
@@ -56,10 +56,11 @@ module CarrierWave
|
|
56
56
|
:basename => lambda{|u, f| u.filename.gsub(/#{File.extname(u.filename)}$/, "") },
|
57
57
|
:extension => lambda{|u, d| File.extname(u.filename).gsub(/^\.+/, "")},
|
58
58
|
:class => lambda{|u, f| u.model.class.name.underscore.pluralize}
|
59
|
-
}
|
59
|
+
}.freeze
|
60
60
|
|
61
61
|
included do
|
62
62
|
attr_accessor :filename
|
63
|
+
|
63
64
|
class_attribute :mappings
|
64
65
|
self.mappings ||= DEFAULT_MAPPINGS.dup
|
65
66
|
end
|
@@ -92,7 +93,8 @@ module CarrierWave
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
|
96
|
+
private
|
97
|
+
|
96
98
|
def interpolate_paperclip_path(path)
|
97
99
|
mappings.each_pair.inject(path) do |agg, pair|
|
98
100
|
agg.gsub(":#{pair[0]}") { pair[1].call(self, self.paperclip_style).to_s }
|
@@ -6,6 +6,8 @@ require 'carrierwave/downloader/remote_file'
|
|
6
6
|
module CarrierWave
|
7
7
|
module Downloader
|
8
8
|
class Base
|
9
|
+
include CarrierWave::Utilities::Uri
|
10
|
+
|
9
11
|
attr_reader :uploader
|
10
12
|
|
11
13
|
def initialize(uploader)
|
@@ -21,6 +23,7 @@ module CarrierWave
|
|
21
23
|
# [remote_headers (Hash)] Request headers
|
22
24
|
#
|
23
25
|
def download(url, remote_headers = {})
|
26
|
+
@current_download_retry_count = 0
|
24
27
|
headers = remote_headers.
|
25
28
|
reverse_merge('User-Agent' => "CarrierWave/#{CarrierWave::VERSION}")
|
26
29
|
uri = process_uri(url.to_s)
|
@@ -42,7 +45,13 @@ module CarrierWave
|
|
42
45
|
response.value
|
43
46
|
end
|
44
47
|
rescue StandardError => e
|
45
|
-
|
48
|
+
if @current_download_retry_count < @uploader.download_retry_count
|
49
|
+
@current_download_retry_count += 1
|
50
|
+
sleep @uploader.download_retry_wait_time
|
51
|
+
retry
|
52
|
+
else
|
53
|
+
raise CarrierWave::DownloadError, "could not download file: #{e.message}"
|
54
|
+
end
|
46
55
|
end
|
47
56
|
CarrierWave::Downloader::RemoteFile.new(response)
|
48
57
|
end
|
@@ -54,17 +63,16 @@ module CarrierWave
|
|
54
63
|
#
|
55
64
|
# [url (String)] The URL where the remote file is stored
|
56
65
|
#
|
57
|
-
def process_uri(
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
+
def process_uri(source)
|
67
|
+
uri = Addressable::URI.parse(source)
|
68
|
+
uri.host = uri.normalized_host
|
69
|
+
# Perform decode first, as the path is likely to be already encoded
|
70
|
+
uri.path = encode_path(decode_uri(uri.path)) if uri.path =~ CarrierWave::Utilities::Uri::PATH_UNSAFE
|
71
|
+
uri.query = encode_non_ascii(uri.query) if uri.query
|
72
|
+
uri.fragment = encode_non_ascii(uri.fragment) if uri.fragment
|
73
|
+
URI.parse(uri.to_s)
|
66
74
|
rescue URI::InvalidURIError, Addressable::URI::InvalidURIError
|
67
|
-
raise CarrierWave::DownloadError, "couldn't parse URL: #{
|
75
|
+
raise CarrierWave::DownloadError, "couldn't parse URL: #{source}"
|
68
76
|
end
|
69
77
|
|
70
78
|
##
|
@@ -8,7 +8,10 @@ module CarrierWave
|
|
8
8
|
when String
|
9
9
|
@file = StringIO.new(file)
|
10
10
|
when Net::HTTPResponse
|
11
|
-
|
11
|
+
body = file.body
|
12
|
+
raise CarrierWave::DownloadError, 'could not download file: No Content' if body.nil?
|
13
|
+
|
14
|
+
@file = StringIO.new(body)
|
12
15
|
@content_type = file.content_type
|
13
16
|
@headers = file
|
14
17
|
@uri = file.uri
|
@@ -30,18 +33,15 @@ module CarrierWave
|
|
30
33
|
|
31
34
|
def original_filename
|
32
35
|
filename = filename_from_header || filename_from_uri
|
33
|
-
|
34
|
-
unless File.extname(filename).present? ||
|
35
|
-
|
36
|
+
extensions = Marcel::Magic.new(content_type).extensions
|
37
|
+
unless File.extname(filename).present? || extensions.blank?
|
38
|
+
extension = extensions.first
|
39
|
+
filename = "#{filename}.#{extension}"
|
36
40
|
end
|
37
41
|
filename
|
38
42
|
end
|
39
43
|
|
40
|
-
|
41
|
-
super || file.respond_to?(*args)
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
44
|
+
private
|
45
45
|
|
46
46
|
def filename_from_header
|
47
47
|
return nil unless headers['content-disposition']
|
@@ -59,7 +59,10 @@ module CarrierWave
|
|
59
59
|
def method_missing(*args, &block)
|
60
60
|
file.send(*args, &block)
|
61
61
|
end
|
62
|
+
|
63
|
+
def respond_to_missing?(*args)
|
64
|
+
super || file.respond_to?(*args)
|
65
|
+
end
|
62
66
|
end
|
63
67
|
end
|
64
68
|
end
|
65
|
-
|
@@ -8,8 +8,10 @@ en:
|
|
8
8
|
extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
9
9
|
content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
10
10
|
content_type_denylist_error: "You are not allowed to upload %{content_type} files"
|
11
|
-
|
12
|
-
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
13
|
-
vips_processing_error: "Failed to manipulate with vips, maybe it is not an image? Original Error: %{e}"
|
11
|
+
processing_error: "Failed to manipulate, maybe it is not an image?"
|
14
12
|
min_size_error: "File size should be greater than %{min_size}"
|
15
13
|
max_size_error: "File size should be less than %{max_size}"
|
14
|
+
min_width_error: "Image width should be greater than %{min_width}px"
|
15
|
+
max_width_error: "Image width should be less than %{max_width}px"
|
16
|
+
min_height_error: "Image height should be greater than %{min_height}px"
|
17
|
+
max_height_error: "Image height should be less than %{max_height}px"
|
data/lib/carrierwave/mount.rb
CHANGED
@@ -132,7 +132,7 @@ module CarrierWave
|
|
132
132
|
# end
|
133
133
|
#
|
134
134
|
def mount_uploader(column, uploader=nil, options={}, &block)
|
135
|
-
mount_base(column, uploader, options, &block)
|
135
|
+
mount_base(column, uploader, options.merge(multiple: false), &block)
|
136
136
|
|
137
137
|
mod = Module.new
|
138
138
|
include mod
|
@@ -163,21 +163,13 @@ module CarrierWave
|
|
163
163
|
end
|
164
164
|
|
165
165
|
def remote_#{column}_url=(url)
|
166
|
-
_mounter(:#{column}).remote_urls =
|
166
|
+
_mounter(:#{column}).remote_urls = url
|
167
167
|
end
|
168
168
|
|
169
169
|
def remote_#{column}_request_header=(header)
|
170
170
|
_mounter(:#{column}).remote_request_headers = [header]
|
171
171
|
end
|
172
172
|
|
173
|
-
def write_#{column}_identifier
|
174
|
-
return if frozen?
|
175
|
-
mounter = _mounter(:#{column})
|
176
|
-
|
177
|
-
mounter.clear! if mounter.remove?
|
178
|
-
write_uploader(mounter.serialization_column, mounter.identifiers.first)
|
179
|
-
end
|
180
|
-
|
181
173
|
def #{column}_identifier
|
182
174
|
_mounter(:#{column}).read_identifiers[0]
|
183
175
|
end
|
@@ -193,16 +185,6 @@ module CarrierWave
|
|
193
185
|
def #{column}_download_error
|
194
186
|
#{column}_download_errors.last
|
195
187
|
end
|
196
|
-
|
197
|
-
def store_previous_changes_for_#{column}
|
198
|
-
attribute_changes = ::ActiveRecord.version.to_s.to_f >= 5.1 ? saved_changes : changes
|
199
|
-
@_previous_changes_for_#{column} = attribute_changes[_mounter(:#{column}).serialization_column]
|
200
|
-
end
|
201
|
-
|
202
|
-
def remove_previously_stored_#{column}
|
203
|
-
before, after = @_previous_changes_for_#{column}
|
204
|
-
_mounter(:#{column}).remove_previous([before], [after])
|
205
|
-
end
|
206
188
|
RUBY
|
207
189
|
end
|
208
190
|
|
@@ -295,7 +277,7 @@ module CarrierWave
|
|
295
277
|
# end
|
296
278
|
#
|
297
279
|
def mount_uploaders(column, uploader=nil, options={}, &block)
|
298
|
-
mount_base(column, uploader, options, &block)
|
280
|
+
mount_base(column, uploader, options.merge(multiple: true), &block)
|
299
281
|
|
300
282
|
mod = Module.new
|
301
283
|
include mod
|
@@ -334,35 +316,18 @@ module CarrierWave
|
|
334
316
|
_mounter(:#{column}).remote_request_headers = headers
|
335
317
|
end
|
336
318
|
|
337
|
-
def write_#{column}_identifier
|
338
|
-
return if frozen?
|
339
|
-
mounter = _mounter(:#{column})
|
340
|
-
|
341
|
-
mounter.clear! if mounter.remove?
|
342
|
-
write_uploader(mounter.serialization_column, mounter.identifiers.presence)
|
343
|
-
end
|
344
|
-
|
345
319
|
def #{column}_identifiers
|
346
320
|
_mounter(:#{column}).read_identifiers
|
347
321
|
end
|
348
|
-
|
349
|
-
def store_previous_changes_for_#{column}
|
350
|
-
attribute_changes = ::ActiveRecord.version.to_s.to_f >= 5.1 ? saved_changes : changes
|
351
|
-
@_previous_changes_for_#{column} = attribute_changes[_mounter(:#{column}).serialization_column]
|
352
|
-
end
|
353
|
-
|
354
|
-
def remove_previously_stored_#{column}
|
355
|
-
_mounter(:#{column}).remove_previous(*@_previous_changes_for_#{column})
|
356
|
-
end
|
357
322
|
RUBY
|
358
323
|
end
|
359
324
|
|
360
|
-
|
325
|
+
private
|
361
326
|
|
362
327
|
def mount_base(column, uploader=nil, options={}, &block)
|
363
328
|
include CarrierWave::Mount::Extension
|
364
329
|
|
365
|
-
uploader = build_uploader(uploader, &block)
|
330
|
+
uploader = build_uploader(uploader, column, &block)
|
366
331
|
uploaders[column.to_sym] = uploader
|
367
332
|
uploader_options[column.to_sym] = options
|
368
333
|
|
@@ -387,6 +352,8 @@ module CarrierWave
|
|
387
352
|
|
388
353
|
def remove_#{column}!
|
389
354
|
_mounter(:#{column}).remove!
|
355
|
+
self.remove_#{column} = true
|
356
|
+
write_#{column}_identifier
|
390
357
|
end
|
391
358
|
|
392
359
|
def remove_#{column}=(value)
|
@@ -413,22 +380,36 @@ module CarrierWave
|
|
413
380
|
_mounter(:#{column}).download_errors
|
414
381
|
end
|
415
382
|
|
383
|
+
def write_#{column}_identifier
|
384
|
+
_mounter(:#{column}).write_identifier
|
385
|
+
end
|
386
|
+
|
416
387
|
def mark_remove_#{column}_false
|
417
388
|
_mounter(:#{column}).remove = false
|
418
389
|
end
|
390
|
+
|
391
|
+
def reset_previous_changes_for_#{column}
|
392
|
+
_mounter(:#{column}).reset_changes!
|
393
|
+
end
|
394
|
+
|
395
|
+
def remove_previously_stored_#{column}
|
396
|
+
_mounter(:#{column}).remove_previous
|
397
|
+
end
|
398
|
+
|
399
|
+
def remove_rolled_back_#{column}
|
400
|
+
_mounter(:#{column}).remove_added
|
401
|
+
end
|
419
402
|
RUBY
|
420
403
|
end
|
421
404
|
|
422
|
-
def build_uploader(uploader, &block)
|
423
|
-
|
405
|
+
def build_uploader(uploader, column, &block)
|
406
|
+
uploader ||= CarrierWave::Uploader::Base
|
407
|
+
return uploader unless block_given?
|
424
408
|
|
425
|
-
uploader = Class.new(uploader
|
426
|
-
const_set("
|
409
|
+
uploader = Class.new(uploader)
|
410
|
+
const_set("CarrierWave#{column.to_s.camelize}Uploader", uploader)
|
427
411
|
|
428
|
-
|
429
|
-
uploader.class_eval(&block)
|
430
|
-
uploader.recursively_apply_block_to_versions(&block)
|
431
|
-
end
|
412
|
+
uploader.class_eval(&block)
|
432
413
|
|
433
414
|
uploader
|
434
415
|
end
|
@@ -447,11 +428,16 @@ module CarrierWave
|
|
447
428
|
|
448
429
|
private
|
449
430
|
|
431
|
+
def initialize_dup(other)
|
432
|
+
@_mounters = @_mounters.dup
|
433
|
+
super
|
434
|
+
end
|
435
|
+
|
450
436
|
def _mounter(column)
|
451
437
|
# We cannot memoize in frozen objects :(
|
452
|
-
return Mounter.
|
438
|
+
return Mounter.build(self, column) if frozen?
|
453
439
|
@_mounters ||= {}
|
454
|
-
@_mounters[column] ||= Mounter.
|
440
|
+
@_mounters[column] ||= Mounter.build(self, column)
|
455
441
|
end
|
456
442
|
|
457
443
|
end # Extension
|