carrierwave 0.3.5.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (43) hide show
  1. data/Generators +1 -1
  2. data/History.txt +11 -0
  3. data/Manifest.txt +7 -5
  4. data/README.rdoc +67 -26
  5. data/Rakefile +4 -1
  6. data/features/grid_fs_storage.feature +32 -0
  7. data/features/step_definitions/general_steps.rb +6 -1
  8. data/features/support/env.rb +5 -16
  9. data/lib/carrierwave.rb +30 -61
  10. data/lib/carrierwave/compatibility/paperclip.rb +2 -2
  11. data/lib/carrierwave/core_ext/inheritable_attributes.rb +3 -3
  12. data/lib/carrierwave/mount.rb +34 -27
  13. data/lib/carrierwave/orm/activerecord.rb +2 -2
  14. data/lib/carrierwave/processing/rmagick.rb +1 -1
  15. data/lib/carrierwave/storage/abstract.rb +0 -2
  16. data/lib/carrierwave/storage/file.rb +3 -5
  17. data/lib/carrierwave/storage/grid_fs.rb +88 -0
  18. data/lib/carrierwave/storage/s3.rb +37 -69
  19. data/lib/carrierwave/uploader.rb +1 -2
  20. data/lib/carrierwave/uploader/cache.rb +21 -18
  21. data/lib/carrierwave/uploader/configuration.rb +59 -0
  22. data/lib/carrierwave/uploader/remove.rb +0 -1
  23. data/lib/carrierwave/uploader/store.rb +3 -30
  24. data/lib/carrierwave/uploader/url.rb +1 -1
  25. data/lib/carrierwave/uploader/versions.rb +1 -4
  26. data/{lib/generators → merb_generators}/uploader_generator.rb +0 -0
  27. data/rails_generators/uploader/templates/uploader.rb +3 -3
  28. data/spec/compatibility/paperclip_spec.rb +11 -2
  29. data/spec/mount_spec.rb +0 -25
  30. data/spec/orm/datamapper_spec.rb +1 -1
  31. data/spec/spec_helper.rb +3 -3
  32. data/spec/storage/grid_fs_spec.rb +76 -0
  33. data/spec/storage/s3_spec.rb +75 -0
  34. data/spec/uploader/cache_spec.rb +1 -13
  35. data/spec/uploader/configuration_spec.rb +71 -0
  36. data/spec/uploader/paths_spec.rb +1 -1
  37. data/spec/uploader/store_spec.rb +0 -16
  38. data/spec/uploader/versions_spec.rb +0 -8
  39. metadata +40 -8
  40. data/carrierwave.gemspec +0 -63
  41. data/lib/carrierwave/uploader/default_path.rb +0 -24
  42. data/lib/carrierwave/uploader/paths.rb +0 -27
  43. data/spec/uploader/default_path_spec.rb +0 -68
data/Generators CHANGED
@@ -1,4 +1,4 @@
1
1
  scope 'merb-gen' do
2
- dir = File.join(File.dirname(__FILE__), 'lib', 'generators/')
2
+ dir = File.join(File.dirname(__FILE__), 'merb_generators/')
3
3
  Merb.add_generators dir + 'uploader_generator'
4
4
  end
@@ -1,3 +1,14 @@
1
+ === Version 0.4.0 2009-09
2
+
3
+ * [changed] the `public` option has been renamed `root` and the old `root` option was removed. No more ambiguity.
4
+ * [changed] Major *breaking* changes to the configuration syntax.
5
+
6
+ * [removed] support for `default_path`
7
+ * [removed] the `cache_to_cache_dir` option
8
+ * [removed] storage no longer calls `setup!` on storage engines
9
+
10
+ * [added] Support for MongoDB's GridFS store
11
+
1
12
  === Version 0.3.4 2009-09-01
2
13
 
3
14
  * [added] `default_url` as a replacement for `default_path`
@@ -3,7 +3,6 @@ History.txt
3
3
  Manifest.txt
4
4
  README.rdoc
5
5
  Rakefile
6
- carrierwave.gemspec
7
6
  cucumber.yml
8
7
  features/caching.feature
9
8
  features/file_storage.feature
