carrierwave 1.3.4 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +278 -86
  3. data/lib/carrierwave/compatibility/paperclip.rb +4 -2
  4. data/lib/carrierwave/downloader/base.rb +101 -0
  5. data/lib/carrierwave/downloader/remote_file.rb +68 -0
  6. data/lib/carrierwave/locale/en.yml +9 -6
  7. data/lib/carrierwave/mount.rb +53 -61
  8. data/lib/carrierwave/mounter.rb +169 -77
  9. data/lib/carrierwave/orm/activerecord.rb +23 -58
  10. data/lib/carrierwave/processing/mini_magick.rb +137 -123
  11. data/lib/carrierwave/processing/rmagick.rb +47 -20
  12. data/lib/carrierwave/processing/vips.rb +315 -0
  13. data/lib/carrierwave/processing.rb +1 -0
  14. data/lib/carrierwave/sanitized_file.rb +91 -70
  15. data/lib/carrierwave/storage/abstract.rb +5 -5
  16. data/lib/carrierwave/storage/file.rb +6 -5
  17. data/lib/carrierwave/storage/fog.rb +114 -62
  18. data/lib/carrierwave/storage.rb +1 -0
  19. data/lib/carrierwave/test/matchers.rb +11 -7
  20. data/lib/carrierwave/uploader/cache.rb +40 -24
  21. data/lib/carrierwave/uploader/callbacks.rb +1 -1
  22. data/lib/carrierwave/uploader/configuration.rb +43 -20
  23. data/lib/carrierwave/uploader/content_type_allowlist.rb +62 -0
  24. data/lib/carrierwave/uploader/content_type_denylist.rb +65 -0
  25. data/lib/carrierwave/uploader/dimension.rb +66 -0
  26. data/lib/carrierwave/uploader/download.rb +2 -123
  27. data/lib/carrierwave/uploader/extension_allowlist.rb +63 -0
  28. data/lib/carrierwave/uploader/extension_denylist.rb +64 -0
  29. data/lib/carrierwave/uploader/file_size.rb +2 -2
  30. data/lib/carrierwave/uploader/mountable.rb +6 -0
  31. data/lib/carrierwave/uploader/processing.rb +45 -7
  32. data/lib/carrierwave/uploader/proxy.rb +17 -4
  33. data/lib/carrierwave/uploader/serialization.rb +1 -1
  34. data/lib/carrierwave/uploader/store.rb +73 -7
  35. data/lib/carrierwave/uploader/url.rb +7 -4
  36. data/lib/carrierwave/uploader/versions.rb +161 -111
  37. data/lib/carrierwave/uploader.rb +10 -17
  38. data/lib/carrierwave/utilities/file_name.rb +47 -0
  39. data/lib/carrierwave/utilities/uri.rb +14 -11
  40. data/lib/carrierwave/utilities.rb +1 -0
  41. data/lib/carrierwave/validations/active_model.rb +7 -9
  42. data/lib/carrierwave/version.rb +1 -1
  43. data/lib/carrierwave.rb +22 -17
  44. data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +13 -4
  45. data/lib/generators/uploader_generator.rb +3 -3
  46. metadata +115 -44
  47. data/lib/carrierwave/uploader/content_type_blacklist.rb +0 -48
  48. data/lib/carrierwave/uploader/content_type_whitelist.rb +0 -48
  49. data/lib/carrierwave/uploader/extension_blacklist.rb +0 -51
  50. data/lib/carrierwave/uploader/extension_whitelist.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8424c8e8238faa3fd7fda7424149843ad11dc06e7704e55412a905c765ac0a0c
4
- data.tar.gz: ecef054ec6f134badaaffbc406794ad3642e000e8a8623d9e63655e726ea2c7c
3
+ metadata.gz: 3fce89671ca96c66db403199f1eab005bdb208ae699bcd6c6d58d470ec337d96
4
+ data.tar.gz: 0047624b2e05641fbb2d65d97815726e9bc296fc8cdb53c37815ead2ce30d6e4
5
5
  SHA512:
