jnicklas-carrierwave 0.1.1 → 0.2.0

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.
data/lib/carrierwave.rb CHANGED
@@ -4,7 +4,7 @@ module CarrierWave
4
4
  class << self
5
5
  attr_accessor :config
6
6
  end
7
-
7
+
8
8
  class UploadError < StandardError; end
9
9
  class NoFileError < UploadError; end
10
10
  class FormNotMultipart < UploadError
@@ -16,47 +16,62 @@ module CarrierWave
16
16
  class InvalidParameter < UploadError; end
17
17
  # Should be used by methods used as process callbacks.
18
18
  class ProcessingError < UploadError; end
19
- end
20
19
 
21
- dir = File.join(File.dirname(__FILE__), 'carrierwave')
20
+ autoload :SanitizedFile, 'carrierwave/sanitized_file'
21
+ autoload :Uploader, 'carrierwave/uploader'
22
+ autoload :Mount, 'carrierwave/mount'
23
+ autoload :RMagick, 'carrierwave/processing/rmagick'
24
+ autoload :ImageScience, 'carrierwave/processing/image_science'
25
+
26
+ module Storage
27
+ autoload :Abstract, 'carrierwave/storage/abstract'
28
+ autoload :File, 'carrierwave/storage/file'
29
+ autoload :S3, 'carrierwave/storage/s3'
30
+ end
31
+
32
+ module Test
33
+ autoload :Matchers, 'carrierwave/test/matchers'
34
+ end
22
35
 
23
- require File.join(dir, 'sanitized_file')
24
- require File.join(dir, 'uploader')
25
- require File.join(dir, 'mount')
26
- require File.join(dir, 'storage', 'abstract')
27
- require File.join(dir, 'storage', 'file')
28
- require File.join(dir, 'storage', 's3')
36
+ end
29
37
 
30
38
  CarrierWave.config = {
39
+ :permissions => 0644,
31
40
  :storage => :file,
32
41
  :use_cache => true,
33
42
  :storage_engines => {
34
- :file => CarrierWave::Storage::File,
35
- :s3 => CarrierWave::Storage::S3
43
+ :file => "CarrierWave::Storage::File",
44
+ :s3 => "CarrierWave::Storage::S3"
36
45
  },
37
46
  :s3 => {
38
47
  :access => :public_read
39
48
  },
40
49
  :store_dir => 'uploads',
41
- :cache_dir => 'uploads/tmp'
50
+ :cache_dir => 'uploads/tmp',
51
+ :mount => {
52
+ :ignore_integrity_errors => true,
53
+ :ignore_processing_errors => true,
54
+ :validate_integrity => true,
55
+ :validate_processing => true
56
+ }
42
57
  }
43
58
 
44
59
  if defined?(Merb)
45
60
  CarrierWave.config[:root] = Merb.root
46
61
  CarrierWave.config[:public] = Merb.dir_for(:public)
47
-
62
+
48
63
  orm_path = File.dirname(__FILE__) / 'carrierwave' / 'orm' / Merb.orm
49
64
  require orm_path if File.exist?(orm_path + '.rb')
50
-
65
+
51
66
  Merb.push_path(:uploader, Merb.root / "app" / "uploaders")
52
-
67
+
53
68
  Merb.add_generators File.dirname(__FILE__) / 'generators' / 'uploader_generator'
54
69
  end
55
70
 
56
71
  if defined?(Rails)
57
72
  CarrierWave.config[:root] = Rails.root
58
73
  CarrierWave.config[:public] = File.join(Rails.root, 'public')
59
-
74
+
60
75
  require File.join(File.dirname(__FILE__), "carrierwave", "orm", 'activerecord')
61
76
 
62
77
  ActiveSupport::Dependencies.load_paths << File.join(Rails.root, "app", "uploaders")
@@ -65,4 +80,4 @@ end
65
80
  if defined?(Sinatra)
66
81
  CarrierWave.config[:root] = Sinatra::Application.root
67
82
  CarrierWave.config[:public] = Sinatra::Application.public
68
- end
83
+ end
@@ -1,20 +1,20 @@
1
1
  module Merb
