jswanner-carrierwave 0.5.0.beta3

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