carrierwave 0.9.0 → 2.1.1

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 (51) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +362 -116
  3. data/lib/carrierwave/compatibility/paperclip.rb +29 -21
  4. data/lib/carrierwave/downloader/base.rb +83 -0
  5. data/lib/carrierwave/downloader/remote_file.rb +65 -0
  6. data/lib/carrierwave/error.rb +1 -0
  7. data/lib/carrierwave/locale/en.yml +7 -4
  8. data/lib/carrierwave/mount.rb +238 -186
  9. data/lib/carrierwave/mounter.rb +188 -0
  10. data/lib/carrierwave/orm/activerecord.rb +60 -24
  11. data/lib/carrierwave/processing/mini_magick.rb +139 -78
  12. data/lib/carrierwave/processing/rmagick.rb +68 -23
  13. data/lib/carrierwave/processing.rb +0 -1
  14. data/lib/carrierwave/sanitized_file.rb +67 -27
  15. data/lib/carrierwave/storage/abstract.rb +15 -2
  16. data/lib/carrierwave/storage/file.rb +69 -2
  17. data/lib/carrierwave/storage/fog.rb +180 -41
  18. data/lib/carrierwave/storage.rb +1 -7
  19. data/lib/carrierwave/test/matchers.rb +77 -12
  20. data/lib/carrierwave/uploader/cache.rb +74 -38
  21. data/lib/carrierwave/uploader/callbacks.rb +0 -2
  22. data/lib/carrierwave/uploader/configuration.rb +72 -6
  23. data/lib/carrierwave/uploader/content_type_blacklist.rb +48 -0
  24. data/lib/carrierwave/uploader/content_type_whitelist.rb +48 -0
  25. data/lib/carrierwave/uploader/default_url.rb +3 -5
  26. data/lib/carrierwave/uploader/download.rb +5 -69
  27. data/lib/carrierwave/uploader/extension_blacklist.rb +14 -10
  28. data/lib/carrierwave/uploader/extension_whitelist.rb +13 -10
  29. data/lib/carrierwave/uploader/file_size.rb +43 -0
  30. data/lib/carrierwave/uploader/mountable.rb +13 -8
  31. data/lib/carrierwave/uploader/processing.rb +15 -17
  32. data/lib/carrierwave/uploader/proxy.rb +16 -7
  33. data/lib/carrierwave/uploader/remove.rb +0 -2
  34. data/lib/carrierwave/uploader/serialization.rb +3 -5
  35. data/lib/carrierwave/uploader/store.rb +17 -24
  36. data/lib/carrierwave/uploader/url.rb +3 -5
  37. data/lib/carrierwave/uploader/versions.rb +117 -86
  38. data/lib/carrierwave/uploader.rb +6 -2
  39. data/lib/carrierwave/utilities/uri.rb +5 -6
  40. data/lib/carrierwave/utilities.rb +1 -3
  41. data/lib/carrierwave/validations/active_model.rb +3 -7
  42. data/lib/carrierwave/version.rb +1 -1
  43. data/lib/carrierwave.rb +36 -3
  44. data/lib/generators/templates/uploader.rb +4 -8
  45. data/lib/generators/uploader_generator.rb +1 -1
  46. metadata +195 -94
  47. data/lib/carrierwave/locale/cs.yml +0 -11
  48. data/lib/carrierwave/locale/de.yml +0 -11
  49. data/lib/carrierwave/locale/nl.yml +0 -11
  50. data/lib/carrierwave/locale/sk.yml +0 -11
  51. data/lib/carrierwave/processing/mime_types.rb +0 -73