2
2
  module Generators
3
3
  class UploaderGenerator < NamedGenerator
4
-
4
+
5
5
  def self.source_root
6
6
  File.join(File.dirname(__FILE__), '..', '..', 'rails_generators', 'uploader', 'templates')
7
7
  end
8
-
8
+
9
9
  first_argument :name, :required => true, :desc => "The name of this uploader"
10
-
10
+
11
11
  template :uploader do |t|
12
12
  t.source = 'uploader.rb'
13
- t.destination = "app/uploaders/#{file_name}_uploader.rb"
13
+ t.destination = "app/models/#{file_name}_uploader.rb"
14
14
  end
15
15
  end
16
-
16
+
17
17
  add :uploader, UploaderGenerator
18
-
18
+
19
19
  end
20
- end
20
+ end
@@ -1,4 +1,6 @@
1
- class <%= class_name %>Uploader < CarrierWave::Uploader
1
+ class <%= class_name %>Uploader
2
+
3
+ include CarrierWave::Uploader
2
4
 
3
5
  # Include RMagick or ImageScience support
4
6
  # include CarrierWave::RMagick
@@ -20,6 +22,12 @@ class <%= class_name %>Uploader < CarrierWave::Uploader
20
22
  # process :scale => [50, 50]
21
23
  # end
22
24
 
25
+ # Add a white list of extensions which are allowed to be uploaded,
26
+ # for images you might use something like this:
27
+ # def extension_white_list
28
+ # %w(jpg jpeg gif png)
29
+ # end
30
+
23
31
  # Override the filename of the uploaded files
24
32
  # def filename
25
33
  # "something.jpg"
data/spec/mount_spec.rb CHANGED
@@ -2,8 +2,6 @@ require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  describe CarrierWave::Mount do
4
4
 
5
- include SanitizedFileSpecHelper
6
-
7
5
  after do
8
6
  FileUtils.rm_rf(public_path)
9
7
  end
@@ -14,12 +12,37 @@ describe CarrierWave::Mount do
14
12
  @class = Class.new
15
13
  @class.send(:extend, CarrierWave::Mount)
16
14
 
17
- @uploader = Class.new(CarrierWave::Uploader)
15
+ @uploader = Class.new do
16
+ include CarrierWave::Uploader
17
+ end
18
18
 
19
19
  @class.mount_uploader(:image, @uploader)
20
20
  @instance = @class.new
21
21
  end
22
22
 
23
+ describe '#image_uploader' do
24
+ it "should return the uploader" do
25
+ @instance.image_uploader.should be_an_instance_of(@uploader)
26
+ end
27
+ end
28
+
29
+ describe '#image_uploader=' do
30
+ it "should set the uploader" do
31
+ @my_uploader = @uploader.new
32
+ @instance.image_uploader = @my_uploader
33
+ @instance.image_uploader.should == @my_uploader
34
+ end
35
+
36
+ it "should use the set uploader" do
37
+ @my_uploader = @uploader.new
38
+ @my_uploader.store!(stub_file('test.jpg'))
39
+ @instance.image_uploader = @my_uploader
40
+ @instance.image_uploader.should == @my_uploader
41
+ @instance.image.should == @my_uploader
42
+ @instance.image.current_path.should == public_path('uploads/test.jpg')
43
+ end
44
+ end
45
+
23
46
  describe '#image' do
24
47
 
25
48
  it "should return nil when nothing has been assigned" do
@@ -66,6 +89,26 @@ describe CarrierWave::Mount do
66
89
  @instance.image = ''
67
90
  end
68
91
 
92
+ it "should fail silently if the image fails an integrity check" do
93
+ @uploader.class_eval do
94
+ def extension_white_list
95
+ %(txt)
96
+ end
97
+ end
98
+ @instance.image = stub_file('test.jpg')
99
+ @instance.image.should be_nil
100
+ end
101
+
102
+ it "should fail silently if the image fails to be processed" do
103
+ @uploader.class_eval do
104
+ process :monkey
105
+ def monkey
106
+ raise CarrierWave::ProcessingError, "Ohh noez!"
107
+ end
108
+ end
109
+ @instance.image = stub_file('test.jpg')
110
+ end
111
+
69
112
  end