@@ -12,6 +11,7 @@ features/file_storage_overridden_store_dir.feature
12
11
  features/file_storage_reversing_processor.feature
13
12
  features/fixtures/bork.txt
14
13
  features/fixtures/monkey.txt
14
+ features/grid_fs_storage.feature
15
15
  features/mount_activerecord.feature
16
16
  features/mount_datamapper.feature
17
17
  features/step_definitions/activerecord_steps.rb
@@ -43,23 +43,23 @@ lib/carrierwave/processing/rmagick.rb
43
43
  lib/carrierwave/sanitized_file.rb
44
44
  lib/carrierwave/storage/abstract.rb
45
45
  lib/carrierwave/storage/file.rb
46
+ lib/carrierwave/storage/grid_fs.rb
46
47
  lib/carrierwave/storage/s3.rb
47
48
  lib/carrierwave/test/matchers.rb
48
49
  lib/carrierwave/uploader.rb
49
50
  lib/carrierwave/uploader/cache.rb
50
51
  lib/carrierwave/uploader/callbacks.rb
51
- lib/carrierwave/uploader/default_path.rb
52
+ lib/carrierwave/uploader/configuration.rb
52
53
  lib/carrierwave/uploader/default_url.rb
53
54
  lib/carrierwave/uploader/extension_whitelist.rb
54
55
  lib/carrierwave/uploader/mountable.rb
55
- lib/carrierwave/uploader/paths.rb
56
56
  lib/carrierwave/uploader/processing.rb
57
57
  lib/carrierwave/uploader/proxy.rb
58
58
  lib/carrierwave/uploader/remove.rb
59
59
  lib/carrierwave/uploader/store.rb
60
60
  lib/carrierwave/uploader/url.rb
61
61
  lib/carrierwave/uploader/versions.rb
62
- lib/generators/uploader_generator.rb
62
+ merb_generators/uploader_generator.rb
63
63
  rails_generators/uploader/USAGE
64
64
  rails_generators/uploader/templates/uploader.rb
65
65
  rails_generators/uploader/uploader_generator.rb
@@ -77,8 +77,10 @@ spec/orm/mongomapper_spec.rb
77
77
  spec/orm/sequel_spec.rb
78
78
  spec/sanitized_file_spec.rb
79
79
  spec/spec_helper.rb
80
+ spec/storage/grid_fs_spec.rb
81
+ spec/storage/s3_spec.rb
80
82
  spec/uploader/cache_spec.rb
81
- spec/uploader/default_path_spec.rb
83
+ spec/uploader/configuration_spec.rb
82
84
  spec/uploader/default_url_spec.rb
83
85
  spec/uploader/extension_whitelist_spec.rb
84
86
  spec/uploader/mountable_spec.rb
@@ -20,6 +20,8 @@ Install the latest stable release:
20
20
 
21
21
  [sudo] gem install carrierwave
22
22
 