data/README.md CHANGED
@@ -3,8 +3,10 @@
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://secure.travis-ci.org/carrierwaveuploader/carrierwave.png)](http://travis-ci.org/carrierwaveuploader/carrierwave)
7
- [![Code Climate](https://codeclimate.com/github/carrierwaveuploader/carrierwave.png)](https://codeclimate.com/github/carrierwaveuploader/carrierwave)
6
+ [![Build Status](https://travis-ci.org/carrierwaveuploader/carrierwave.svg?branch=master)](http://travis-ci.org/carrierwaveuploader/carrierwave)
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
+
8
10
 
9
11
  ## Information
10
12
 
@@ -14,25 +16,27 @@ It works well with Rack based web applications, such as Ruby on Rails.
14
16
 
15
17
  ## Getting Help
16
18
 
17
- * Please ask the [Google Group](http://groups.google.com/group/carrierwave) for help if you have any questions.
19
+ * Please ask the community on [Stack Overflow](https://stackoverflow.com/questions/tagged/carrierwave) for help if you have any questions. Please do not post usage questions on the issue tracker.
18
20
  * Please report bugs on the [issue tracker](http://github.com/carrierwaveuploader/carrierwave/issues) but read the "getting help" section in the wiki first.
19
21
 
20
22
  ## Installation
21
23
 
22
- Install the latest stable release:
24
+ Install the latest release:
23
25
 
24
- [sudo] gem install carrierwave
26
+ ```
27
+ $ gem install carrierwave
28
+ ```
25
29
 
26
30
  In Rails, add it to your Gemfile:
27
31
 
28
32
  ```ruby
29
- gem 'carrierwave'
33
+ gem 'carrierwave', '~> 2.0'
30
34
  ```
31
35
 
32
36
  Finally, restart the server to apply the changes.
33
37
 
34
- Note that CarrierWave is not compatible with Rails 2 as of version 0.5. If you want to use
35
- Rails 2, please use the 0.4-stable branch on GitHub.
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.
36
40
 
37
41
  ## Getting Started
38
42
 
@@ -85,7 +89,7 @@ a migration:
85
89
 
86
90
 
87
91
  rails g migration add_avatar_to_users avatar:string
88
- rake db:migrate
92
+ rails db:migrate
89
93
 
90
94
  Open your model file and mount the uploader:
91
95
 
@@ -100,14 +104,22 @@ automatically be stored when the record is saved.
100
104
 
101
105
  ```ruby
102
106
  u = User.new
103
- u.avatar = params[:file]
104
- u.avatar = File.open('somewhere')
107
+ u.avatar = params[:file] # Assign a file like this, or
108
+
109
+ # like this
110
+ File.open('somewhere') do |f|
111
+ u.avatar = f
112
+ end
113
+
105
114
  u.save!
106
115
  u.avatar.url # => '/url/to/file.png'
107
116
  u.avatar.current_path # => 'path/to/file.png'
108
- u.avatar.identifier # => 'file.png'
117
+ u.avatar_identifier # => 'file.png'
109
118
  ```
110
119
 
120
+ **Note**: `u.avatar` will never return nil, even if there is no photo associated to it.
121
+ To check if a photo was saved to the model, use `u.avatar.file.nil?` instead.
122
+
111
123
  ### DataMapper, Mongoid, Sequel
112
124
 
113
125
  Other ORM support has been extracted into separate gems:
@@ -118,6 +130,77 @@ Other ORM support has been extracted into separate gems:
118
130
 
119
131
  There are more extensions listed in [the wiki](https://github.com/carrierwaveuploader/carrierwave/wiki)
120
132
 
133
+ ## Multiple file uploads
134
+
135
+ CarrierWave also has convenient support for multiple file upload fields.
136
+
137
+ ### ActiveRecord
138
+
139
+ Add a column which can store an array. This could be an array column or a JSON
140
+ column for example. Your choice depends on what your database supports. For
141
+ example, create a migration like this:
142
+
143
+
144
+ #### For databases with ActiveRecord json data type support (e.g. PostgreSQL, MySQL)
145
+
146
+ rails g migration add_avatars_to_users avatars:json
147
+ rails db:migrate
148
+
149
+ #### For database without ActiveRecord json data type support (e.g. SQLite)
150
+
151
+ rails g migration add_avatars_to_users avatars:string
152
+ rails db:migrate
153
+
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
+
156
+ Open your model file and mount the uploader:
157
+
158
+
159
+ ```ruby
160
+ class User < ActiveRecord::Base
161
+ mount_uploaders :avatars, AvatarUploader
162
+ serialize :avatars, JSON # If you use SQLite, add this line.
163
+ end
164
+ ```
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
+
169
+ Make sure your file input fields are set up as multiple file fields. For
170
+ example in Rails you'll want to do something like this:
171
+
172
+ ```erb
173
+ <%= form.file_field :avatars, multiple: true %>
174
+ ```
175
+
176
+ Also, make sure your upload controller permits the multiple file upload attribute, *pointing to an empty array in a hash*. For example:
177
+
178
+ ```ruby
179
+ params.require(:user).permit(:email, :first_name, :last_name, {avatars: []})
180
+ ```
181
+
182
+ Now you can select multiple files in the upload dialog (e.g. SHIFT+SELECT), and they will
183
+ automatically be stored when the record is saved.
184
+
185
+ ```ruby
186
+ u = User.new(params[:user])
187
+ u.save!
188
+ u.avatars[0].url # => '/url/to/file.png'
189
+ u.avatars[0].current_path # => 'path/to/file.png'
190
+ u.avatars[0].identifier # => 'file.png'
191
+ ```
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
+
121
204
  ## Changing the storage directory
122
205
 
123
206
  In order to change where uploaded files are put, just override the `store_dir`
@@ -146,97 +229,140 @@ end
146
229
 
147
230
  ## Securing uploads
148
231
 
149
- Certain file might be dangerous if uploaded to the wrong location, such as php
150
- files or other script files. CarrierWave allows you to specify a white-list of
151
- allowed extensions.
232
+ Certain files might be dangerous if uploaded to the wrong location, such as PHP
233
+ files or other script files. CarrierWave allows you to specify a whitelist of
234
+ allowed extensions or content types.
152
235
 
153
236
  If you're mounting the uploader, uploading a file with the wrong extension will
154
237
  make the record invalid instead. Otherwise, an error is raised.
155
238
 
156
239
  ```ruby
157
240
  class MyUploader < CarrierWave::Uploader::Base
158
- def extension_white_list
241
+ def extension_whitelist
159
242
  %w(jpg jpeg gif png)
160
243
  end
161
244
  end
162
245
  ```
163
246
 
247
+ The same thing could be done using content types.
248
+ Let's say we need an uploader that accepts only images. This can be done like this
249
+
250
+ ```ruby
251
+ class MyUploader < CarrierWave::Uploader::Base
252
+ def content_type_whitelist
253
+ /image\//
254
+ end
255
+ end
256
+ ```
257
+
258
+ You can use a blacklist to reject content types.
259
+ Let's say we need an uploader that reject JSON files. This can be done like this
260
+
261
+ ```ruby
262
+ class NoJsonUploader < CarrierWave::Uploader::Base
263
+ def content_type_blacklist
264
+ ['application/text', 'application/json']
265
+ end
266
+ end
267
+ ```
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
+
164
285
  ### Filenames and unicode chars
165
286
 
166
287
  Another security issue you should care for is the file names (see
167
288
  [Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html#file-uploads)).
168
- By default, CarrierWave provides only English letters, arabic numerals and '-+_.' symbols as
289
+ By default, CarrierWave provides only English letters, arabic numerals and some symbols as
169
290
  white-listed characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
170
291
  have to override `sanitize_regexp` method. It should return regular expression which would match
171
292
  all *non*-allowed symbols.
172
293
 
173
- With Ruby 1.9 and higher you can simply write (as it has [Oniguruma](http://oniguruma.rubyforge.org/oniguruma/)
174
- built-in):
175
-
176
294
  ```ruby
177
295
  CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
178
296
  ```
179
297
 
180
- With Ruby 1.8 you have to manually specify all character ranges. For example, for files which may
181
- contain Russian letters:
182
-
183
- ```ruby
184
- CarrierWave::SanitizedFile.sanitize_regexp = /[^a-zA-Zа-яА-ЯёЁ0-9\.\-\+_]/u
185
- ```
186
-
187
298
  Also make sure that allowing non-latin characters won't cause a compatibility issue with a third-party
188
299
  plugins or client-side software.
189
300
 
190
301
  ## Setting the content type
191
302
 
192
- If you care about the content type of your files and notice that it's not being set
193
- as expected, you can configure your uploaders to use `CarrierWave::MimeTypes`.
194
- This adds a dependency on the [mime-types](http://rubygems.org/gems/mime-types) gem,
195
- but is recommended when using fog, and fog already has a dependency on mime-types.
303
+ As of v0.11.0, the `mime-types` gem is a runtime dependency and the content type is set automatically.
304
+ You no longer need to do this manually.
196
305
 
197
- ```ruby
198
- require 'carrierwave/processing/mime_types'
306
+ ## Adding versions
199
307
 
200
- class MyUploader < CarrierWave::Uploader::Base
201
- include CarrierWave::MimeTypes
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*:
202
309
 
203
- process :set_content_type
204
- end
205
- ```
310
+ *Note:* You must have Imagemagick installed to do image resizing.
206
311
 
207
- ## Adding versions
312
+ Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
208
313
 
209
- Often you'll want to add different versions of the same file. The classic
210
- example is image thumbnails. There is built in support for this:
314
+ To install Imagemagick on OSX with homebrew type the following:
315
+
316
+ ```
317
+ $ brew install imagemagick
318
+ ```
211
319
 
212
320
  ```ruby
213
321
  class MyUploader < CarrierWave::Uploader::Base
214
- include CarrierWave::RMagick
322
+ include CarrierWave::MiniMagick
215
323
 
216
- process :resize_to_fit => [800, 800]
324
+ process resize_to_fit: [800, 800]
217
325
 
218
326
  version :thumb do
219
- process :resize_to_fill => [200,200]
327
+ process resize_to_fill: [200,200]
220
328
  end
221
329
 
222
330
  end
223
331
  ```
224
332
 
225
333
  When this uploader is used, an uploaded image would be scaled to be no larger
226
- than 800 by 800 pixels. A version called thumb is then created, which is scaled
227
- and cropped to exactly 200 by 200 pixels. The uploader could be used like this:
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:
228
342
 
229
343
  ```ruby
230
344
  uploader = AvatarUploader.new
231
345
  uploader.store!(my_file) # size: 1024x768
232
346
 
233
- uploader.url # => '/url/to/my_file.png' # size: 800x600
347
+ uploader.url # => '/url/to/my_file.png' # size: 800x800
234
348
  uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
235
349
  ```
236
350
 
237
351
  One important thing to remember is that process is called *before* versions are
238
352
  created. This can cut down on processing cost.
239
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
+
240
366
  It is possible to nest versions within versions:
241
367
 
242
368
  ```ruby
@@ -258,11 +384,11 @@ properties within the model or based on the picture itself.
258
384
  ```ruby
259
385
  class MyUploader < CarrierWave::Uploader::Base
260
386
 
261
- version :human, :if => :is_human?
262
- version :monkey, :if => :is_monkey?
263
- version :banner, :if => :is_landscape?
387
+ version :human, if: :is_human?
388
+ version :monkey, if: :is_monkey?
389
+ version :banner, if: :is_landscape?
264
390
 
265
- protected
391
+ private
266
392
 
267
393
  def is_human? picture
268
394
  model.can_program?(:ruby)
@@ -273,7 +399,7 @@ protected
273
399
  end
274
400
 
275
401
  def is_landscape? picture
276
- image = MiniMagick::Image.open(picture.path)
402
+ image = MiniMagick::Image.new(picture.path)
277
403
  image[:width] > image[:height]
278
404
  end
279
405
 
@@ -296,7 +422,7 @@ class MyUploader < CarrierWave::Uploader::Base
296
422
  process resize_to_fill: [280, 280]
297
423
  end
298
424
 
299
- version :small_thumb, :from_version => :thumb do
425
+ version :small_thumb, from_version: :thumb do
300
426
  process resize_to_fill: [20, 20]
301
427
  end
302
428
 
@@ -315,7 +441,7 @@ file, just add a hidden field called `avatar_cache` (don't forget to add it to
315
441
  the attr_accessible list as necessary). In Rails, this would look like this:
316
442
 
317
443
  ```erb
318
- <%= form_for @user, :html => {:multipart => true} do |f| %>
444
+ <%= form_for @user, html: { multipart: true } do |f| %>
319
445
  <p>
320
446
  <label>My Avatar</label>
321
447
  <%= f.file_field :avatar %>
@@ -328,7 +454,7 @@ It might be a good idea to show the user that a file has been uploaded, in the
328
454
  case of images, a small thumbnail would be a good indicator:
329
455
 
330
456
  ```erb
331
- <%= form_for @user, :html => {:multipart => true} do |f| %>
457
+ <%= form_for @user, html: { multipart: true } do |f| %>
332
458
  <p>
333
459
  <label>My Avatar</label>
334
460
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -344,7 +470,7 @@ If you want to remove a previously uploaded file on a mounted uploader, you can
344
470
  easily add a checkbox to the form which will remove the file when checked.
345
471
 
346
472
  ```erb
347
- <%= form_for @user, :html => {:multipart => true} do |f| %>
473
+ <%= form_for @user, html: { multipart: true } do |f| %>
348
474
  <p>
349
475
  <label>My Avatar</label>
350
476
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -360,7 +486,13 @@ easily add a checkbox to the form which will remove the file when checked.
360
486
  <% end %>
361
487
  ```
362
488
 
363
- If you want to remove the file manually, you can call <code>remove_avatar!</code>.
489
+ If you want to remove the file manually, you can call <code>remove_avatar!</code>, then save the object.
490
+
491
+ ```erb
492
+ @user.remove_avatar!
493
+ @user.save
494
+ #=> true
495
+ ```
364
496
 
365
497
  ## Uploading files from a remote location
366
498
 
@@ -369,7 +501,7 @@ via a URL. CarrierWave makes this simple, just add the appropriate attribute to
369
501
  form and you're good to go:
370
502
 
371
503
  ```erb
372
- <%= form_for @user, :html => {:multipart => true} do |f| %>
504
+ <%= form_for @user, html: { multipart: true } do |f| %>
373
505
  <p>
374
506
  <label>My Avatar URL:</label>
375
507
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -391,7 +523,7 @@ this easily by overriding the `default_url` method in your uploader:
391
523
 
392
524
  ```ruby
393
525
  class MyUploader < CarrierWave::Uploader::Base
394
- def default_url
526
+ def default_url(*args)
395
527
  "/images/fallback/" + [version_name, "default.png"].compact.join('_')
396
528
  end
397
529
  end
@@ -401,7 +533,7 @@ Or if you are using the Rails asset pipeline:
401
533
 
402
534
  ```ruby
403
535
  class MyUploader < CarrierWave::Uploader::Base
404
- def default_url
536
+ def default_url(*args)
405
537
  ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
406
538
  end
407
539
  end
@@ -428,11 +560,19 @@ instance.recreate_versions!(:thumb, :large)
428
560
  Or on a mounted uploader:
429
561
 
430
562
  ```ruby
431
- User.all.each do |user|
563
+ User.find_each do |user|
432
564
  user.avatar.recreate_versions!
433
565
  end
434
566
  ```
435
567
 
568
+ Note: `recreate_versions!` will throw an exception on records without an image. To avoid this, scope the records to those with images or check if an image exists within the block. If you're using ActiveRecord, recreating versions for a user avatar might look like this:
569
+
570
+ ```ruby
571
+ User.find_each do |user|
572
+ user.avatar.recreate_versions! if user.avatar?
573
+ end
574
+ ```
575
+
436
576
  ## Configuring CarrierWave
437
577
 
438
578
  CarrierWave has a broad range of configuration options, which you can configure,
@@ -458,6 +598,16 @@ If you're using Rails, create an initializer for this:
458
598
 
459
599
  config/initializers/carrierwave.rb
460
600
 
601
+ If you want CarrierWave to fail noisily in development, you can change these configs in your environment file:
602
+
603
+ ```ruby
604
+ CarrierWave.configure do |config|
605
+ config.ignore_integrity_errors = false
606
+ config.ignore_processing_errors = false
607
+ config.ignore_download_errors = false
608
+ end
609
+ ```
610
+
461
611
 
462
612
  ## Testing with CarrierWave
463
613
 
@@ -474,6 +624,9 @@ if Rails.env.test? or Rails.env.cucumber?
474
624
  end
475
625
  ```
476
626
 
627
+ Remember, if you have already set `storage :something` in your uploader, the `storage`
628
+ setting from this initializer will be ignored.
629
+
477
630
  If you need to test your processing, you should test it in isolation, and enable
478
631
  processing only for those tests that need it.
479
632
 
@@ -485,35 +638,43 @@ require 'carrierwave/test/matchers'
485
638
  describe MyUploader do
486
639
  include CarrierWave::Test::Matchers
487
640
 
641
+ let(:user) { double('user') }
642
+ let(:uploader) { MyUploader.new(user, :avatar) }
643
+
488
644
  before do
489
645
  MyUploader.enable_processing = true
490
- @uploader = MyUploader.new(@user, :avatar)
491
- @uploader.store!(File.open(path_to_file))
646
+ File.open(path_to_file) { |f| uploader.store!(f) }
492
647
  end
493
648
 
494
649
  after do
495
650
  MyUploader.enable_processing = false
496
- @uploader.remove!
651
+ uploader.remove!
497
652
  end
498
653
 
499
654
  context 'the thumb version' do
500
- it "should scale down a landscape image to be exactly 64 by 64 pixels" do
501
- @uploader.thumb.should have_dimensions(64, 64)
655
+ it "scales down a landscape image to be exactly 64 by 64 pixels" do
656
+ expect(uploader.thumb).to have_dimensions(64, 64)
502
657
  end
503
658
  end
504
659
 
505
660
  context 'the small version' do
506
- it "should scale down a landscape image to fit within 200 by 200 pixels" do
507
- @uploader.small.should be_no_larger_than(200, 200)
661
+ it "scales down a landscape image to fit within 200 by 200 pixels" do
662
+ expect(uploader.small).to be_no_larger_than(200, 200)
508
663
  end
509
664
  end
510
665
 
511
- it "should make the image readable only to the owner and not executable" do
512
- @uploader.should have_permissions(0600)
666
+ it "makes the image readable only to the owner and not executable" do
667
+ expect(uploader).to have_permissions(0600)
668
+ end
669
+
670
+ it "has the correct format" do
671
+ expect(uploader).to be_format('png')
513
672
  end
514
673
  end
515
674
  ```
516
675
 
676
+ If you're looking for minitest asserts, checkout [carrierwave_asserts](https://github.com/hcfairbanks/carrierwave_asserts).
677
+
517
678
  Setting the enable_processing flag on an uploader will prevent any of the versions from processing as well.
518
679
  Processing can be enabled for a single version by setting the processing flag on the version like so:
519
680
 
@@ -521,31 +682,41 @@ Processing can be enabled for a single version by setting the processing flag on
521
682
  @uploader.thumb.enable_processing = true
522
683
  ```
523
684
 
685
+ ## Fog
686
+
687
+ If you want to use fog you must add in your CarrierWave initializer the
688
+ following lines
689
+
690
+ ```ruby
691
+ config.fog_credentials = { ... } # Provider specific credentials
692
+ ```
693
+
524
694
  ## Using Amazon S3
525
695
 
526
- [Fog](http://github.com/fog/fog) is used to support Amazon S3. Ensure you have it in your Gemfile:
696
+ [Fog AWS](http://github.com/fog/fog-aws) is used to support Amazon S3. Ensure you have it in your Gemfile:
527
697
 
528
698
  ```ruby
529
- gem "fog", "~> 1.3.1"
699
+ gem "fog-aws"
530
700
  ```
531
701
 
532
702
  You'll need to provide your fog_credentials and a fog_directory (also known as a bucket) in an initializer.
533
- For the sake of performance it is assumed that the directory already exists, so please create it if need be.
703
+ For the sake of performance it is assumed that the directory already exists, so please create it if it needs to be.
534
704
  You can also pass in additional options, as documented fully in lib/carrierwave/storage/fog.rb. Here's a full example:
535
705
 
536
706
  ```ruby
537
707
  CarrierWave.configure do |config|
538
708
  config.fog_credentials = {
539
- :provider => 'AWS', # required
540
- :aws_access_key_id => 'xxx', # required
541
- :aws_secret_access_key => 'yyy', # required
542
- :region => 'eu-west-1', # optional, defaults to 'us-east-1'
543
- :host => 's3.example.com', # optional, defaults to nil
544
- :endpoint => 'https://s3.example.com:8080' # optional, defaults to nil
709
+ provider: 'AWS', # 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
713
+ region: 'eu-west-1', # optional, defaults to 'us-east-1'
714
+ host: 's3.example.com', # optional, defaults to nil
715
+ endpoint: 'https://s3.example.com:8080' # optional, defaults to nil
545
716
  }
546
- config.fog_directory = 'name_of_directory' # required
547
- config.fog_public = false # optional, defaults to true
548
- config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
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 {}
549
720
  end
550
721
  ```
551
722
 
@@ -559,12 +730,20 @@ end
559
730
 
560
731
  That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
561
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
+
562
741
  ## Using Rackspace Cloud Files
563
742
 
564
743
  [Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
565
744
 
566
745
  ```ruby
567
- gem "fog", "~> 1.10.1"
746
+ gem "fog"
568
747
  ```
569
748
 
570
749
  You'll need to configure a directory (also known as a container), username and API key in the initializer.
@@ -575,10 +754,10 @@ Using a US-based account:
575
754
  ```ruby
576
755
  CarrierWave.configure do |config|
577
756
  config.fog_credentials = {
578
- :provider => 'Rackspace',
579
- :rackspace_username => 'xxxxxx',
580
- :rackspace_api_key => 'yyyyyy',
581
- :rackspace_region => :ord # optional, defaults to :dfw
757
+ provider: 'Rackspace',
758
+ rackspace_username: 'xxxxxx',
759
+ rackspace_api_key: 'yyyyyy',
760
+ rackspace_region: :ord # optional, defaults to :dfw
582
761
  }
583
762
  config.fog_directory = 'name_of_directory'
584
763
  end
@@ -589,11 +768,11 @@ Using a UK-based account:
589
768
  ```ruby
590
769
  CarrierWave.configure do |config|
591
770
  config.fog_credentials = {
592
- :provider => 'Rackspace',
593
- :rackspace_username => 'xxxxxx',
594
- :rackspace_api_key => 'yyyyyy',
595
- :rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
596
- :rackspace_region => :lon
771
+ provider: 'Rackspace',
772
+ rackspace_username: 'xxxxxx',
773
+ rackspace_api_key: 'yyyyyy',
774
+ rackspace_auth_url: Fog::Rackspace::UK_AUTH_ENDPOINT,
775
+ rackspace_region: :lon
597
776
  }
598
777
  config.fog_directory = 'name_of_directory'
599
778
  end
@@ -620,25 +799,26 @@ the url to the file on Rackspace Cloud Files.
620
799
 
621
800
  ## Using Google Storage for Developers
622
801
 
623
- [Fog](http://github.com/fog/fog) is used to support Google Storage for Developers. Ensure you have it in your Gemfile:
802
+ [Fog](http://github.com/fog/fog-google) is used to support Google Storage for Developers. Ensure you have it in your Gemfile:
624
803
 
625
804
  ```ruby
626
- gem "fog", "~> 1.3.1"
805
+ gem "fog-google"
806
+ gem "google-api-client", "> 0.8.5", "< 0.9"
807
+ gem "mime-types"
627
808
  ```
628
809
 
629
810
  You'll need to configure a directory (also known as a bucket), access key id and secret access key in the initializer.
630
811
  For the sake of performance it is assumed that the directory already exists, so please create it if need be.
631
812
 
632
- Sign up [here](http://gs-signup-redirect.appspot.com/) and get your credentials [here](https://storage.cloud.google.com/m)
633
- under the section “Interoperable Access”.
813
+ Please read the [fog-google README](https://github.com/fog/fog-google/blob/master/README.md) on how to get credentials.
634
814
 
635
815
 
636
816
  ```ruby
637
817
  CarrierWave.configure do |config|
638
818
  config.fog_credentials = {
639
- :provider => 'Google',
640
- :google_storage_access_key_id => 'xxxxxx',
641
- :google_storage_secret_access_key => 'yyyyyy'
819
+ provider: 'Google',
820
+ google_storage_access_key_id: 'xxxxxx',
821
+ google_storage_secret_access_key: 'yyyyyy'
642
822
  }
643
823
  config.fog_directory = 'name_of_directory'
644
824
  end
@@ -655,6 +835,31 @@ end
655
835
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
656
836
  the url to the file on Google.
657
837
 
838
+ ## Optimized Loading of Fog
839
+
840
+ Since Carrierwave doesn't know which parts of Fog you intend to use, it will just load the entire library (unless you use e.g. [`fog-aws`, `fog-google`] instead of fog proper). If you prefer to load fewer classes into your application, you need to load those parts of Fog yourself *before* loading CarrierWave in your Gemfile. Ex:
841
+
842
+ ```ruby
843
+ gem "fog", "~> 1.27", require: "fog/rackspace/storage"
844
+ gem "carrierwave"
845
+ ```
846
+
847
+ A couple of notes about versions:
848
+ * This functionality was introduced in Fog v1.20.
849
+ * This functionality is slated for CarrierWave v1.0.0.
850
+
851
+ If you're not relying on Gemfile entries alone and are requiring "carrierwave" anywhere, ensure you require "fog/rackspace/storage" before it. Ex:
852
+
853
+ ```ruby
854
+ require "fog/rackspace/storage"
855
+ require "carrierwave"
856
+ ```
857
+
858
+ Beware that this specific require is only needed when working with a fog provider that was not extracted to its own gem yet.
859
+ A list of the extracted providers can be found in the page of the `fog` organizations [here](https://github.com/fog).
860
+
861
+ When in doubt, inspect `Fog.constants` to see what has been loaded.
862
+
658
863
  ## Dynamic Asset Host
659
864
 
660
865
  The `asset_host` config property can be assigned a proc (or anything that responds to `call`) for generating the host dynamically. The proc-compliant object gets an instance of the current `CarrierWave::Storage::Fog::File` or `CarrierWave::SanitizedFile` as its only argument.
@@ -692,11 +897,11 @@ Convert will only work if the file has the same file extension, thus the use of
692
897
  class AvatarUploader < CarrierWave::Uploader::Base
693
898
  include CarrierWave::RMagick
694
899
 
695
- process :resize_to_fill => [200, 200]
696
- process :convert => 'png'
900
+ process resize_to_fill: [200, 200]
901
+ process convert: 'png'
697
902
 
698
903
  def filename
699
- super.chomp(File.extname(super)) + '.png'
904
+ super.chomp(File.extname(super)) + '.png' if original_filename.present?
700
905
  end
701
906
  end
702
907
  ```
@@ -706,8 +911,8 @@ manipulation methods.
706
911
 
707
912
  ## Using MiniMagick
708
913
 
709
- MiniMagick is similar to RMagick but performs all the operations using the 'mogrify'
710
- command which is part of the standard ImageMagick kit. This allows you to have the power
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
711
916
  of ImageMagick without having to worry about installing all the RMagick libraries.
712
917
 
713
918
  See the MiniMagick site for more details:
@@ -725,7 +930,7 @@ for the RMagick processor.
725
930
  class AvatarUploader < CarrierWave::Uploader::Base
726
931
  include CarrierWave::MiniMagick
727
932
 
728
- process :resize_to_fill => [200, 200]
933
+ process resize_to_fill: [200, 200]
729
934
  end
730
935
  ```
731
936
 
@@ -745,26 +950,33 @@ details.
745
950
  Be sure to use mount_on to specify the correct column:
746
951
 
747
952
  ```ruby
748
- mount_uploader :avatar, AvatarUploader, :mount_on => :avatar_file_name
953
+ mount_uploader :avatar, AvatarUploader, mount_on: :avatar_file_name
749
954
  ```
750
955
 
751
- Unfortunately attachment_fu differs too much in philosophy for there to be a
752
- sensible compatibility mode. Patches for migrating from other solutions will be
753
- happily accepted.
956
+ ## I18n
754
957
 
755
- ## i18n
756
-
757
- The Active Record validations use the Rails i18n framework. Add these keys to
958
+ The Active Record validations use the Rails `i18n` framework. Add these keys to
758
959
  your translations file:
759
960
 
760
961
  ```yaml
761
962
  errors:
762
963
  messages:
763
- carrierwave_processing_error: "Cannot resize image."
764
- carrierwave_integrity_error: "Not an image."
765
- carrierwave_download_error: "Couldn't download image."
964
+ carrierwave_processing_error: failed to be processed
965
+ carrierwave_integrity_error: is not of an allowed file type
966
+ carrierwave_download_error: could not be downloaded
967
+ extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
968
+ extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
969
+ content_type_whitelist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
970
+ content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
971
+ rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
972
+ mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
973
+ min_size_error: "File size should be greater than %{min_size}"
974
+ max_size_error: "File size should be less than %{max_size}"
766
975
  ```
767
976
 
977
+ The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
978
+ library adds support for additional locales.
979
+
768
980
  ## Large files
769
981
 
770
982
  By default, CarrierWave copies an uploaded file twice, first copying the file into the cache, then
@@ -778,6 +990,7 @@ class MyUploader < CarrierWave::Uploader::Base
778
990
  def move_to_cache
779
991
  true
780
992
  end
993
+
781
994
  def move_to_store
782
995
  true
783
996
  end
@@ -788,13 +1001,46 @@ When the `move_to_cache` and/or `move_to_store` methods return true, files will
788
1001
 
789
1002
  This has only been tested with the local filesystem store.
790
1003
 
1004
+ ## Skipping ActiveRecord callbacks
1005
+
1006
+ By default, mounting an uploader into an ActiveRecord model will add a few
1007
+ callbacks. For example, this code:
1008
+
1009
+ ```ruby
1010
+ class User
1011
+ mount_uploader :avatar, AvatarUploader
1012
+ end
1013
+ ```
1014
+
1015
+ Will add these callbacks:
1016
+
1017
+ ```ruby
1018
+ after_save :store_avatar!
1019
+ before_save :write_avatar_identifier
1020
+ after_commit :remove_avatar!, on: :destroy
1021
+ after_commit :mark_remove_avatar_false, on: :update
1022
+ after_save :store_previous_changes_for_avatar
1023
+ after_commit :remove_previously_stored_avatar, on: :update
1024
+ ```
1025
+
1026
+ If you want to skip any of these callbacks (eg. you want to keep the existing
1027
+ avatar, even after uploading a new one), you can use ActiveRecord’s
1028
+ `skip_callback` method.
1029
+
1030
+ ```ruby
1031
+ class User
1032
+ mount_uploader :avatar, AvatarUploader
1033
+ skip_callback :commit, :after, :remove_previously_stored_avatar
1034
+ end
1035
+ ```
1036
+
791
1037
  ## Contributing to CarrierWave
792
1038
 
793
1039
  See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
794
1040
 
795
1041
  ## License
796
1042
 
797
- Copyright (c) 2008-2013 Jonas Nicklas
1043
+ Copyright (c) 2008-2015 Jonas Nicklas
798
1044
 
799
1045
  Permission is hereby granted, free of charge, to any person obtaining
800
1046
  a copy of this software and associated documentation files (the