70
113
 
71
114
  describe '#image_cache' do
@@ -140,6 +183,51 @@ describe CarrierWave::Mount do
140
183
  @instance.image.current_path.should == public_path('uploads/test.jpg')
141
184
  end
142
185
  end
186
+
187
+ describe '#image_integrity_error' do
188
+
189
+ it "should be nil by default" do
190
+ @instance.image_integrity_error.should be_nil
191
+ end
192
+
193
+ it "should be nil after a file is cached" do
194
+ @instance.image = stub_file('test.jpg')
195
+ @instance.image_integrity_error.should be_nil
196
+ end
197
+
198
+ it "should be an error instance after an integrity check has failed" do
199
+ @uploader.class_eval do
200
+ def extension_white_list
201
+ %(txt)
202
+ end
203
+ end
204
+ @instance.image = stub_file('test.jpg')
205
+ @instance.image_integrity_error.should be_an_instance_of(CarrierWave::IntegrityError)
206
+ end
207
+ end
208
+
209
+ describe '#image_processing_error' do
210
+
211
+ it "should be nil by default" do
212
+ @instance.image_processing_error.should be_nil
213
+ end
214
+
215
+ it "should be nil after a file is cached" do
216
+ @instance.image = stub_file('test.jpg')
217
+ @instance.image_processing_error.should be_nil
218
+ end
219
+
220
+ it "should be an error instance after an integrity check has failed" do
221
+ @uploader.class_eval do
222
+ process :monkey
223
+ def monkey
224
+ raise CarrierWave::ProcessingError, "Ohh noez!"
225
+ end
226
+ end
227
+ @instance.image = stub_file('test.jpg')
228
+ @instance.image_processing_error.should be_an_instance_of(CarrierWave::ProcessingError)
229
+ end
230
+ end
143
231
 
144
232
  end
145
233
 
@@ -178,4 +266,60 @@ describe CarrierWave::Mount do
178
266
 
179
267
  end
180
268
 
269
+ describe '#mount_uploader with :ignore_integrity_errors => false' do
270
+
271
+ before do
272
+ @class = Class.new
273
+ @class.send(:extend, CarrierWave::Mount)
274
+
275
+ @uploader = Class.new do
276
+ include CarrierWave::Uploader
277
+ end
278
+
279
+ @class.mount_uploader(:image, @uploader, :ignore_integrity_errors => false)
280
+ @instance = @class.new
281
+ end
282
+
283
+ it "should raise an error if the image fails an integrity check" do
284
+ @uploader.class_eval do
285
+ def extension_white_list
286
+ %(txt)
287
+ end
288
+ end
289
+ running {
290
+ @instance.image = stub_file('test.jpg')
291
+ }.should raise_error(CarrierWave::IntegrityError)
292
+ end
293
+
294
+ end
295
+
296
+ describe '#mount_uploader with :ignore_processing_errors => false' do
297
+
298
+ before do
299
+ @class = Class.new
300
+ @class.send(:extend, CarrierWave::Mount)
301
+
302
+ @uploader = Class.new do
303
+ include CarrierWave::Uploader
304
+ end
305
+
306
+ @class.mount_uploader(:image, @uploader, :ignore_processing_errors => false)
307
+ @instance = @class.new
308
+ end
309
+
310
+ it "should raise an error if the image fails to be processed" do
311
+ @uploader.class_eval do
312
+ process :monkey
313
+ def monkey
314
+ raise CarrierWave::ProcessingError, "Ohh noez!"
315
+ end
316
+ end
317
+ running {
318
+ @instance.image = stub_file('test.jpg')
319
+ }.should raise_error(CarrierWave::ProcessingError)
320
+ end
321
+
322
+ end
323
+
324
+
181
325
  end
@@ -28,8 +28,6 @@ class Event < ActiveRecord::Base; end # setup a basic AR class for testing
28
28
 
29
29
  describe CarrierWave::ActiveRecord do
30
30
 
