carrierwave-rails3 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/README.rdoc +527 -0
  2. data/lib/carrierwave.rb +103 -0
  3. data/lib/carrierwave/compatibility/paperclip.rb +95 -0
  4. data/lib/carrierwave/core_ext/file.rb +11 -0
  5. data/lib/carrierwave/mount.rb +359 -0
  6. data/lib/carrierwave/orm/activerecord.rb +75 -0
  7. data/lib/carrierwave/orm/datamapper.rb +27 -0
  8. data/lib/carrierwave/orm/mongoid.rb +23 -0
  9. data/lib/carrierwave/orm/mongomapper.rb +27 -0
  10. data/lib/carrierwave/orm/sequel.rb +45 -0
  11. data/lib/carrierwave/processing/image_science.rb +116 -0
  12. data/lib/carrierwave/processing/mini_magick.rb +261 -0
  13. data/lib/carrierwave/processing/rmagick.rb +278 -0
  14. data/lib/carrierwave/sanitized_file.rb +273 -0
  15. data/lib/carrierwave/storage/abstract.rb +30 -0
  16. data/lib/carrierwave/storage/cloud_files.rb +169 -0
  17. data/lib/carrierwave/storage/file.rb +48 -0
  18. data/lib/carrierwave/storage/grid_fs.rb +104 -0
  19. data/lib/carrierwave/storage/right_s3.rb +3 -0
  20. data/lib/carrierwave/storage/s3.rb +206 -0
  21. data/lib/carrierwave/test/matchers.rb +164 -0
  22. data/lib/carrierwave/uploader.rb +44 -0
  23. data/lib/carrierwave/uploader/cache.rb +146 -0
  24. data/lib/carrierwave/uploader/callbacks.rb +41 -0
  25. data/lib/carrierwave/uploader/configuration.rb +134 -0
  26. data/lib/carrierwave/uploader/default_url.rb +19 -0
  27. data/lib/carrierwave/uploader/download.rb +60 -0
  28. data/lib/carrierwave/uploader/extension_whitelist.rb +38 -0
  29. data/lib/carrierwave/uploader/mountable.rb +39 -0
  30. data/lib/carrierwave/uploader/processing.rb +84 -0
  31. data/lib/carrierwave/uploader/proxy.rb +62 -0
  32. data/lib/carrierwave/uploader/remove.rb +23 -0
  33. data/lib/carrierwave/uploader/store.rb +90 -0
  34. data/lib/carrierwave/uploader/url.rb +33 -0
  35. data/lib/carrierwave/uploader/versions.rb +147 -0
  36. data/lib/generators/templates/uploader.rb +47 -0
  37. data/lib/generators/uploader_generator.rb +13 -0
  38. data/spec/compatibility/paperclip_spec.rb +52 -0
  39. data/spec/mount_spec.rb +538 -0
  40. data/spec/orm/activerecord_spec.rb +271 -0
  41. data/spec/orm/datamapper_spec.rb +168 -0
  42. data/spec/orm/mongoid_spec.rb +202 -0
  43. data/spec/orm/mongomapper_spec.rb +202 -0
  44. data/spec/orm/sequel_spec.rb +183 -0
  45. data/spec/processing/image_science_spec.rb +56 -0
  46. data/spec/processing/mini_magick_spec.rb +76 -0
  47. data/spec/processing/rmagick_spec.rb +75 -0
  48. data/spec/sanitized_file_spec.rb +623 -0
  49. data/spec/spec_helper.rb +92 -0
  50. data/spec/storage/cloudfiles_spec.rb +78 -0
  51. data/spec/storage/grid_fs_spec.rb +86 -0
  52. data/spec/storage/s3_spec.rb +118 -0
  53. data/spec/uploader/cache_spec.rb +209 -0
  54. data/spec/uploader/callback_spec.rb +24 -0
  55. data/spec/uploader/configuration_spec.rb +105 -0
  56. data/spec/uploader/default_url_spec.rb +85 -0
  57. data/spec/uploader/download_spec.rb +75 -0
  58. data/spec/uploader/extension_whitelist_spec.rb +44 -0
  59. data/spec/uploader/mountable_spec.rb +33 -0
  60. data/spec/uploader/paths_spec.rb +22 -0
  61. data/spec/uploader/processing_spec.rb +73 -0
  62. data/spec/uploader/proxy_spec.rb +54 -0
  63. data/spec/uploader/remove_spec.rb +70 -0
  64. data/spec/uploader/store_spec.rb +264 -0
  65. data/spec/uploader/url_spec.rb +102 -0
  66. data/spec/uploader/versions_spec.rb +298 -0
  67. metadata +128 -0
