carrierwave 0.10.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.

Potentially problematic release.


This version of carrierwave might be problematic. Click here for more details.

Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +307 -121
  3. data/lib/carrierwave/compatibility/paperclip.rb +0 -2
  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 +229 -180
  9. data/lib/carrierwave/mounter.rb +188 -0
  10. data/lib/carrierwave/orm/activerecord.rb +59 -24
  11. data/lib/carrierwave/processing/mini_magick.rb +137 -83
  12. data/lib/carrierwave/processing/rmagick.rb +65 -8
  13. data/lib/carrierwave/processing.rb +0 -1
  14. data/lib/carrierwave/sanitized_file.rb +67 -32
  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 +177 -39
  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 +71 -13
  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 +4 -74
  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 +10 -10
  32. data/lib/carrierwave/uploader/proxy.rb +6 -8
  33. data/lib/carrierwave/uploader/remove.rb +0 -2
  34. data/lib/carrierwave/uploader/serialization.rb +2 -4
  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 +123 -93
  38. data/lib/carrierwave/uploader.rb +6 -2
  39. data/lib/carrierwave/utilities/uri.rb +5 -6
  40. data/lib/carrierwave/utilities.rb +0 -3
  41. data/lib/carrierwave/validations/active_model.rb +3 -5
  42. data/lib/carrierwave/version.rb +1 -1
  43. data/lib/carrierwave.rb +34 -8
  44. data/lib/generators/templates/uploader.rb +4 -8
  45. metadata +130 -57
  46. data/lib/carrierwave/locale/cs.yml +0 -11
  47. data/lib/carrierwave/locale/de.yml +0 -11
  48. data/lib/carrierwave/locale/el.yml +0 -11
  49. data/lib/carrierwave/locale/es.yml +0 -11
  50. data/lib/carrierwave/locale/fr.yml +0 -11
  51. data/lib/carrierwave/locale/ja.yml +0 -11
  52. data/lib/carrierwave/locale/nb.yml +0 -11
  53. data/lib/carrierwave/locale/nl.yml +0 -11
  54. data/lib/carrierwave/locale/pl.yml +0 -11
  55. data/lib/carrierwave/locale/pt-BR.yml +0 -11
  56. data/lib/carrierwave/locale/pt-PT.yml +0 -11
  57. data/lib/carrierwave/locale/ru.yml +0 -11
  58. data/lib/carrierwave/locale/sk.yml +0 -11
  59. data/lib/carrierwave/locale/tr.yml +0 -11
  60. data/lib/carrierwave/processing/mime_types.rb +0 -74
  61. data/lib/carrierwave/utilities/deprecation.rb +0 -18
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://travis-ci.org/carrierwaveuploader/carrierwave.png?branch=master)](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,24 +104,103 @@ 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:
114
126
 