31
- include SanitizedFileSpecHelper
32
-
33
31
  describe '.mount_uploader' do
34
32
 
35
33
  before(:all) { TestMigration.up }
@@ -39,7 +37,9 @@ describe CarrierWave::ActiveRecord do
39
37
  before do
40
38
  @class = Class.new(ActiveRecord::Base)
41
39
  @class.table_name = "events"
42
- @uploader = Class.new(CarrierWave::Uploader)
40
+ @uploader = Class.new do
41
+ include CarrierWave::Uploader
42
+ end
43
43
  @class.mount_uploader(:image, @uploader)
44
44
  @event = @class.new
45
45
  end
@@ -98,6 +98,27 @@ describe CarrierWave::ActiveRecord do
98
98
  @event.image = ''
99
99
  @event.image.should be_nil
100
100
  end
101
+
102
+ it "should make the record invalid when an integrity error occurs" do
103
+ @uploader.class_eval do
104
+ def extension_white_list
105
+ %(txt)
106
+ end
107
+ end
108
+ @event.image = stub_file('test.jpg')
109
+ @event.should_not be_valid
110
+ end
111
+
112
+ it "should make the record invalid when a processing error occurs" do
113
+ @uploader.class_eval do
114
+ process :monkey
115
+ def monkey
116
+ raise CarrierWave::ProcessingError, "Ohh noez!"
117
+ end
118
+ end
119
+ @event.image = stub_file('test.jpg')
120
+ @event.should_not be_valid
121
+ end
101
122
 
102
123
  end
103
124
 
@@ -6,10 +6,10 @@ DataMapper.setup(:default, 'sqlite3::memory:')
6
6
 
7
7
  describe CarrierWave::DataMapper do
8
8
 
9
- include SanitizedFileSpecHelper
10
-
11
9
  before do
12
- uploader = Class.new(CarrierWave::Uploader)
10
+ uploader = Class.new do
11
+ include CarrierWave::Uploader
12
+ end
13
13
 
14
14
  @class = Class.new
15
15
  @class.class_eval do