@@ -0,0 +1,527 @@
1
+ = CarrierWave
2
+
3
+ http://carrierwave.rubyforge.org
4
+
5
+ == Summary
6
+
7
+ This plugin for Merb and Rails provides a simple and extremely flexible way to
8
+ upload files.
9
+
10
+ == Description
11
+
12
+ * RDoc Documentation {available at Rubyforge}[http://carrierwave.rubyforge.org/rdoc].
13
+ * Source code {hosted at GitHub}[http://github.com/jnicklas/carrierwave]
14
+ * Please {report any issues}[http://github.com/jnicklas/carrierwave/issues] on GitHub
15
+ * Please direct any questions at the {mailing list}[http://groups.google.com/group/carrierwave]
16
+ * Check out the {example app}[http://github.com/jnicklas/carrierwave-example-app]
17
+
18
+ == Getting Started
19
+
20
+ Install the latest stable release:
21
+
22
+ [sudo] gem install carrierwave
23
+
24
+ In Merb, add it as a dependency to your config/dependencies.rb:
25
+
26
+ dependency 'carrierwave'
27
+
28
+ In Rails, add it to your environment.rb:
29
+
30
+ config.gem "carrierwave"
31
+
32
+ == Quick Start
33
+
34
+ Start off by generating an uploader:
35
+
36
+ merb-gen uploader Avatar
37
+
38
+ or in Rails:
39
+
40
+ script/generate uploader Avatar
41
+
42
+ this should give you a file in:
43
+
44
+ app/uploaders/avatar_uploader.rb
45
+
46
+ Check out this file for some hints on how you can customize your uploader. It
47
+ should look something like this:
48
+
49
+ class AvatarUploader < CarrierWave::Uploader::Base
50
+ storage :file
51
+ end
52
+
53
+ You can use your uploader class to store and retrieve files like this:
54
+
55
+ uploader = AvatarUploader.new
56
+
57
+ uploader.store!(my_file)
58
+
59
+ uploader.retrieve_from_store!('my_file.png')
60
+
61
+ CarrierWave gives you a +store+ for permanent storage, and a +cache+ for
62
+ temporary storage. You can use different stores, at the moment a filesystem
63
+ store, an Amazon S3 store, a Rackspace Cloud Files store, and a store for MongoDB's GridFS are bundled.
64
+
65
+ Most of the time you are going to want to use CarrierWave together with an ORM.
66
+ It is quite simple to mount uploaders on columns in your model, so you can
67
+ simply assign files and get going:
68
+
69
+ === ActiveRecord, DataMapper, Sequel, MongoMapper
70
+
71
+ Make sure you are loading CarrierWave after loading your ORM, otherwise you'll
72
+ need to require the relevant extension manually, e.g.:
73
+
74
+ require 'carrierwave/orm/activerecord'
75
+
76
+ Add a string column to the model you want to mount the uploader on:
77
+
78
+ add_column :user, :avatar, :string
79
+
80
+ Open your model file and mount the uploader:
81
+
82
+ class User
83
+ mount_uploader :avatar, AvatarUploader
84
+ end
85
+
86
+ This works the same with all supported ORMs.
87
+
88
+ Now you can cache files by assigning them to the attribute, they will
89
+ automatically be stored when the record is saved.
90
+
91
+ u = User.new
92
+ u.avatar = params[:file]
93
+ u.avatar = File.open('somewhere')
94
+ u.save!
95
+ u.avatar.url # => '/url/to/file.png'
96
+ u.avatar.current_path # => 'path/to/file.png'
97
+
98
+ == Changing the storage directory
99
+
100
+ In order to change where uploaded files are put, just override the +store_dir+
101
+ method:
102
+
103
+ class MyUploader < CarrierWave::Uploader::Base
104
+ def store_dir
105
+ 'public/my/upload/directory'
106
+ end
107
+ end
108
+
109
+ This works for the file storage as well as Amazon S3 and Rackspace Cloud Files.
110
+ Define +store_dir+ as +nil+ if you'd like to store files at the root level.
111
+
112
+ == Securing uploads
113
+
114
+ Certain file might be dangerous if uploaded to the wrong location, such as php files or other script files. CarrierWave allows you to specify a white-list of allowed extensions.
115
+
116
+ If you're mounting the uploader, uploading a file with the wrong extension will make the record invalid instead. Otherwise, an error is raised.
117
+
118
+ class MyUploader < CarrierWave::Uploader::Base
119
+ def extension_white_list
120
+ %w(jpg jpeg gif png)
121
+ end
122
+ end
123
+
124
+ == Adding versions
125
+
126
+ Often you'll want to add different versions of the same file. The classic
127
+ example is image thumbnails. There is built in support for this:
128
+
129
+ class MyUploader < CarrierWave::Uploader::Base
130
+ include CarrierWave::RMagick
131
+
132
+ process :resize_to_fit => [800, 800]
133
+
134
+ version :thumb do
135
+ process :resize_to_fill => [200,200]
136
+ end
137
+
138
+ end
139
+
140
+ When this uploader is used, an uploaded image would be scaled to be no larger
141
+ than 800 by 800 pixels. A version called thumb is then created, which is scaled
142
+ and cropped to exactly 200 by 200 pixels. The uploader could be used like this:
143
+
144
+ uploader = AvatarUploader.new
145
+ uploader.store!(my_file) # size: 1024x768
146
+
147
+ uploader.url # => '/url/to/my_file.png' # size: 800x600
148
+ uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
149
+
150
+ One important thing to remember is that process is called *before* versions are
151
+ created. This can cut down on processing cost.
152
+
153
+ It is possible to nest versions within versions:
154
+
155
+ class MyUploader < CarrierWave::Uploader::Base
156
+
157
+ version :animal do
158
+ version :human
159
+ version :monkey
160
+ version :llama
161
+ end
162
+ end
163
+
164
+ == Making uploads work across form redisplays
165
+
166
+ Often you'll notice that uploaded files disappear when a validation fails.
167
+ CarrierWave has a feature that makes it easy to remember the uploaded file even
168
+ in that case. Suppose your +user+ model has an uploader mounted on +avatar+
169
+ file, just add a hidden field called +avatar_cache+. In Rails, this would look
170
+ like this:
171
+
172
+ <% form_for @user, :html => {:multipart => true} do |f| %>
173
+ <p>
174
+ <label>My Avatar</label>
175
+ <%= f.file_field :avatar %>
176
+ <%= f.hidden_field :avatar_cache %>
177
+ </p>
178
+ <% end %>
179
+
180
+ It might be a good idea to show the user that a file has been uploaded, in the
181
+ case of images, a small thumbnail would be a good indicator:
182
+
183
+ <% form_for @user, :html => {:multipart => true} do |f| %>
184
+ <p>
185
+ <label>My Avatar</label>
186
+ <%= image_tag(@user.avatar_url) if @user.avatar? %>
187
+ <%= f.file_field :avatar %>
188
+ <%= f.hidden_field :avatar_cache %>
189
+ </p>
190
+ <% end %>
191
+
192
+ == Removing uploaded files
193
+
194
+ If you want to remove a previously uploaded file on a mounted uploader, you can
195
+ easily add a checkbox to the form which will remove the file when checked.
196
+
197
+ <% form_for @user, :html => {:multipart => true} do |f| %>
198
+ <p>
199
+ <label>My Avatar</label>
200
+ <%= image_tag(@user.avatar_url) if @user.avatar? %>
201
+ <%= f.file_field :avatar %>
202
+ </p>
203
+
204
+ <p>
205
+ <label>
206
+ <%= f.check_box :remove_avatar %>
207
+ Remove avatar
208
+ </label>
209
+ </p>
210
+ <% end %>
211
+
212
+ If you want to remove the file manually, you can call <code>remove_avatar!</code>.
213
+
214
+ == Uploading files from a remote location
215
+
216
+ Your users may find it convenient to upload a file from a location on the Internet
217
+ via a URL. CarrierWave makes this simple, just add the appropriate column to your
218
+ form and you're good to go:
219
+
220
+ <% form_for @user, :html => {:multipart => true} do |f| %>
221
+ <p>
222
+ <label>My Avatar URL:</label>
223
+ <%= image_tag(@user.avatar_url) if @user.avatar? %>
224
+ <%= f.text_field :remote_avatar_url %>
225
+ </p>
226
+ <% end %>
227
+
228
+ == Providing a default URL
229
+
230
+ In many cases, especially when working with images, it might be a good idea to
231
+ provide a default url, a fallback in case no file has been uploaded. You can do
232
+ this easily by overriding the +default_url+ method in your uploader:
233
+
234
+ class MyUploader < CarrierWave::Uploader::Base
235
+ def default_url
236
+ "/images/fallback/" + [version_name, "default.png"].compact.join('_')
237
+ end
238
+ end
239
+
240
+ == Configuring CarrierWave
241
+
242
+ CarrierWave has a broad range of configuration options, which you can configure,
243
+ both globally and on a per-uploader basis:
244
+
245
+ CarrierWave.configure do |config|
246
+ config.permissions = 0666
247
+ config.storage = :s3
248
+ end
249
+
250
+ Or alternatively:
251
+
252
+ class AvatarUploader < CarrierWave::Uploader::Base
253
+ permissions 0777
254
+ end
255
+
256
+ == Testing CarrierWave
257
+
258
+ It's a good idea to test you uploaders in isolation. In order to speed up your
259
+ tests, it's recommended to switch off processing in your tests, and to use the
260
+ file storage. In Rails you could do that by adding an initializer with:
261
+
262
+ if Rails.env.test? or Rails.env.cucumber?
263
+ CarrierWave.configure do |config|
264
+ config.storage = :file
265
+ config.enable_processing = false
266
+ end
267
+ end
268
+
269
+ If you need to test your processing, you should test it in isolation, and enable
270
+ processing only for those tests that need it.
271
+
272
+ CarrierWave comes with some RSpec matchers which you may find useful:
273
+
274
+ require 'carrierwave/test/matchers'
275
+
276
+ describe MyUploader do
277
+ before do
278
+ MyUploader.enable_processing = true
279
+ @uploader = MyUploader.new(@user, :avatar)
280
+ @uploader.store!(File.open(path_to_file))
281
+ end
282
+
283
+ after do
284
+ MyUploader.enable_processing = false
285
+ end
286
+
287
+ context 'the thumb version' do
288
+ it "should scale down a landscape image to be exactly 64 by 64 pixels" do
289
+ @uploader.thumb.should have_dimensions(64, 64)
290
+ end
291
+ end
292
+
293
+ context 'the small version' do
294
+ it "should scale down a landscape image to fit within 200 by 200 pixels" do
295
+ @uploader.small.should be_no_larger_than(200, 200)
296
+ end
297
+ end
298
+
299
+ it "should make the image readable only to the owner and not executable" do
300
+ @uploader.should have_permissions(0600)
301
+ end
302
+ end
303
+
304
+ == Using Amazon S3
305
+
306
+ Older versions of CarrierWave used the +aws-s3+ and +right_aws+ libraries. The Aws[http://github.com/appoxy/aws]
307
+ is now used meaning european buckets are supported out the box. Ensure you have it installed:
308
+
309
+ gem install aws
310
+
311
+ You'll need to configure a bucket, access id and secret key like this:
312
+
313
+ CarrierWave.configure do |config|
314
+ config.s3_access_key_id = 'xxxxxx'
315
+ config.s3_secret_access_key = 'xxxxxx'
316
+ config.s3_bucket = 'name_of_bucket'
317
+ end
318
+
319
+ Do this in an initializer in Rails, and in a +before_app_loads+ block in Merb.
320
+
321
+ And then in your uploader, set the storage to :s3
322
+
323
+ class AvatarUploader < CarrierWave::Uploader::Base
324
+ storage :s3
325
+ end
326
+
327
+ That's it! You can still use the <code>CarrierWave::Uploader#url</code> method to return
328
+ the url to the file on Amazon S3.
329
+
330
+
331
+ == Using Rackspace Cloud Files
332
+
333
+ Cloud Files support requires a {Rackspace Cloud}[http://rackspacecloud.com] username and API key.
334
+ You must also create a container for Carrierwave to use, and mark it public (publish it to the CDN)
335
+
336
+ CarrierWave.configure do |config|
337
+ config.cloud_files_username = 'xxxxxx'
338
+ config.cloud_files_api_key = 'xxxxxxxxxxxxxxxxxxxxx'
339
+ config.cloud_files_container = 'name_of_bucket'
340
+ end
341
+
342
+ Do this in an initializer in Rails, and in a +before_app_loads+ block in Merb.
343
+
344
+ And then in your uploader, set the storage to :cloud_files
345
+
346
+ class AvatarUploader < CarrierWave::Uploader::Base
347
+ storage :cloud_files
348
+ end
349
+
350
+ That's it! You can still use the <code>CarrierWave::Uploader#url</code> method to return
351
+ the url to the file on the Cloud Files CDN.
352
+
353
+ == Using MongoDB's GridFS store
354
+
355
+ You'll need to configure the database and host to use:
356
+
357
+ CarrierWave.configure do |config|
358
+ config.grid_fs_database = 'my_mongo_database'
359
+ config.grid_fs_host = 'mongo.example.com'
360
+ end
361
+
362
+ The defaults are 'carrierwave' and 'localhost'.
363
+
364
+ And then in your uploader, set the storage to <code>:grid_fs</code>:
365
+
366
+ class AvatarUploader < CarrierWave::Uploader::Base
367
+ storage :grid_fs
368
+ end
369
+
370
+ Since GridFS doesn't make the files available via HTTP, you'll need to stream
371
+ them yourself. In Rails for example, you could use the +send_data+ method. You
372
+ can tell CarrierWave the URL you will serve your images from, allowing it to
373
+ generate the correct URL, by setting eg:
374
+
375
+ CarrierWave.configure do |config|
376
+ config.grid_fs_access_url = "/image/show"
377
+ end
378
+
379
+ == Using RMagick
380
+
381
+ If you're uploading images, you'll probably want to manipulate them in some way,
382
+ you might want to create thumbnail images for example. CarrierWave comes with a
383
+ small library to make manipulating images with RMagick easier, you'll need to
384
+ include it in your Uploader:
385
+
386
+ class AvatarUploader < CarrierWave::Uploader::Base
387
+ include CarrierWave::RMagick
388
+ end
389
+
390
+ The RMagick module gives you a few methods, like
391
+ <code>CarrierWave::RMagick#resize_to_fill</code> which manipulate the image file in some
392
+ way. You can set a +process+ callback, which will call that method any time a
393
+ file is uploaded.
394
+
395
+ class AvatarUploader < CarrierWave::Uploader::Base
396
+ include CarrierWave::RMagick
397
+
398
+ process :resize_to_fill => [200, 200]
399
+ process :convert => 'png'
400
+
401
+ def filename
402
+ super + '.png'
403
+ end
404
+ end
405
+
406
+ Check out the manipulate! method, which makes it easy for you to write your own
407
+ manipulation methods.
408
+
409
+ == Using ImageScience
410
+
411
+ ImageScience works the same way as RMagick.
412
+
413
+ class AvatarUploader < CarrierWave::Uploader::Base
414
+ include CarrierWave::ImageScience
415
+
416
+ process :resize_to_fill => [200, 200]
417
+ end
418
+
419
+ == Using MiniMagick
420
+
421
+ MiniMagick is similar to RMagick but performs all the operations using the 'mogrify'
422
+ command which is part of the standard ImageMagick kit. This allows you to have the power
423
+ of ImageMagick without having to worry about installing all the RMagick libraries.
424
+
425
+ See the MiniMagick site for more details:
426
+
427
+ http://github.com/probablycorey/mini_magick
428
+
429
+ And the ImageMagick command line options for more for whats on offer:
430
+
431
+ http://www.imagemagick.org/script/command-line-options.php
432
+
433
+ Currently, the MiniMagick carrierwave processor provides exactly the same methods as
434
+ for the RMagick processor.
435
+
436
+ class AvatarUploader < CarrierWave::Uploader::Base
437
+ include CarrierWave::MiniMagick
438
+
439
+ process :resize_to_fill => [200, 200]
440
+ end
441
+
442
+ == Migrating
443
+
444
+ If you are using Paperclip, you can use the provided compatibility module:
445
+
446
+ class AvatarUploader < CarrierWave::Uploader::Base
447
+ include CarrierWave::Compatibility::Paperclip
448
+ end
449
+
450
+ See the documentation for <code>Paperclip::Compatibility::Paperclip</code> for more
451
+ detaills.
452
+
453
+ Be sure to use mount_on to specify the correct column:
454
+
455
+ mount_uploader :avatar, AvatarUploader, :mount_on => :avatar_file_name
456
+
457
+ Unfortunately AttachmentFoo differs too much in philosophy for there to be a
458
+ sensible compatibility mode. Patches for migrating from other solutions will be
459
+ happily accepted.
460
+
461
+ == i18n
462
+
463
+ The activerecord validations use the Rails i18n framework. Add these keys to
464
+ your translations file:
465
+
466
+ carrierwave:
467
+ errors:
468
+ integrity: 'Not an image.'
469
+ processing: 'Cannot resize image.'
470
+
471
+ == Contributors
472
+
473
+ These people have contributed their time and effort to CarrierWave:
474
+
475
+ * Jonas Nicklas
476
+ * Pavel Kunc
477
+ * Andrew Timberlake
478
+ * Durran Jordan
479
+ * Scott Motte
480
+ * Sho Fukamachi
481
+ * Sam Lown
482
+ * Dave Ott
483
+ * Quin Hoxie
484
+ * H. Wade Minter
485
+ * Trevor Turk
486
+ * Nicklas Ramhöj
487
+ * Matt Hooks
488
+ * Andreas Haller
489
+ * Lars Pind
490
+ * Ramon Soares
491
+
492
+ == License
493
+
494
+ Copyright (c) 2008 Jonas Nicklas
495
+
496
+ Permission is hereby granted, free of charge, to any person obtaining
497
+ a copy of this software and associated documentation files (the
498
+ "Software"), to deal in the Software without restriction, including
499
+ without limitation the rights to use, copy, modify, merge, publish,
500
+ distribute, sublicense, and/or sell copies of the Software, and to
501
+ permit persons to whom the Software is furnished to do so, subject to
502
+ the following conditions:
503
+
504
+ The above copyright notice and this permission notice shall be
505
+ included in all copies or substantial portions of the Software.
506
+
507
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
508
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
509
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
510
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
511
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
512
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
513
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
514
+
515
+ == Development
516
+
517
+ If you want to run the tests (and you should) it might be convenient to install
518
+ the development dependencies, you can do that with:
519
+
520
+ sudo gem install carrierwave --development
521
+
522
+ CarrierWave is still young, but most of it is pretty well documented. It is also
523
+ extensively specced, and there are cucumber features for some common use cases.
524
+ Just dig in and look at the source for more in-depth explanation of what things
525
+ are doing.
526
+
527
+ Issues are reported on GitHub, pull requests are very welcome!