115
127
  * [carrierwave-datamapper](https://github.com/carrierwaveuploader/carrierwave-datamapper)
116
128
  * [carrierwave-mongoid](https://github.com/carrierwaveuploader/carrierwave-mongoid)
117
- * [carrierwave-sequel](https://github.com/jnicklas/carrierwave-sequel)
129
+ * [carrierwave-sequel](https://github.com/carrierwaveuploader/carrierwave-sequel)
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,69 +229,85 @@ 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.
196
-
197
- ```ruby
198
- require 'carrierwave/processing/mime_types'
199
-
200
- class MyUploader < CarrierWave::Uploader::Base
201
- include CarrierWave::MimeTypes
202
-
203
- process :set_content_type
204
- end
205
- ```
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.
206
305
 
207
306
  ## Adding versions
208
307
 
209
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*:
210
309
 
211
- *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.
310
+ *Note:* You must have Imagemagick installed to do image resizing.
212
311
 
213
312
  Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
214
313
 
@@ -222,30 +321,48 @@ $ brew install imagemagick
222
321
  class MyUploader < CarrierWave::Uploader::Base
223
322
  include CarrierWave::MiniMagick
224
323
 
225
- process :resize_to_fit => [800, 800]
324
+ process resize_to_fit: [800, 800]
226
325
 
227
326
  version :thumb do
228
- process :resize_to_fill => [200,200]
327
+ process resize_to_fill: [200,200]
229
328
  end
230
329
 
231
330
  end
232
331
  ```
233
332
 
234
333
  When this uploader is used, an uploaded image would be scaled to be no larger
235
- than 800 by 800 pixels. A version called thumb is then created, which is scaled
236
- 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:
237
342
 
238
343
  ```ruby
239
344
  uploader = AvatarUploader.new
240
345
  uploader.store!(my_file) # size: 1024x768
241
346
 
242
- uploader.url # => '/url/to/my_file.png' # size: 800x600
347
+ uploader.url # => '/url/to/my_file.png' # size: 800x800
243
348
  uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
244
349
  ```
245
350
 
246
351
  One important thing to remember is that process is called *before* versions are
247
352
  created. This can cut down on processing cost.
248
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
+
249
366
  It is possible to nest versions within versions:
250
367
 
251
368
  ```ruby
@@ -267,11 +384,11 @@ properties within the model or based on the picture itself.
267
384
  ```ruby
268
385
  class MyUploader < CarrierWave::Uploader::Base
269
386
 
270
- version :human, :if => :is_human?
271
- version :monkey, :if => :is_monkey?
272
- version :banner, :if => :is_landscape?
387
+ version :human, if: :is_human?
388
+ version :monkey, if: :is_monkey?
389
+ version :banner, if: :is_landscape?
273
390
 
274
- protected
391
+ private
275
392
 
276
393
  def is_human? picture
277
394
  model.can_program?(:ruby)
@@ -282,7 +399,7 @@ protected
282
399
  end
283
400
 
284
401
  def is_landscape? picture
285
- image = MiniMagick::Image.open(picture.path)
402
+ image = MiniMagick::Image.new(picture.path)
286
403
  image[:width] > image[:height]
287
404
  end
288
405
 
@@ -305,7 +422,7 @@ class MyUploader < CarrierWave::Uploader::Base
305
422
  process resize_to_fill: [280, 280]
306
423
  end
307
424
 
308
- version :small_thumb, :from_version => :thumb do
425
+ version :small_thumb, from_version: :thumb do
309
426
  process resize_to_fill: [20, 20]
310
427
  end
311
428
 
@@ -324,7 +441,7 @@ file, just add a hidden field called `avatar_cache` (don't forget to add it to
324
441
  the attr_accessible list as necessary). In Rails, this would look like this:
325
442
 
326
443
  ```erb
327
- <%= form_for @user, :html => {:multipart => true} do |f| %>
444
+ <%= form_for @user, html: { multipart: true } do |f| %>
328
445
  <p>
329
446
  <label>My Avatar</label>
330
447
  <%= f.file_field :avatar %>
@@ -337,7 +454,7 @@ It might be a good idea to show the user that a file has been uploaded, in the
337
454
  case of images, a small thumbnail would be a good indicator:
338
455
 
339
456
  ```erb
340
- <%= form_for @user, :html => {:multipart => true} do |f| %>
457
+ <%= form_for @user, html: { multipart: true } do |f| %>
341
458
  <p>
342
459
  <label>My Avatar</label>
343
460
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -353,7 +470,7 @@ If you want to remove a previously uploaded file on a mounted uploader, you can
353
470
  easily add a checkbox to the form which will remove the file when checked.
354
471
 
355
472
  ```erb
356
- <%= form_for @user, :html => {:multipart => true} do |f| %>
473
+ <%= form_for @user, html: { multipart: true } do |f| %>
357
474
  <p>
358
475
  <label>My Avatar</label>
359
476
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -384,7 +501,7 @@ via a URL. CarrierWave makes this simple, just add the appropriate attribute to
384
501
  form and you're good to go:
385
502
 
386
503
  ```erb
387
- <%= form_for @user, :html => {:multipart => true} do |f| %>
504
+ <%= form_for @user, html: { multipart: true } do |f| %>
388
505
  <p>
389
506
  <label>My Avatar URL:</label>
390
507
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -406,7 +523,7 @@ this easily by overriding the `default_url` method in your uploader:
406
523
 
407
524
  ```ruby
408
525
  class MyUploader < CarrierWave::Uploader::Base
409
- def default_url
526
+ def default_url(*args)
410
527
  "/images/fallback/" + [version_name, "default.png"].compact.join('_')
411
528
  end
412
529
  end
@@ -416,7 +533,7 @@ Or if you are using the Rails asset pipeline:
416
533
 
417
534
  ```ruby
418
535
  class MyUploader < CarrierWave::Uploader::Base
419
- def default_url
536
+ def default_url(*args)
420
537
  ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
421
538
  end
422
539
  end
@@ -443,7 +560,7 @@ instance.recreate_versions!(:thumb, :large)
443
560
  Or on a mounted uploader:
444
561
 
445
562
  ```ruby
446
- User.all.each do |user|
563
+ User.find_each do |user|
447
564
  user.avatar.recreate_versions!
448
565
  end
449
566
  ```
@@ -451,7 +568,7 @@ end
451
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:
452
569
 
453
570
  ```ruby
454
- User.all.each do |user|
571
+ User.find_each do |user|
455
572
  user.avatar.recreate_versions! if user.avatar?
456
573
  end
457
574
  ```
@@ -481,6 +598,16 @@ If you're using Rails, create an initializer for this:
481
598
 
482
599
  config/initializers/carrierwave.rb
483
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
+
484
611
 
485
612
  ## Testing with CarrierWave
486
613
 
@@ -511,35 +638,43 @@ require 'carrierwave/test/matchers'
511
638
  describe MyUploader do
512
639
  include CarrierWave::Test::Matchers
513
640
 
641
+ let(:user) { double('user') }
642
+ let(:uploader) { MyUploader.new(user, :avatar) }
643
+
514
644
  before do
515
645
  MyUploader.enable_processing = true
516
- @uploader = MyUploader.new(@user, :avatar)
517
- @uploader.store!(File.open(path_to_file))
646
+ File.open(path_to_file) { |f| uploader.store!(f) }
518
647
  end
519
648
 
520
649
  after do
521
650
  MyUploader.enable_processing = false
522
- @uploader.remove!
651
+ uploader.remove!
523
652
  end
524
653
 
525
654
  context 'the thumb version' do
526
- it "should scale down a landscape image to be exactly 64 by 64 pixels" do
527
- @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)
528
657
  end
529
658
  end
530
659
 
531
660
  context 'the small version' do
532
- it "should scale down a landscape image to fit within 200 by 200 pixels" do
533
- @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)
534
663
  end
535
664
  end
536
665
 
537
- it "should make the image readable only to the owner and not executable" do
538
- @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')
539
672
  end
540
673
  end
541
674
  ```
542
675
 
676
+ If you're looking for minitest asserts, checkout [carrierwave_asserts](https://github.com/hcfairbanks/carrierwave_asserts).
677
+
543
678
  Setting the enable_processing flag on an uploader will prevent any of the versions from processing as well.
544
679
  Processing can be enabled for a single version by setting the processing flag on the version like so:
545
680
 
@@ -547,31 +682,41 @@ Processing can be enabled for a single version by setting the processing flag on
547
682
  @uploader.thumb.enable_processing = true
548
683
  ```
549
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
+
550
694
  ## Using Amazon S3
551
695
 
552
- [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:
553
697
 
554
698
  ```ruby
555
- gem "fog", "~> 1.3.1"
699
+ gem "fog-aws"
556
700
  ```
557
701
 
558
702
  You'll need to provide your fog_credentials and a fog_directory (also known as a bucket) in an initializer.
559
- 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.
560
704
  You can also pass in additional options, as documented fully in lib/carrierwave/storage/fog.rb. Here's a full example:
561
705
 
562
706
  ```ruby
563
707
  CarrierWave.configure do |config|
564
708
  config.fog_credentials = {
565
- :provider => 'AWS', # required
566
- :aws_access_key_id => 'xxx', # required
567
- :aws_secret_access_key => 'yyy', # required
568
- :region => 'eu-west-1', # optional, defaults to 'us-east-1'
569
- :host => 's3.example.com', # optional, defaults to nil
570
- :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
571
716
  }
572
- config.fog_directory = 'name_of_directory' # required
573
- config.fog_public = false # optional, defaults to true
574
- 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 {}
575
720
  end
576
721
  ```
577
722
 
@@ -585,6 +730,14 @@ end
585
730
 
586
731
  That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
587
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
+
588
741
  ## Using Rackspace Cloud Files
589
742
 
590
743
  [Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
@@ -601,10 +754,10 @@ Using a US-based account:
601
754
  ```ruby
602
755
  CarrierWave.configure do |config|
603
756
  config.fog_credentials = {
604
- :provider => 'Rackspace',
605
- :rackspace_username => 'xxxxxx',
606
- :rackspace_api_key => 'yyyyyy',
607
- :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
608
761
  }
609
762
  config.fog_directory = 'name_of_directory'
610
763
  end
@@ -615,11 +768,11 @@ Using a UK-based account:
615
768
  ```ruby
616
769
  CarrierWave.configure do |config|
617
770
  config.fog_credentials = {
618
- :provider => 'Rackspace',
619
- :rackspace_username => 'xxxxxx',
620
- :rackspace_api_key => 'yyyyyy',
621
- :rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
622
- :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
623
776
  }
624
777
  config.fog_directory = 'name_of_directory'
625
778
  end
@@ -646,25 +799,26 @@ the url to the file on Rackspace Cloud Files.
646
799
 
647
800
  ## Using Google Storage for Developers
648
801
 
649
- [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:
650
803
 
651
804
  ```ruby
652
- gem "fog"
805
+ gem "fog-google"
806
+ gem "google-api-client", "> 0.8.5", "< 0.9"
807
+ gem "mime-types"
653
808
  ```
654
809
 
655
810
  You'll need to configure a directory (also known as a bucket), access key id and secret access key in the initializer.
656
811
  For the sake of performance it is assumed that the directory already exists, so please create it if need be.
657
812
 
658
- Sign up [here](http://gs-signup-redirect.appspot.com/) and get your credentials [here](https://storage.cloud.google.com/m)
659
- 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.
660
814
 
661
815
 
662
816
  ```ruby
663
817
  CarrierWave.configure do |config|
664
818
  config.fog_credentials = {
665
- :provider => 'Google',
666
- :google_storage_access_key_id => 'xxxxxx',
667
- :google_storage_secret_access_key => 'yyyyyy'
819
+ provider: 'Google',
820
+ google_storage_access_key_id: 'xxxxxx',
821
+ google_storage_secret_access_key: 'yyyyyy'
668
822
  }
669
823
  config.fog_directory = 'name_of_directory'
670
824
  end
@@ -681,6 +835,31 @@ end
681
835
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
682
836
  the url to the file on Google.
683
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
+
684
863
  ## Dynamic Asset Host
685
864
 
686
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.
@@ -718,8 +897,8 @@ Convert will only work if the file has the same file extension, thus the use of
718
897
  class AvatarUploader < CarrierWave::Uploader::Base
719
898
  include CarrierWave::RMagick
720
899
 
721
- process :resize_to_fill => [200, 200]
722
- process :convert => 'png'
900
+ process resize_to_fill: [200, 200]
901
+ process convert: 'png'
723
902
 
724
903
  def filename
725
904
  super.chomp(File.extname(super)) + '.png' if original_filename.present?
@@ -732,8 +911,8 @@ manipulation methods.
732
911
 
733
912
  ## Using MiniMagick
734
913
 
735
- MiniMagick is similar to RMagick but performs all the operations using the 'mogrify'
736
- 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
737
916
  of ImageMagick without having to worry about installing all the RMagick libraries.
738
917
 
739
918
  See the MiniMagick site for more details:
@@ -751,7 +930,7 @@ for the RMagick processor.
751
930
  class AvatarUploader < CarrierWave::Uploader::Base
752
931
  include CarrierWave::MiniMagick
753
932
 
754
- process :resize_to_fill => [200, 200]
933
+ process resize_to_fill: [200, 200]
755
934
  end
756
935
  ```
757
936
 
@@ -771,28 +950,33 @@ details.
771
950
  Be sure to use mount_on to specify the correct column:
772
951
 
773
952
  ```ruby
774
- mount_uploader :avatar, AvatarUploader, :mount_on => :avatar_file_name
953
+ mount_uploader :avatar, AvatarUploader, mount_on: :avatar_file_name
775
954
  ```
776
955
 
777
- Unfortunately attachment_fu differs too much in philosophy for there to be a
778
- sensible compatibility mode. Patches for migrating from other solutions will be
779
- happily accepted.
956
+ ## I18n
780
957
 
781
- ## i18n
782
-
783
- 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
784
959
  your translations file:
785
960
 
786
961
  ```yaml
787
962
  errors:
788
963
  messages:
789
- carrierwave_processing_error: "Cannot resize image."
790
- carrierwave_integrity_error: "Not an image."
791
- carrierwave_download_error: "Couldn't download image."
792
- extension_white_list_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
793
- extension_black_list_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
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}"
794
975
  ```
795
976
 
977
+ The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
978
+ library adds support for additional locales.
979
+
796
980
  ## Large files
797
981
 
798
982
  By default, CarrierWave copies an uploaded file twice, first copying the file into the cache, then
@@ -806,6 +990,7 @@ class MyUploader < CarrierWave::Uploader::Base
806
990
  def move_to_cache
807
991
  true
808
992
  end
993
+
809
994
  def move_to_store
810
995
  true
811
996
  end
@@ -832,9 +1017,10 @@ Will add these callbacks:
832
1017
  ```ruby
833
1018
  after_save :store_avatar!
834
1019
  before_save :write_avatar_identifier
835
- after_commit :remove_avatar! :on => :destroy
836
- before_update :store_previous_model_for_avatar
837
- after_save :remove_previously_stored_avatar
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
838
1024
  ```
839
1025
 
840
1026
  If you want to skip any of these callbacks (eg. you want to keep the existing
@@ -844,7 +1030,7 @@ avatar, even after uploading a new one), you can use ActiveRecord’s
844
1030
  ```ruby
845
1031
  class User
846
1032
  mount_uploader :avatar, AvatarUploader
847
- skip_callback :save, :after, :remove_previously_stored_avatar
1033
+ skip_callback :commit, :after, :remove_previously_stored_avatar
848
1034
  end
849
1035
  ```
850
1036
 
@@ -854,7 +1040,7 @@ See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/ma
854
1040
 
855
1041
  ## License
856
1042
 
857
- Copyright (c) 2008-2013 Jonas Nicklas
1043
+ Copyright (c) 2008-2015 Jonas Nicklas
858
1044
 
859
1045
  Permission is hereby granted, free of charge, to any person obtaining
860
1046
  a copy of this software and associated documentation files (the