@@ -0,0 +1,170 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ require 'carrierwave/orm/sequel'
4
+
5
+ DB = Sequel.sqlite
6
+
7
+ describe CarrierWave::Sequel do
8
+
9
+ def setup_variables_for_class(klass)
10
+ uploader = Class.new do
11
+ include CarrierWave::Uploader
12
+ end
13
+ klass.mount_uploader(:image, uploader)
14
+ model = klass.new
15
+ [klass, uploader, model]
16
+ end
17
+
18
+ describe '.mount_uploader' do
19
+
20
+ before(:all) do
21
+ DB.create_table :events do
22
+ primary_key :id
23
+ column :image, :string
24
+ column :textfile, :string
25
+ end
26
+ end
27
+
28
+ after(:all) do
29
+ DB.drop_table :events
30
+ end
31
+
32
+ before do
33
+ @class = Class.new(Sequel::Model)
34
+ @class.set_dataset :events
35
+ @class, @uploader, @event = setup_variables_for_class(@class)
36
+ end
37
+
38
+ describe '#image' do
39
+
40
+ it "should return nil when nothing has been assigned" do
41
+ @event.image.should be_nil
42
+ end
43
+
44
+ it "should return nil when an empty string has been assigned" do
45
+ @event[:image] = ''
46
+ @event.save
47
+ @event.reload
48
+ @event.image.should be_nil
49
+ end
50
+
51
+ it "should retrieve a file from the storage if a value is stored in the database" do
52
+ @event[:image] = 'test.jpeg'
53
+ @event.save
54
+ @event.reload
55
+ @event.image.should be_an_instance_of(@uploader)
56
+ end
57
+
58
+ it "should set the path to the store dir" do
59
+ @event[:image] = 'test.jpeg'
60
+ @event.save
61
+ @event.reload
62
+ @event.image.current_path.should == public_path('uploads/test.jpeg')
63
+ end
64
+
65
+ end
66
+
67
+ describe '#image=' do
68
+
69
+ it "should cache a file" do
70
+ @event.image = stub_file('test.jpeg')
71
+ @event.image.should be_an_instance_of(@uploader)
72
+ end
73
+
74
+ it "should write nothing to the database, to prevent overriden filenames to fail because of unassigned attributes" do
75
+ @event[:image].should be_nil
76
+ end
77
+
78
+ it "should copy a file into into the cache directory" do
79
+ @event.image = stub_file('test.jpeg')
80
+ @event.image.current_path.should =~ /^#{public_path('uploads/tmp')}/
81
+ end
82
+
83
+ it "should do nothing when nil is assigned" do
84
+ @event.image = nil
85
+ @event.image.should be_nil
86
+ end
87
+
88
+ it "should do nothing when an empty string is assigned" do
89
+ @event.image = ''
90
+ @event.image.should be_nil
91
+ end
92
+
93
+ end
94
+
95
+ describe '#save' do
96
+
97
+ it "should do nothing when no file has been assigned" do
98
+ @event.save.should be_true
99
+ @event.image.should be_nil
100
+ end
101
+
102
+ it "should copy the file to the upload directory when a file has been assigned" do
103
+ @event.image = stub_file('test.jpeg')
104
+ @event.save.should be_true
105
+ @event.image.should be_an_instance_of(@uploader)
106
+ @event.image.current_path.should == public_path('uploads/test.jpeg')
107
+ end
108
+
109
+ describe 'with validation' do
110
+
111
+ before do
112
+ @class.class_eval do
113
+ validates_each :image do |object, attribute, value|
114
+ object.errors[attribute] << 'FAIL!'
115
+ end
116
+ end
117
+ end
118
+
119
+ it "should do nothing when a validation fails" do
120
+ pending "I don't understand how this is supposed to work :S" do
121
+ @event.image = stub_file('test.jpeg')
122
+ @event.save.should be_false
123
+ @event.image.should be_an_instance_of(@uploader)
124
+ @event.image.current_path.should =~ /^#{public_path('uploads/tmp')}/
125
+ end
126
+ end
127
+ end
128
+
129
+ it "should assign the filename to the database" do
130
+ @event.image = stub_file('test.jpeg')
131
+ @event.save.should be_true
132
+ @event.reload
133
+ @event[:image].should == 'test.jpeg'
134
+ end
135
+
136
+ end
137
+
138
+ describe 'with overriddent filename' do
139
+
140
+ describe '#save' do
141
+
142
+ before do
143
+ @uploader.class_eval do
144
+ def filename
145
+ model.name + File.extname(super)
146
+ end
147
+ end
148
+ @event.stub!(:name).and_return('jonas')
149
+ end
150
+
151
+ it "should copy the file to the upload directory when a file has been assigned" do
152
+ @event.image = stub_file('test.jpeg')
153
+ @event.save.should be_true
154
+ @event.image.should be_an_instance_of(@uploader)
155
+ @event.image.current_path.should == public_path('uploads/jonas.jpeg')
156
+ end
157
+
158
+ it "should assign an overridden filename to the database" do
159
+ @event.image = stub_file('test.jpeg')
160
+ @event.save.should be_true
161
+ @event.reload
162
+ @event[:image].should == 'jonas.jpeg'
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+ end
@@ -2,8 +2,6 @@ require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  describe CarrierWave::SanitizedFile do
4
4
 
5
- include SanitizedFileSpecHelper
6
-
7
5
  before do
8
6
  unless File.exists?(file_path('llama.jpg'))
9
7
  FileUtils.cp(file_path('test.jpg'), file_path('llama.jpg'))
@@ -206,15 +204,9 @@ describe CarrierWave::SanitizedFile do
206
204
  @sanitized_file.extension.should == 'png'
207
205
  end
208
206
 
209
- describe "with permissions set" do
210
- before do
211
- @sanitized_file.options[:permissions] = 0755
212
- end
213
-
214
- it "should set the right permissions" do
215
- @sanitized_file.move_to(file_path('gurr.png'))
216
- @sanitized_file.should have_permissions(0755)
217
- end
207
+ it "should set the right permissions" do
208
+ @sanitized_file.move_to(file_path('gurr.png'), 0755)
209
+ @sanitized_file.should have_permissions(0755)
218
210
  end