6
- metadata.gz: 5d01517bae4bca3457d5576739c51fa2c9ba0ca54a72060b0c673268ae6dc8199f309891c4bc5212ec64019055a0ea40fe853a208ec74cbaf5cc325c4f8888ab
7
- data.tar.gz: edc2a20b818d2cdbabb71aee399de99a08ed6a95096e6e634c6213403368704b0871b88ff81d0ec6f1b0dd7661c4bec9dc78c524105bf6ecdb6e28e1f30028b7
6
+ metadata.gz: 5f63f1e37da1f107660263cc2d4be4e09dd0076e12bf80bc057449ddbd288887210ae17392d4092ff240c9992be3819721e7665a72023e4b58a8e9d351434d37
7
+ data.tar.gz: 205220c3605f50f23379781d94c587aee68a75aa7d4d854a258d362983122115641482098e81574dd873acce90deeb124d01b24c9ff7970dc45c2cb3146a9bd1
data/README.md CHANGED
@@ -3,14 +3,14 @@
3
3
  This gem provides a simple and extremely flexible way to upload files from Ruby applications.
4
4
  It works well with Rack based web applications, such as Ruby on Rails.
5
5
 
6
- [![Build Status](https://travis-ci.org/carrierwaveuploader/carrierwave.svg?branch=master)](http://travis-ci.org/carrierwaveuploader/carrierwave)
6
+ [![Build Status](https://github.com/carrierwaveuploader/carrierwave/workflows/Test/badge.svg)](https://github.com/carrierwaveuploader/carrierwave/actions)
7
7
  [![Code Climate](https://codeclimate.com/github/carrierwaveuploader/carrierwave.svg)](https://codeclimate.com/github/carrierwaveuploader/carrierwave)
8
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
12
12
 
13
- * RDoc documentation [available on RubyDoc.info](http://rubydoc.info/gems/carrierwave/frames)
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', '~> 1.0'
33
+ gem 'carrierwave', '~> 3.0'
34
34
  ```
35
35
 
36
36
  Finally, restart the server to apply the changes.
37
37
 
38
- As of version 1.0, CarrierWave requires Rails 4.0 or higher and Ruby 2.0
39
- or higher. If you're on Rails 3, you should use v0.11.0.
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
 
@@ -94,7 +100,7 @@ a migration:
94
100
  Open your model file and mount the uploader:
95
101
 
96
102
  ```ruby
97
- class User < ActiveRecord::Base
103
+ class User < ApplicationRecord
98
104
  mount_uploader :avatar, AvatarUploader
99
105
  end
100
106
  ```
@@ -157,7 +163,7 @@ Open your model file and mount the uploader:
157
163
 
158
164
 
159
165
  ```ruby
160
- class User < ActiveRecord::Base
166
+ class User < ApplicationRecord
161
167
  mount_uploaders :avatars, AvatarUploader
162
168
  serialize :avatars, JSON # If you use SQLite, add this line.
163
169
  end
@@ -190,6 +196,17 @@ u.avatars[0].current_path # => 'path/to/file.png'
190
196
  u.avatars[0].identifier # => 'file.png'
191
197
  ```
192
198
 
199
+ If you want to preserve existing files on uploading new one, you can go like:
200
+
201
+ ```erb
202
+ <% user.avatars.each do |avatar| %>
203
+ <%= hidden_field :user, :avatars, multiple: true, value: avatar.identifier %>
204
+ <% end %>
205
+ <%= form.file_field :avatars, multiple: true %>
206
+ ```
207
+
208
+ 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).
209
+
193
210
  ## Changing the storage directory
194
211
 
195
212
  In order to change where uploaded files are put, just override the `store_dir`
@@ -216,10 +233,24 @@ class MyUploader < CarrierWave::Uploader::Base
216
233
  end
217
234
  ```
218
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
+
219
250
  ## Securing uploads
220
251
 
221
252
  Certain files might be dangerous if uploaded to the wrong location, such as PHP
222
- files or other script files. CarrierWave allows you to specify a whitelist of
253
+ files or other script files. CarrierWave allows you to specify an allowlist of
223
254
  allowed extensions or content types.
224
255
 
225
256
  If you're mounting the uploader, uploading a file with the wrong extension will
@@ -227,7 +258,7 @@ make the record invalid instead. Otherwise, an error is raised.
227
258
 
228
259
  ```ruby
229
260
  class MyUploader < CarrierWave::Uploader::Base
230
- def extension_whitelist
261
+ def extension_allowlist
231
262
  %w(jpg jpeg gif png)
232
263
  end
233
264
  end
@@ -238,29 +269,45 @@ Let's say we need an uploader that accepts only images. This can be done like th
238
269
 
239
270
  ```ruby
240
271
  class MyUploader < CarrierWave::Uploader::Base
241
- def content_type_whitelist
272
+ def content_type_allowlist
242
273
  /image\//
243
274
  end
244
275
  end
245
276
  ```
246
277
 
247
- You can use a blacklist to reject content types.
278
+ You can use a denylist to reject content types.
248
279
  Let's say we need an uploader that reject JSON files. This can be done like this
249
280
 
250
281
  ```ruby
251
282
  class NoJsonUploader < CarrierWave::Uploader::Base
252
- def content_type_blacklist
283
+ def content_type_denylist
253
284
  ['application/text', 'application/json']
254
285
  end
255
286
  end
256
287
  ```
257
288
 
289
+ ### CVE-2016-3714 (ImageTragick)
290
+ This version of CarrierWave has the ability to mitigate CVE-2016-3714. However, you **MUST** set a content_type_allowlist 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.
291
+
292
+
293
+ A valid allowlist that will restrict your uploader to images only, and mitigate the CVE is:
294
+
295
+ ```ruby
296
+ class MyUploader < CarrierWave::Uploader::Base
297
+ def content_type_allowlist
298
+ [/image\//]
299
+ end
300
+ end
301
+ ```
302
+
303
+ **WARNING**: A `content_type_allowlist` is the only form of allowlist or denylist supported by CarrierWave that can effectively mitigate against CVE-2016-3714. Use of `extension_allowlist` will not inspect the file headers, and thus still leaves your application open to the vulnerability.
304
+
258
305
  ### Filenames and unicode chars
259
306
 
260
307
  Another security issue you should care for is the file names (see
261
308
  [Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html#file-uploads)).
262
309
  By default, CarrierWave provides only English letters, arabic numerals and some symbols as
263
- white-listed characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
310
+ allowlisted characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
264
311
  have to override `sanitize_regexp` method. It should return regular expression which would match
265
312
  all *non*-allowed symbols.
266
313
 
@@ -278,17 +325,8 @@ You no longer need to do this manually.
278
325
 
279
326
  ## Adding versions
280
327
 
281
- 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
-
283
- *Note:* You must have Imagemagick and MiniMagick installed to do image resizing. MiniMagick is a Ruby interface for Imagemagick which is a C program. This is why MiniMagick fails on 'bundle install' without Imagemagick installed.
284
-
285
- Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
286
-
287
- To install Imagemagick on OSX with homebrew type the following:
288
-
289
- ```
290
- $ brew install imagemagick
291
- ```
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).
292
330
 
293
331
  ```ruby
294
332
  class MyUploader < CarrierWave::Uploader::Base
@@ -305,15 +343,13 @@ end
305
343
 
306
344
  When this uploader is used, an uploaded image would be scaled to be no larger
307
345
  than 800 by 800 pixels. The original aspect ratio will be kept.
308
- A version called thumb is then created, which is scaled
309
- to exactly 200 by 200 pixels.
310
346
 
311
- If you would like to crop images to a specific height and width you
312
- can use the alternative option of '''resize_to_fill'''. It will make sure
347
+ A version called `:thumb` is then created, which is scaled
348
+ to exactly 200 by 200 pixels. The thumbnail uses `resize_to_fill` which makes sure
313
349
  that the width and height specified are filled, only cropping
314
350
  if the aspect ratio requires it.
315
351
 
316
- The uploader could be used like this:
352
+ The above uploader could be used like this:
317
353
 
318
354
  ```ruby
319
355
  uploader = AvatarUploader.new
@@ -326,6 +362,24 @@ uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
326
362
  One important thing to remember is that process is called *before* versions are
327
363
  created. This can cut down on processing cost.
328
364
 
365
+ ### Conditional processing
366
+
367
+ If you want to use conditional process, you can only use `if` statement.
368
+
369
+ See `carrierwave/uploader/processing.rb` for details.
370
+
371
+ ```ruby
372
+ class MyUploader < CarrierWave::Uploader::Base
373
+ process :scale => [200, 200], :if => :image?
374
+
375
+ def image?(carrier_wave_sanitized_file)
376
+ true
377
+ end
378
+ end
379
+ ```
380
+
381
+ ### Nested versions
382
+
329
383
  It is possible to nest versions within versions:
330
384
 
331
385
  ```ruby
@@ -362,7 +416,7 @@ private
362
416
  end
363
417
 
364
418
  def is_landscape? picture
365
- image = MiniMagick::Image.open(picture.path)
419
+ image = MiniMagick::Image.new(picture.path)
366
420
  image[:width] > image[:height]
367
421
  end
368
422
 
@@ -392,8 +446,27 @@ class MyUploader < CarrierWave::Uploader::Base
392
446
  end
393
447
  ```
394
448
 
395
- The option `:from_version` uses the file cached in the `:thumb` version instead
396
- of the original version, potentially resulting in faster processing.
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.
397
470
 
398
471
  ## Making uploads work across form redisplays
399
472
 
@@ -478,6 +551,17 @@ failures automatically with attribute validation errors. If you aren't, or you
478
551
  disable CarrierWave's `validate_download` option, you'll need to handle those
479
552
  errors yourself.
480
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
+
481
565
  ## Providing a default URL
482
566
 
483
567
  In many cases, especially when working with images, it might be a good idea to
@@ -575,14 +659,17 @@ end
575
659
  ## Testing with CarrierWave
576
660
 
577
661
  It's a good idea to test your uploaders in isolation. In order to speed up your
578
- tests, it's recommended to switch off processing in your tests, and to use the
579
- file storage. In Rails you could do that by adding an initializer with:
662
+ tests, it's recommended to switch off processing in your tests, and to use the file storage.
663
+ Also, you can disable SSRF protection at your own risk using the `skip_ssrf_protection` configuration.
664
+
665
+ In Rails you could do that by adding an initializer with:
580
666
 
581
667
  ```ruby
582
668
  if Rails.env.test? or Rails.env.cucumber?
583
669
  CarrierWave.configure do |config|
584
670
  config.storage = :file
585
671
  config.enable_processing = false
672
+ config.skip_ssrf_protection = true
586
673
  end
587
674
  end
588
675
  ```
@@ -651,7 +738,6 @@ If you want to use fog you must add in your CarrierWave initializer the
651
738
  following lines
652
739
 
653
740
  ```ruby
654
- config.fog_provider = 'fog' # 'fog/aws' etc. Defaults to 'fog'
655
741
  config.fog_credentials = { ... } # Provider specific credentials
656
742
  ```
657
743
 
@@ -669,7 +755,6 @@ You can also pass in additional options, as documented fully in lib/carrierwave/
669
755
 
670
756
  ```ruby
671
757
  CarrierWave.configure do |config|
672
- config.fog_provider = 'fog/aws' # required
673
758
  config.fog_credentials = {
674
759
  provider: 'AWS', # required
675
760
  aws_access_key_id: 'xxx', # required unless using use_iam_profile
@@ -682,6 +767,13 @@ CarrierWave.configure do |config|
682
767
  config.fog_directory = 'name_of_bucket' # required
683
768
  config.fog_public = false # optional, defaults to true
684
769
  config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
770
+ # Use this if you have AWS S3 ACLs disabled.
771
+ # config.fog_attributes = { 'x-amz-acl' => 'bucket-owner-full-control' }
772
+ # Use this if you have Google Cloud Storage uniform bucket-level access enabled.
773
+ # config.fog_attributes = { uniform: true }
774
+ # For an application which utilizes multiple servers but does not need caches persisted across requests,
775
+ # uncomment the line :file instead of the default :storage. Otherwise, it will use AWS as the temp cache store.
776
+ # config.cache_storage = :file
685
777
  end
686
778
  ```
687
779
 
@@ -695,6 +787,14 @@ end
695
787
 
696
788
  That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
697
789
 
790
+ **Note**: for Carrierwave to work properly it needs credentials with the following permissions:
791
+
792
+ * `s3:ListBucket`
793
+ * `s3:PutObject`
794
+ * `s3:GetObject`
795
+ * `s3:DeleteObject`
796
+ * `s3:PutObjectAcl`
797
+
698
798
  ## Using Rackspace Cloud Files
699
799
 
700
800
  [Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
@@ -704,13 +804,12 @@ gem "fog"
704
804
  ```
705
805
 
706
806
  You'll need to configure a directory (also known as a container), username and API key in the initializer.
707
- For the sake of performance it is assumed that the directory already exists, so please create it if need be.
807
+ For the sake of performance it is assumed that the directory already exists, so please create it if needs to be.
708
808
 
709
809
  Using a US-based account:
710
810
 
711
811
  ```ruby
712
812
  CarrierWave.configure do |config|
713
- config.fog_provider = "fog/rackspace/storage" # optional, defaults to "fog"
714
813
  config.fog_credentials = {
715
814
  provider: 'Rackspace',
716
815
  rackspace_username: 'xxxxxx',
@@ -725,7 +824,6 @@ Using a UK-based account:
725
824
 
726
825
  ```ruby
727
826
  CarrierWave.configure do |config|
728
- config.fog_provider = "fog/rackspace/storage" # optional, defaults to "fog"
729
827
  config.fog_credentials = {
730
828
  provider: 'Rackspace',
731
829
  rackspace_username: 'xxxxxx',
@@ -756,31 +854,41 @@ end
756
854
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
757
855
  the url to the file on Rackspace Cloud Files.
758
856
 
759
- ## Using Google Storage for Developers
857
+ ## Using Google Cloud Storage
760
858
 
761
- [Fog](http://github.com/fog/fog-google) is used to support Google Storage for Developers. Ensure you have it in your Gemfile:
859
+ [Fog](http://github.com/fog/fog-google) is used to support Google Cloud Storage. Ensure you have it in your Gemfile:
762
860
 
763
861
  ```ruby
764
862
  gem "fog-google"
765
- gem "google-api-client", "> 0.8.5", "< 0.9"
766
- gem "mime-types"
767
863
  ```
768
864
 
769
- You'll need to configure a directory (also known as a bucket), access key id and secret access key in the initializer.
770
- For the sake of performance it is assumed that the directory already exists, so please create it if need be.
865
+ You'll need to configure a directory (also known as a bucket) and the credentials in the initializer.
866
+ For the sake of performance it is assumed that the directory already exists, so please create it if needs to be.
771
867
 
772
868
  Please read the [fog-google README](https://github.com/fog/fog-google/blob/master/README.md) on how to get credentials.
773
869
 
870
+ For Google Storage JSON API (recommended):
871
+ ```ruby
872
+ CarrierWave.configure do |config|
873
+ config.fog_credentials = {
874
+ provider: 'Google',
875
+ google_project: 'my-project',
876
+ google_json_key_string: 'xxxxxx'
877
+ # or use google_json_key_location if using an actual file
878
+ }
879
+ config.fog_directory = 'google_cloud_storage_bucket_name'
880
+ end
881
+ ```
774
882
 
883
+ For Google Storage XML API:
775
884
  ```ruby
776
885
  CarrierWave.configure do |config|
777
- config.fog_provider = 'fog/google' # required
778
- config.fog_credentials = {
779
- provider: 'Google',
780
- google_storage_access_key_id: 'xxxxxx',
781
- google_storage_secret_access_key: 'yyyyyy'
782
- }
783
- config.fog_directory = 'name_of_directory'
886
+ config.fog_credentials = {
887
+ provider: 'Google',
888
+ google_storage_access_key_id: 'xxxxxx',
889
+ google_storage_secret_access_key: 'yyyyyy'
890
+ }
891
+ config.fog_directory = 'google_cloud_storage_bucket_name'
784
892
  end
785
893
  ```
786
894
 
@@ -833,12 +941,48 @@ CarrierWave.configure do |config|
833
941
  end
834
942
  ```
835
943
 
836
- ## Using RMagick
944
+ ## Manipulating images
837
945
 
838
946
  If you're uploading images, you'll probably want to manipulate them in some way,
839
- you might want to create thumbnail images for example. CarrierWave comes with a
840
- small library to make manipulating images with RMagick easier, you'll need to
841
- include it in your Uploader:
947
+ you might want to create thumbnail images for example.
948
+
949
+ ### Using MiniMagick
950
+
951
+ MiniMagick performs all the operations using the 'convert' CLI which is part of the standard ImageMagick kit.
952
+ This allows you to have the power of ImageMagick without having to worry about installing
953
+ all the RMagick libraries, it often results in higher memory footprint.
954
+
955
+ See the MiniMagick site for more details:
956
+
957
+ https://github.com/minimagick/minimagick
958
+
959
+ To install Imagemagick on OSX with homebrew type the following:
960
+
961
+ ```
962
+ $ brew install imagemagick
963
+ ```
964
+
965
+ And the ImageMagick command line options for more for what's on offer:
966
+
967
+ http://www.imagemagick.org/script/command-line-options.php
968
+
969
+ Currently, the MiniMagick carrierwave processor provides exactly the same methods as
970
+ for the RMagick processor.
971
+
972
+ ```ruby
973
+ class AvatarUploader < CarrierWave::Uploader::Base
974
+ include CarrierWave::MiniMagick
975
+
976
+ process resize_to_fill: [200, 200]
977
+ end
978
+ ```
979
+
980
+ See `carrierwave/processing/mini_magick.rb` for details.
981
+
982
+ ### Using RMagick
983
+
984
+ CarrierWave also comes with support for RMagick, a well-known image processing library.
985
+ To use it, you'll need to include this in your Uploader:
842
986
 
843
987
  ```ruby
844
988
  class AvatarUploader < CarrierWave::Uploader::Base
@@ -851,7 +995,6 @@ The RMagick module gives you a few methods, like
851
995
  way. You can set a `process` callback, which will call that method any time a
852
996
  file is uploaded.
853
997
  There is a demonstration of convert here.
854
- Convert will only work if the file has the same file extension, thus the use of the filename method.
855
998
 
856
999
  ```ruby
857
1000
  class AvatarUploader < CarrierWave::Uploader::Base
@@ -859,40 +1002,59 @@ class AvatarUploader < CarrierWave::Uploader::Base
859
1002
 
860
1003
  process resize_to_fill: [200, 200]
861
1004
  process convert: 'png'
862
-
863
- def filename
864
- super.chomp(File.extname(super)) + '.png' if original_filename.present?
865
- end
866
1005
  end
867
1006
  ```
868
1007
 
869
1008
  Check out the manipulate! method, which makes it easy for you to write your own
870
1009
  manipulation methods.
871
1010
 
872
- ## Using MiniMagick
1011
+ ### Using Vips
873
1012
 
874
- MiniMagick is similar to RMagick but performs all the operations using the 'mogrify'
875
- command which is part of the standard ImageMagick kit. This allows you to have the power
876
- of ImageMagick without having to worry about installing all the RMagick libraries.
1013
+ CarrierWave version 2.2.0 added support for the `libvips` image processing library, through [ImageProcessing::Vips](https://github.com/janko/image_processing/blob/master/doc/vips.md). Its functionality matches that of the RMagick and MiniMagick processors, but it uses less memory and offers [faster processing](https://github.com/libvips/libvips/wiki/Speed-and-memory-use). To use the Vips processing module you must first install `libvips`, for example:
877
1014
 
878
- See the MiniMagick site for more details:
1015
+ ````bash
1016
+ $ sudo apt install libvips
1017
+ ````
879
1018
 
880
- https://github.com/minimagick/minimagick
1019
+ You also need to tell your uploader to use Vips:
881
1020
 
882
- And the ImageMagick command line options for more for whats on offer:
1021
+ ````ruby
1022
+ class ImageFileUploader < CarrierWave::Uploader::Base
1023
+ include CarrierWave::Vips
1024
+ end
1025
+ ````
883
1026
 
884
- http://www.imagemagick.org/script/command-line-options.php
1027
+ ### List of available processing methods:
885
1028
 
886
- Currently, the MiniMagick carrierwave processor provides exactly the same methods as
887
- for the RMagick processor.
1029
+ > [!NOTE]
1030
+ > While the intention is to provide uniform interfaces to all three processing libraries the availability and implementation of processing methods can <a href="supported-processing-methods">vary slightly between them</a>.
888
1031
 
889
- ```ruby
890
- class AvatarUploader < CarrierWave::Uploader::Base
891
- include CarrierWave::MiniMagick
1032
+ - `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.
1033
+ - `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.
1034
+ - `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.
1035
+ - `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".
1036
+ - `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.
1037
+ - `crop` - Crop the image to the contents of a box with the specified height and width, positioned a given number of pixels from the top and left. The original image edge will be retained should the bottom and/or right edge of the box fall outside the image bounds.
892
1038
 
893
- process resize_to_fill: [200, 200]
894
- end
895
- ```
1039
+ #### Supported processing methods
1040
+
1041
+ The following table shows which processing methods are supported by each processing library, and which parameters they accept:
1042
+
1043
+ Method|RMagick|MiniMagick|Vips
1044
+ ------|-----------------|-----------------|-----------------|
1045
+ `convert`|`format`|`format`, `page`<sup>1</sup>|`format`, `page`<sup>1</sup>
1046
+ `resize_to_limit`|`width`, `height`|`width`, `height`|`width`, `height`
1047
+ `resize_to_fit`|`width`, `height`|`width`, `height`|`width`, `height`
1048
+ `resize_to_fill`|`width`, `height`, `gravity`<sup>2</sup>|`width`, `height`, `gravity`<sup>2</sup>|`width`, `height`
1049
+ `resize_and_pad`|`width`, `height`, `background`, `gravity`<sup>2</sup>|`width`, `height`, `background`, `gravity`<sup>2</sup>|`width`, `height`, `background`, `gravity`<sup>2</sup>
1050
+ `resize_to_geometry_string`|`geometry_string`<sup>3</sup>|*not implemented*|*not implemented*
1051
+ `crop`|`left`, `top`, `width`, `height`|`left`, `top`, `width`, `height`|`left`, `top`, `width`, `height`
1052
+
1053
+ <sup>1</sup>`page` refers to the page number when converting from PDF, frame number when converting from GIF, and layer number when converting from PSD.
1054
+
1055
+ <sup>2</sup>`gravity` refers to an image position given as one of `Center`, `North`, `NorthWest`, `West`, `SouthWest`, `South`, `SouthEast`, `East`, or `NorthEast`.
1056
+
1057
+ <sup>3</sup>`geometry_string` is an [ImageMagick geometry string](https://rmagick.github.io/imusage.html#geometry).
896
1058
 
897
1059
  ## Migrating from Paperclip
898
1060
 
@@ -924,14 +1086,17 @@ errors:
924
1086
  carrierwave_processing_error: failed to be processed
925
1087
  carrierwave_integrity_error: is not of an allowed file type
926
1088
  carrierwave_download_error: could not be downloaded
927
- extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
928
- extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
929
- content_type_whitelist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
930
- content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
931
- rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
932
- mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
1089
+ extension_allowlist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
1090
+ extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
1091
+ content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
1092
+ content_type_denylist_error: "You are not allowed to upload %{content_type} files"
1093
+ processing_error: "Failed to manipulate, maybe it is not an image?"
933
1094
  min_size_error: "File size should be greater than %{min_size}"
934
1095
  max_size_error: "File size should be less than %{max_size}"
1096
+ min_width_error: "Image width should be greater than %{min_width}px"
1097
+ max_width_error: "Image width should be less than %{max_width}px"
1098
+ min_height_error: "Image height should be greater than %{min_height}px"
1099
+ max_height_error: "Image height should be less than %{max_height}px"
935
1100
  ```
936
1101
 
937
1102
  The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
@@ -975,12 +1140,12 @@ end
975
1140
  Will add these callbacks:
976
1141
 
977
1142
  ```ruby
978
- after_save :store_avatar!
979
1143
  before_save :write_avatar_identifier
1144
+ after_save :store_previous_changes_for_avatar
980
1145
  after_commit :remove_avatar!, on: :destroy
981
1146
  after_commit :mark_remove_avatar_false, on: :update
982
- after_save :store_previous_changes_for_avatar
983
1147
  after_commit :remove_previously_stored_avatar, on: :update
1148
+ after_commit :store_avatar!, on: [:create, :update]
984
1149
  ```
985
1150
 
986
1151
  If you want to skip any of these callbacks (eg. you want to keep the existing
@@ -994,13 +1159,40 @@ class User
994
1159
  end
995
1160
  ```
996
1161
 
1162
+ ## Uploader Callbacks
1163
+
1164
+ In addition to the ActiveRecord callbacks described above, uploaders also have callbacks.
1165
+
1166
+ ```ruby
1167
+ class MyUploader < ::CarrierWave::Uploader::Base
1168
+ before :remove, :log_removal
1169
+ private
1170
+ def log_removal
1171
+ ::Rails.logger.info(format('Deleting file on S3: %s', @file))
1172
+ end
1173
+ end
1174
+ ```
1175
+
1176
+ Uploader callbacks can be `before` or `after` the following events:
1177
+
1178
+ ```
1179
+ cache
1180
+ process
1181
+ remove
1182
+ retrieve_from_cache
1183
+ retrieve_from_store
1184
+ store
1185
+ ```
1186
+
997
1187
  ## Contributing to CarrierWave
998
1188
 
999
1189
  See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
1000
1190
 
1001
1191
  ## License
1002
1192
 
1003
- Copyright (c) 2008-2015 Jonas Nicklas
1193
+ The MIT License (MIT)
1194
+
1195
+ Copyright (c) 2008 Jonas Nicklas
1004
1196
 
1005
1197
  Permission is hereby granted, free of charge, to any person obtaining
1006
1198
  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
- private
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 }