23
+ CarrierWave is hosted *only* on {Gemcutter}[http://gemcutter.org] as of version 0.4.0.
24
+
23
25
  In Merb, add it as a dependency to your config/dependencies.rb:
24
26
 
25
27
  dependency 'carrierwave'
@@ -59,7 +61,7 @@ You can use your uploader class to store and retrieve files like this:
59
61
 
60
62
  CarrierWave gives you a +store+ for permanent storage, and a +cache+ for
61
63
  temporary storage. You can use different stores, at the moment a filesystem
62
- store and an Amazon S3 store are bundled.
64
+ store, an Amazon S3 store and a store for MongoDB's GridFS are bundled.
63
65
 
64
66
  Most of the time you are going to want to use CarrierWave together with an ORM.
65
67
  It is quite simple to mount uploaders on columns in your model, so you can
@@ -72,25 +74,13 @@ need to require the relevant extension manually, e.g.:
72
74
 
73
75
  require 'carrierwave/orm/activerecord'
74
76
 
75
- Open your model file. For ActiveRecord do something like:
76
-
77
- class User < ActiveRecord::Base
78
- mount_uploader :avatar, AvatarUploader
79
- end
80
-
81
- Or for DataMapper:
77
+ Open your model file and mount the uploader:
82
78
 
83
79
  class User
84
- include DataMapper::Resource
85
-
86
80
  mount_uploader :avatar, AvatarUploader
87
81
  end
88
82
 
89
- Or for Sequel
90
-
91
- class User < Sequel::Model
92
- mount_uploader :avatar, AvatarUploader
93
- end
83
+ This works the same with all supported ORMs.
94
84
 
95
85
  Now you can cache files by assigning them to the attribute, they will
96
86
  automatically be stored when the record is saved.
@@ -115,6 +105,18 @@ method:
115
105
 
116
106
  This works for the file storage as well as Amazon S3.
117
107
 
108
+ == Securing uploads
109
+
110
+ 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.
111
+
112
+ If you're mounting the uploader, uploading a file with the wrong extension will make the record invalid instead. Otherwise, an error is raised.
113
+
114
+ class MyUploader < CarrierWave::Uploader::Base
115
+ def extension_white_list
116
+ %w(jpg jpeg gif png)
117
+ end
118
+ end
119
+
118
120
  == Adding versions
119
121
 
120
122
  Often you'll want to add different versions of the same file. The classic
@@ -171,7 +173,7 @@ like this:
171
173
  </p>
172
174
  <% end %>
173
175
 
174
- It might be a good idea to show th user that a file has been uploaded, in the
176
+ It might be a good idea to show the user that a file has been uploaded, in the
175
177
  case of images, a small thumbnail would be a good indicator:
176
178
 
177
179
  <% form_for @user do |f| %>
@@ -183,12 +185,6 @@ case of images, a small thumbnail would be a good indicator:
183
185
  </p>
184
186
  <% end %>
185
187
 
186
- NOTE: this feature currently requires write access to your filesystem. If write
187
- access is unavailable you will not be able to upload files. You can prevent
188
- CarrierWave from writing to the file system by setting
189
- `CarrierWave.config[:cache_to_cache_dir] = false`. This will however break
190
- redisplays of forms.
191
-
192
188
  == Providing a default URL
193
189
 
194
190
  In many cases, especially when working with images, it might be a good idea to
@@ -201,25 +197,68 @@ this easily by overriding the +default_url+ method in your uploader:
201
197
  end
202
198
  end
203
199
 
200
+ == Configuring CarrierWave
201
+
202
+ CarrierWave has a broad range of configuration options, which you can configure, both globally and on a per-uploader basis:
203
+
204
+ CarrierWave.configure do |config|
205
+ config.permissions = 0666
206
+ config.storage = :s3
207
+ end
208
+
209
+ Or alternatively:
210
+
211
+ class AvatarUploader < CarrierWave::Uploader::Base
212
+ permissions 0777
213
+ end
214
+
204
215
  == Using Amazon S3
205
216
 
206
217
  You'll need to configure a bucket, access id and secret key like this:
207
218
 
208
- CarrierWave.config[:s3][:access_key_id] = 'xxxxxx'
209
- CarrierWave.config[:s3][:secret_access_key] = 'xxxxxx'
210
- CarrierWave.config[:s3][:bucket] = 'name_of_bucket'
219
+ CarrierWave.configure do |config|
220
+ config.s3_access_key_id = 'xxxxxx'
221
+ config.s3_secret_access_key = 'xxxxxx'
222
+ config.s3_bucket = 'name_of_bucket'
223
+ end
211
224
 
212
225
  Do this in an initializer in Rails, and in a +before_app_loads+ block in Merb.
213
226
 
214
227
  And then in your uploader, set the storage to :s3
215
228
 
216
- class AvatarUploader <
229
+ class AvatarUploader < CarrierWave::Uploader::Base
217
230
  storage :s3
218
231
  end
219
232
 
220
233
  That's it! You can still use the +CarrierWave::Uploader#url+ method to return
221
234
  the url to the file on Amazon S3
222
235
 
236
+ == Using MongoDB's GridFS store
237
+
238
+ You'll need to configure the database and host to use:
239
+
240
+ CarrierWave.configure do |config|
241
+ config.grid_fs_database = 'my_mongo_database'
242
+ config.grid_fs_host = 'mongo.example.com'
243
+ end
244
+
245
+ The defaults are 'carrierwave' and 'localhost'.
246
+
247
+ And then in your uploader, set the storage to +:grid_fs+:
248
+
249
+ class AvatarUploader < CarrierWave::Uploader::Base
250
+ storage :grid_fs
251
+ end
252
+
253
+ Since GridFS doesn't make the files available via HTTP, you'll need to stream
254
+ them yourself. In Rails for example, you could use the +send_data+ method. You
255
+ can tell CarrierWave the URL you will serve your images from, allowing it to
256
+ generate the correct URL, by setting eg:
257
+
258
+ CarrierWave.configure do |config|
259
+ config.grid_fs_access_url = "/image/show"
260
+ end
261
+
223
262
  == Using RMagick
224
263
 
225
264
  If you're uploading images, you'll probably want to manipulate them in some way,
@@ -298,6 +337,8 @@ These people have contributed their time and effort to CarrierWave:
298
337
  * Andrew Timberlake
299
338
  * Durran Jordan
300
339
  * Scott Motte
340
+ * Sho Fukamachi
341
+ * Sam Lown
301
342
 
302
343
  == License
303
344
 
data/Rakefile CHANGED
@@ -14,15 +14,18 @@ $hoe = Hoe.spec 'carrierwave' do
14
14
  self.rubyforge_name = self.name
15
15
  self.readme_file = 'README.rdoc'
16
16
  self.version = CarrierWave::VERSION
17
+ self.extra_dev_deps << ['newgem', '>=1.5.2']
17
18
  self.extra_dev_deps << ['rspec', '>=1.2.8']
18
19
  self.extra_dev_deps << ['cucumber', '>=0.3.96']
19
20
  self.extra_dev_deps << ['activerecord', '>=2.3.3']
20
21
  self.extra_dev_deps << ['sqlite3-ruby', '>=1.2.5']
21
22
  self.extra_dev_deps << ['dm-core', '>=0.9.11']
23
+ self.extra_dev_deps << ['data_objects', '>=0.9.12']
22
24
  self.extra_dev_deps << ['do_sqlite3', '>=0.9.11']
23
25
  self.extra_dev_deps << ['sequel', '>=3.2.0']
24
26
  self.extra_dev_deps << ['rmagick', '>=2.10.0']
25
- self.extra_dev_deps << ['jnunemaker-mongomapper', '>=0.3.3']
27
+ self.extra_dev_deps << ['mongo_mapper', '>=0.5.4']
28
+ self.extra_dev_deps << ['aws-s3', '>=0.6.2']
26
29
  self.extra_rdoc_files << 'README.rdoc'
27
30
  end
28
31
 
@@ -0,0 +1,32 @@
1
+ Feature: uploader with file storage
2
+ In order to be awesome
3
+ As a developer using CarrierWave
4
+ I want to upload files to the filesystem
5
+
6
+ Background:
7
+ Given an uploader class that uses the 'grid_fs' storage
8
+ And an instance of that class
9
+
10
+ Scenario: store a file
11
+ When I store the file 'fixtures/bork.txt'
12
+ Then the contents of the file should be 'this is a file'
13
+
14
+ Scenario: store two files in succession
15
+ When I store the file 'fixtures/bork.txt'
16
+ Then the contents of the file should be 'this is a file'
17
+ When I store the file 'fixtures/monkey.txt'
18
+ Then the contents of the file should be 'this is another file'
19
+
20
+ Scenario: cache a file and then store it
21
+ When I cache the file 'fixtures/bork.txt'
22
+ Then there should be a file called 'bork.txt' somewhere in a subdirectory of 'public/uploads/tmp'
23
+ And the file called 'bork.txt' in a subdirectory of 'public/uploads/tmp' should be identical to the file at 'fixtures/bork.txt'
24
+ And there should not be a file at 'public/uploads/bork.txt'
25
+ When I store the file
26
+ Then the contents of the file should be 'this is a file'
27
+
28
+ Scenario: retrieving a file from cache then storing
29
+ Given the file 'fixtures/bork.txt' is cached file at 'public/uploads/tmp/20090212-2343-8336-0348/bork.txt'
30
+ When I retrieve the cache name '20090212-2343-8336-0348/bork.txt' from the cache
31
+ And I store the file
32
+ Then the contents of the file should be 'this is a file'
@@ -1,13 +1,18 @@
1
1
  # encoding: utf-8
2
2
 
3
- Given /^an uploader class that uses the 'file' storage$/ do
3
+ Given /^an uploader class that uses the '(.*?)' storage$/ do |kind|
4
4
  @klass = Class.new(CarrierWave::Uploader::Base)
5
+ @klass.storage = kind.to_sym
5
6
  end
6
7
 
7
8
  Given /^an instance of that class$/ do
8
9
  @uploader = @klass.new
9
10
  end
10
11
 
12
+ Then /^the contents of the file should be '(.*?)'$/ do |contents|
13
+ @uploader.read.chomp.should == contents
14
+ end
15
+
11
16
  Given /^that the uploader reverses the filename$/ do
12
17
  @klass.class_eval do
13
18
  def filename
@@ -1,34 +1,23 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  $TESTING=true
4
- $:.push File.join(File.dirname(__FILE__), '..', 'lib')
4
+ $:.unshift File.expand_path(File.join('..', '..', 'lib'), File.dirname(__FILE__))
5
5
 
6
- require 'rubygems'
7
6
  require File.join(File.dirname(__FILE__), 'activerecord')
8
7
  require File.join(File.dirname(__FILE__), 'datamapper')
9
8
 
10
- if ENV["AS"]
11
- puts "--> using ActiveSupport"
12
- require 'activesupport'
13
- elsif ENV["EXTLIB"]
14
- puts "--> using Extlib"
15
- require 'extlib'
16
- end
17
-
18
- require 'tempfile'
19
- #require 'ruby-debug'
20
9
  require 'spec'
21
-
22
10
  require 'carrierwave'
23
11
 
24
12
  alias :running :lambda
25
13
 
26
14
  def file_path( *paths )
27
- File.expand_path(File.join(File.dirname(__FILE__), '..', *paths))
15
+ File.expand_path(File.join('..', *paths), File.dirname(__FILE__))
28
16
  end
29
17
 
30
- CarrierWave.config[:public] = file_path('public')
31
- CarrierWave.config[:root] = file_path
18
+ CarrierWave.configure do |config|
19
+ config.root = file_path('public')
20
+ end
32
21
 
33
22
  After do
34
23
  FileUtils.rm_rf(file_path("public"))
@@ -7,39 +7,17 @@ require 'carrierwave/core_ext/inheritable_attributes'
7
7
 
8
8
  module CarrierWave
9
9
 
10
- VERSION = "0.3.5.2"
10
+ VERSION = "0.4.0"
11
11
 
12
12
  class << self
13
- attr_accessor :config, :logger
14
-
15
- def logger
16
- return @logger if @logger
17
- require 'logger'
18
- @logger = Logger.new(STDOUT)
19
- end
20
-
21
- ##
22
- # Generates a unique cache id for use in the caching system
23
- #
24
- # === Returns
25
- #
26
- # [String] a cache id in the format YYYYMMDD-HHMM-PID-RND
27
- #
28
- def generate_cache_id
29
- Time.now.strftime('%Y%m%d-%H%M') + '-' + Process.pid.to_s + '-' + ("%04d" % rand(9999))
13
+ def configure(&block)
14
+ CarrierWave::Uploader::Base.configure(&block)
30
15
  end
31
16
  end
32
17
 
33
18
  class UploadError < StandardError; end
34
- class NoFileError < UploadError; end
35
- class FormNotMultipart < UploadError
36
- def message
37
- "You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed.\n\n If this is a file upload, please check that your upload form is multipart encoded."
38
- end
39
- end
40
19
  class IntegrityError < UploadError; end
41
20
  class InvalidParameter < UploadError; end
42
- # Should be used by methods used as process callbacks.
43
21
  class ProcessingError < UploadError; end
44
22
 
45
23
  autoload :SanitizedFile, 'carrierwave/sanitized_file'
@@ -51,6 +29,7 @@ module CarrierWave
51
29
  autoload :Abstract, 'carrierwave/storage/abstract'
52
30
  autoload :File, 'carrierwave/storage/file'
53
31
  autoload :S3, 'carrierwave/storage/s3'
32
+ autoload :GridFS, 'carrierwave/storage/grid_fs'
54
33
  end
55
34
 
56
35
  module Uploader
@@ -61,13 +40,12 @@ module CarrierWave
61
40
  autoload :Processing, 'carrierwave/uploader/processing'
62
41
  autoload :Versions, 'carrierwave/uploader/versions'
63
42
  autoload :Remove, 'carrierwave/uploader/remove'
64
- autoload :Paths, 'carrierwave/uploader/paths'
65
43
  autoload :ExtensionWhitelist, 'carrierwave/uploader/extension_whitelist'
66
- autoload :DefaultPath, 'carrierwave/uploader/default_path'
67
44
  autoload :DefaultUrl, 'carrierwave/uploader/default_url'
68
45
  autoload :Proxy, 'carrierwave/uploader/proxy'
69
46
  autoload :Url, 'carrierwave/uploader/url'
70
47
  autoload :Mountable, 'carrierwave/uploader/mountable'
48
+ autoload :Configuration, 'carrierwave/uploader/configuration'
71
49
  end
72
50
 
73
51
  module Compatibility
@@ -80,52 +58,43 @@ module CarrierWave
80
58
 
81
59
  end
82
60
 
83
- CarrierWave.config = {
84
- :permissions => 0644,
85
- :storage => :file,
86
- :use_cache => true,
87
- :storage_engines => {
61
+ CarrierWave.configure do |config|
62
+ config.permissions = 0644
63
+ config.storage_engines = {
88
64
  :file => "CarrierWave::Storage::File",
89
- :s3 => "CarrierWave::Storage::S3"
90
- },
91
- :s3 => {
92
- :access => :public_read
93
- },
94
- :store_dir => 'uploads',
95
- :cache_dir => 'uploads/tmp',
96
- :cache_to_cache_dir => true,
97
- :mount => {
98
- :ignore_integrity_errors => true,
99
- :ignore_processing_errors => true,
100
- :validate_integrity => true,
101
- :validate_processing => true
65
+ :s3 => "CarrierWave::Storage::S3",
66
+ :grid_fs => "CarrierWave::Storage::GridFS"
102
67
  }
103
- }
68
+ config.storage = :file
69
+ config.s3_access = :public_read
70
+ config.grid_fs_database = 'carrierwave'
71
+ config.grid_fs_host = 'localhost'
72
+ config.store_dir = 'uploads'
73
+ config.cache_dir = 'uploads/tmp'
74
+ config.ignore_integrity_errors = true
75
+ config.ignore_processing_errors = true
76
+ config.validate_integrity = true
77
+ config.validate_processing = true
78
+ end
104
79
 
105
80
  if defined?(Merb)
106
- CarrierWave.logger = Merb.logger
107
- CarrierWave.config[:root] = Merb.root
108
- CarrierWave.config[:public] = Merb.dir_for(:public)
109
- Merb.add_generators File.dirname(__FILE__) / 'generators' / 'uploader_generator'
110
-
81
+ CarrierWave.configure do |config|
82
+ config.root = Merb.dir_for(:public)
83
+ end
111
84
  Merb::BootLoader.before_app_loads do
112
85
  # Setup path for uploaders and load all of them before classes are loaded
113
86
  Merb.push_path(:uploaders, Merb.root / 'app' / 'uploaders', '*.rb')
114
87
  Dir.glob(File.join(Merb.load_paths[:uploaders])).each {|f| require f }
115
88
  end
116
-
117
89
  elsif defined?(Rails)
118
- CarrierWave.logger = Rails.logger
119
- CarrierWave.config[:root] = Rails.root
120
- CarrierWave.config[:public] = File.join(Rails.root, 'public')
121
-
90
+ CarrierWave.configure do |config|
91
+ config.root = File.join(Rails.root, 'public')
92
+ end
122
93
  ActiveSupport::Dependencies.load_paths << File.join(Rails.root, "app", "uploaders")
123
-
124
94
  elsif defined?(Sinatra)
125
-
126
- CarrierWave.config[:root] = Sinatra::Application.root
127
- CarrierWave.config[:public] = Sinatra::Application.public
128
-
95
+ CarrierWave.configure do |config|
96
+ config.root = Sinatra::Application.public
97
+ end
129
98
  end
130
99
 
131
100