219
211
 
220
212
  end
@@ -266,15 +258,9 @@ describe CarrierWave::SanitizedFile do
266
258
  new_file.extension.should == 'png'
267
259
  end
268
260
 
269
- describe "with permissions set" do
270
- before do
271
- @sanitized_file.options[:permissions] = 0755
272
- end
273
-
274
- it "should set the right permissions" do
275
- new_file = @sanitized_file.copy_to(file_path('gurr.png'))
276
- new_file.should have_permissions(0755)
277
- end
261
+ it "should set the right permissions" do
262
+ new_file = @sanitized_file.copy_to(file_path('gurr.png'), 0755)
263
+ new_file.should have_permissions(0755)
278
264
  end
279
265
 
280
266
  end
@@ -345,9 +331,9 @@ describe CarrierWave::SanitizedFile do
345
331
  end
346
332
  end
347
333
 
348
- describe '#string?' do
334
+ describe '#is_path?' do
349
335
  it "should be false" do
350
- @sanitized_file.string?.should be_false
336
+ @sanitized_file.is_path?.should be_false
351
337
  end
352
338
  end
353
339
 
@@ -363,9 +349,9 @@ describe CarrierWave::SanitizedFile do
363
349
 
364
350
  it_should_behave_like "all valid sanitized files that are stored on disk"
365
351
 
366
- describe '#string?' do
352
+ describe '#is_path?' do
367
353
  it "should be false" do
368
- @sanitized_file.string?.should be_false
354
+ @sanitized_file.is_path?.should be_false
369
355
  end
370
356
  end
371
357
 
@@ -391,9 +377,9 @@ describe CarrierWave::SanitizedFile do
391
377
  end
392
378
  end
393
379
 
394
- describe '#string?' do
380
+ describe '#is_path?' do
395
381
  it "should be false" do
396
- @sanitized_file.string?.should be_false
382
+ @sanitized_file.is_path?.should be_false
397
383
  end
398
384
  end
399
385
 
@@ -422,9 +408,9 @@ describe CarrierWave::SanitizedFile do
422
408
 
423
409
  it_should_behave_like "all valid sanitized files that are stored on disk"
424
410
 
425
- describe '#string?' do
411
+ describe '#is_path?' do
426
412
  it "should be false" do
427
- @sanitized_file.string?.should be_false
413
+ @sanitized_file.is_path?.should be_false
428
414
  end
429
415
  end
430
416
 
@@ -448,9 +434,9 @@ describe CarrierWave::SanitizedFile do
448
434
 
449
435
  it_should_behave_like "all valid sanitized files that are stored on disk"
450
436
 
451
- describe '#string?' do
437
+ describe '#is_path?' do
452
438
  it "should be true" do
453
- @sanitized_file.string?.should be_true
439
+ @sanitized_file.is_path?.should be_true
454
440
  end
455
441
  end
456
442
 
@@ -474,9 +460,9 @@ describe CarrierWave::SanitizedFile do
474
460
 
475
461
  it_should_behave_like "all valid sanitized files that are stored on disk"
476
462
 
477
- describe '#string?' do
463
+ describe '#is_path?' do
478
464
  it "should be true" do
479
- @sanitized_file.string?.should be_true
465
+ @sanitized_file.is_path?.should be_true
480
466
  end
481
467
  end
482
468
 
@@ -506,9 +492,9 @@ describe CarrierWave::SanitizedFile do
506
492
  end
507
493
  end
508
494
 
509
- describe '#string?' do
495
+ describe '#is_path?' do
510
496
  it "should be false" do
511
- @empty.string?.should be_false
497
+ @empty.is_path?.should be_false
512
498
  end
513
499
  end
514
500
 
@@ -572,9 +558,9 @@ describe CarrierWave::SanitizedFile do
572
558
  end
573
559
  end
574
560
 
575
- describe '#string?' do
561
+ describe '#is_path?' do
576
562
  it "should be false" do
577
- @empty.string?.should be_false
563
+ @empty.is_path?.should be_false
578
564
  end
579
565
  end
580
566