joshpuetz-paperclip 2.3.0.1 → 2.3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/paperclip.rb +5 -2
- data/lib/paperclip/attachment.rb +8 -4
- data/lib/paperclip/storage.rb +26 -25
- data/lib/paperclip/thumbnail.rb +15 -12
- data/test/attachment_test.rb +107 -4
- data/test/helper.rb +11 -0
- data/test/integration_test.rb +13 -11
- data/test/paperclip_test.rb +53 -32
- data/test/storage_test.rb +19 -28
- data/test/thumbnail_test.rb +50 -0
- metadata +2 -3
data/lib/paperclip.rb
CHANGED
@@ -44,7 +44,7 @@ end
|
|
44
44
|
# documentation for Paperclip::ClassMethods for more useful information.
|
45
45
|
module Paperclip
|
46
46
|
|
47
|
-
VERSION = "2.
|
47
|
+
VERSION = "2.3.0"
|
48
48
|
|
49
49
|
class << self
|
50
50
|
# Provides configurability to Paperclip. There are a number of options available, such as:
|
@@ -93,7 +93,7 @@ module Paperclip
|
|
93
93
|
# Paperclip.options[:log_command] is set to true (defaults to false). This
|
94
94
|
# will only log if logging in general is set to true as well.
|
95
95
|
def run cmd, params = "", expected_outcodes = 0
|
96
|
-
command = %Q
|
96
|
+
command = %Q[#{path_for_command(cmd)} #{params}].gsub(/\s+/, " ")
|
97
97
|
command = "#{command} 2>#{bit_bucket}" if Paperclip.options[:swallow_stderr]
|
98
98
|
Paperclip.log(command) if Paperclip.options[:log_command]
|
99
99
|
output = `#{command}`
|
@@ -189,6 +189,9 @@ module Paperclip
|
|
189
189
|
# to a command line error. This will override the global setting for this attachment.
|
190
190
|
# Defaults to true. This option used to be called :whiny_thumbanils, but this is
|
191
191
|
# deprecated.
|
192
|
+
# * +keep_old_files+: Keep the existing attachment files (original + resized) from
|
193
|
+
# being automatically deleted when an attachment is cleared or updated.
|
194
|
+
# Defaults to +false+.
|
192
195
|
# * +convert_options+: When creating thumbnails, use this free-form options
|
193
196
|
# field to pass in various convert command options. Typical options are "-strip" to
|
194
197
|
# remove all Exif data from the image (save space for thumbnails and avatars) or
|
data/lib/paperclip/attachment.rb
CHANGED
@@ -14,7 +14,8 @@ module Paperclip
|
|
14
14
|
:default_style => :original,
|
15
15
|
:validations => [],
|
16
16
|
:storage => :filesystem,
|
17
|
-
:whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
|
17
|
+
:whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails],
|
18
|
+
:keep_old_files=> false
|
18
19
|
}
|
19
20
|
end
|
20
21
|
|
@@ -40,6 +41,7 @@ module Paperclip
|
|
40
41
|
@default_style = options[:default_style]
|
41
42
|
@storage = options[:storage]
|
42
43
|
@whiny = options[:whiny_thumbnails] || options[:whiny]
|
44
|
+
@keep_old_files = options[:keep_old_files]
|
43
45
|
@convert_options = options[:convert_options] || {}
|
44
46
|
@processors = options[:processors] || [:thumbnail]
|
45
47
|
@options = options
|
@@ -394,9 +396,11 @@ module Paperclip
|
|
394
396
|
|
395
397
|
def queue_existing_for_delete #:nodoc:
|
396
398
|
return unless file?
|
397
|
-
@
|
398
|
-
|
399
|
-
|
399
|
+
unless @keep_old_files
|
400
|
+
@queued_for_delete += [:original, *@styles.keys].uniq.map do |style|
|
401
|
+
path(style) if exists?(style)
|
402
|
+
end.compact
|
403
|
+
end
|
400
404
|
instance_write(:file_name, nil)
|
401
405
|
instance_write(:content_type, nil)
|
402
406
|
instance_write(:file_size, nil)
|
data/lib/paperclip/storage.rb
CHANGED
@@ -33,7 +33,6 @@ module Paperclip
|
|
33
33
|
def to_file style = default_style
|
34
34
|
@queued_for_write[style] || (File.new(path(style), 'rb') if exists?(style))
|
35
35
|
end
|
36
|
-
alias_method :to_io, :to_file
|
37
36
|
|
38
37
|
def flush_writes #:nodoc:
|
39
38
|
@queued_for_write.each do |style, file|
|
@@ -128,17 +127,21 @@ module Paperclip
|
|
128
127
|
# separate parts of your file name.
|
129
128
|
module S3
|
130
129
|
def self.extended base
|
131
|
-
require '
|
130
|
+
require 'aws/s3'
|
132
131
|
base.instance_eval do
|
133
132
|
@s3_credentials = parse_credentials(@options[:s3_credentials])
|
134
133
|
@bucket = @options[:bucket] || @s3_credentials[:bucket]
|
135
134
|
@bucket = @bucket.call(self) if @bucket.is_a?(Proc)
|
136
135
|
@s3_options = @options[:s3_options] || {}
|
137
|
-
@s3_permissions = @options[:s3_permissions] ||
|
138
|
-
@s3_protocol = @options[:s3_protocol] || (@s3_permissions ==
|
136
|
+
@s3_permissions = @options[:s3_permissions] || :public_read
|
137
|
+
@s3_protocol = @options[:s3_protocol] || (@s3_permissions == :public_read ? 'http' : 'https')
|
139
138
|
@s3_headers = @options[:s3_headers] || {}
|
140
139
|
@s3_host_alias = @options[:s3_host_alias]
|
141
140
|
@url = ":s3_path_url" unless @url.to_s.match(/^:s3.*url$/)
|
141
|
+
AWS::S3::Base.establish_connection!( @s3_options.merge(
|
142
|
+
:access_key_id => @s3_credentials[:access_key_id],
|
143
|
+
:secret_access_key => @s3_credentials[:secret_access_key]
|
144
|
+
))
|
142
145
|
end
|
143
146
|
Paperclip.interpolates(:s3_alias_url) do |attachment, style|
|
144
147
|
"#{attachment.s3_protocol}://#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{^/}, "")}"
|
@@ -151,16 +154,6 @@ module Paperclip
|
|
151
154
|
end
|
152
155
|
end
|
153
156
|
|
154
|
-
def s3
|
155
|
-
@s3 ||= RightAws::S3.new(@s3_credentials[:access_key_id],
|
156
|
-
@s3_credentials[:secret_access_key],
|
157
|
-
@s3_options)
|
158
|
-
end
|
159
|
-
|
160
|
-
def s3_bucket
|
161
|
-
@s3_bucket ||= s3.bucket(@bucket, true, @s3_permissions)
|
162
|
-
end
|
163
|
-
|
164
157
|
def bucket_name
|
165
158
|
@bucket
|
166
159
|
end
|
@@ -175,7 +168,11 @@ module Paperclip
|
|
175
168
|
end
|
176
169
|
|
177
170
|
def exists?(style = default_style)
|
178
|
-
|
171
|
+
if original_filename
|
172
|
+
AWS::S3::S3Object.exists?(path(style), bucket_name)
|
173
|
+
else
|
174
|
+
false
|
175
|
+
end
|
179
176
|
end
|
180
177
|
|
181
178
|
def s3_protocol
|
@@ -185,18 +182,24 @@ module Paperclip
|
|
185
182
|
# Returns representation of the data of the file assigned to the given
|
186
183
|
# style, in the format most representative of the current storage.
|
187
184
|
def to_file style = default_style
|
188
|
-
@queued_for_write[style]
|
185
|
+
return @queued_for_write[style] if @queued_for_write[style]
|
186
|
+
file = Tempfile.new(path(style))
|
187
|
+
file.write(AWS::S3::S3Object.value(path(style), bucket_name))
|
188
|
+
file.rewind
|
189
|
+
return file
|
189
190
|
end
|
190
|
-
alias_method :to_io, :to_file
|
191
191
|
|
192
192
|
def flush_writes #:nodoc:
|
193
193
|
@queued_for_write.each do |style, file|
|
194
194
|
begin
|
195
195
|
log("saving #{path(style)}")
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
196
|
+
AWS::S3::S3Object.store(path(style),
|
197
|
+
file,
|
198
|
+
bucket_name,
|
199
|
+
{:content_type => instance_read(:content_type),
|
200
|
+
:access => @s3_permissions,
|
201
|
+
}.merge(@s3_headers))
|
202
|
+
rescue AWS::S3::ResponseError => e
|
200
203
|
raise
|
201
204
|
end
|
202
205
|
end
|
@@ -207,10 +210,8 @@ module Paperclip
|
|
207
210
|
@queued_for_delete.each do |path|
|
208
211
|
begin
|
209
212
|
log("deleting #{path}")
|
210
|
-
|
211
|
-
|
212
|
-
end
|
213
|
-
rescue RightAws::AwsError
|
213
|
+
AWS::S3::S3Object.delete(path, bucket_name)
|
214
|
+
rescue AWS::S3::ResponseError
|
214
215
|
# Ignore this.
|
215
216
|
end
|
216
217
|
end
|
data/lib/paperclip/thumbnail.rb
CHANGED
@@ -2,7 +2,7 @@ module Paperclip
|
|
2
2
|
# Handles thumbnailing images that are uploaded.
|
3
3
|
class Thumbnail < Processor
|
4
4
|
|
5
|
-
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options
|
5
|
+
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options, :source_file_options
|
6
6
|
|
7
7
|
# Creates a Thumbnail object set to work on the +file+ given. It
|
8
8
|
# will attempt to transform the image into one defined by +target_geometry+
|
@@ -12,17 +12,18 @@ module Paperclip
|
|
12
12
|
# set, the options will be appended to the convert command upon image conversion
|
13
13
|
def initialize file, options = {}, attachment = nil
|
14
14
|
super
|
15
|
-
geometry
|
16
|
-
@file
|
17
|
-
@crop
|
18
|
-
@target_geometry
|
19
|
-
@current_geometry
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
15
|
+
geometry = options[:geometry]
|
16
|
+
@file = file
|
17
|
+
@crop = geometry[-1,1] == '#'
|
18
|
+
@target_geometry = Geometry.parse geometry
|
19
|
+
@current_geometry = Geometry.from_file @file
|
20
|
+
@source_file_options = options[:source_file_options]
|
21
|
+
@convert_options = options[:convert_options]
|
22
|
+
@whiny = options[:whiny].nil? ? true : options[:whiny]
|
23
|
+
@format = options[:format]
|
23
24
|
|
24
|
-
@current_format
|
25
|
-
@basename
|
25
|
+
@current_format = File.extname(@file.path)
|
26
|
+
@basename = File.basename(@file.path, @current_format)
|
26
27
|
end
|
27
28
|
|
28
29
|
# Returns true if the +target_geometry+ is meant to crop.
|
@@ -43,6 +44,7 @@ module Paperclip
|
|
43
44
|
dst.binmode
|
44
45
|
|
45
46
|
command = <<-end_command
|
47
|
+
#{ source_file_options }
|
46
48
|
"#{ File.expand_path(src.path) }[0]"
|
47
49
|
#{ transformation_command }
|
48
50
|
"#{ File.expand_path(dst.path) }"
|
@@ -61,7 +63,8 @@ module Paperclip
|
|
61
63
|
# into the thumbnail.
|
62
64
|
def transformation_command
|
63
65
|
scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
|
64
|
-
trans = "
|
66
|
+
trans = ""
|
67
|
+
trans << " -resize \"#{scale}\"" unless scale.blank?
|
65
68
|
trans << " -crop \"#{crop}\" +repage" if crop
|
66
69
|
trans << " #{convert_options}" if convert_options?
|
67
70
|
trans
|
data/test/attachment_test.rb
CHANGED
@@ -14,14 +14,27 @@ class AttachmentTest < Test::Unit::TestCase
|
|
14
14
|
assert_equal "#{RAILS_ROOT}/public/fake_models/1234/fake", @attachment.path
|
15
15
|
end
|
16
16
|
|
17
|
+
should "call a proc sent to check_guard" do
|
18
|
+
@dummy = Dummy.new
|
19
|
+
@dummy.expects(:one).returns(:one)
|
20
|
+
assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
|
21
|
+
end
|
22
|
+
|
23
|
+
should "call a method name sent to check_guard" do
|
24
|
+
@dummy = Dummy.new
|
25
|
+
@dummy.expects(:one).returns(:one)
|
26
|
+
assert_equal :one, @dummy.avatar.send(:check_guard, :one)
|
27
|
+
end
|
28
|
+
|
17
29
|
context "Attachment default_options" do
|
18
30
|
setup do
|
19
31
|
rebuild_model
|
20
32
|
@old_default_options = Paperclip::Attachment.default_options.dup
|
21
33
|
@new_default_options = @old_default_options.merge({
|
22
|
-
:path
|
23
|
-
:url
|
24
|
-
:default_url
|
34
|
+
:path => "argle/bargle",
|
35
|
+
:url => "fooferon",
|
36
|
+
:default_url => "not here.png",
|
37
|
+
:keep_old_files => false
|
25
38
|
})
|
26
39
|
end
|
27
40
|
|
@@ -592,7 +605,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
592
605
|
|
593
606
|
should "commit the files to disk" do
|
594
607
|
[:large, :medium, :small].each do |style|
|
595
|
-
io = @attachment.
|
608
|
+
io = @attachment.to_file(style)
|
596
609
|
assert File.exists?(io)
|
597
610
|
assert ! io.is_a?(::Tempfile)
|
598
611
|
io.close
|
@@ -764,4 +777,94 @@ class AttachmentTest < Test::Unit::TestCase
|
|
764
777
|
end
|
765
778
|
end
|
766
779
|
end
|
780
|
+
|
781
|
+
|
782
|
+
######################
|
783
|
+
# test :keep_old_files
|
784
|
+
######################
|
785
|
+
|
786
|
+
context "An attachment with :keep_old_files => true" do
|
787
|
+
|
788
|
+
setup do
|
789
|
+
@old_defaults = Paperclip::Attachment.default_options.dup
|
790
|
+
Paperclip::Attachment.default_options.merge!( {
|
791
|
+
:path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
|
792
|
+
})
|
793
|
+
FileUtils.rm_rf("tmp")
|
794
|
+
|
795
|
+
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png" ), 'rb')
|
796
|
+
@file_2 = File.new(File.join(File.dirname(__FILE__), "fixtures", "50x50.png"), 'rb')
|
797
|
+
|
798
|
+
rebuild_model
|
799
|
+
@instance = Dummy.new
|
800
|
+
|
801
|
+
@attachment = Paperclip::Attachment.new(:avatar, @instance, {
|
802
|
+
:keep_old_files => true,
|
803
|
+
:styles => {:small => "32x32#"}
|
804
|
+
})
|
805
|
+
@attachment.assign(@file)
|
806
|
+
@attachment.save
|
807
|
+
end
|
808
|
+
|
809
|
+
teardown do
|
810
|
+
@file.close
|
811
|
+
@file_2.close
|
812
|
+
Paperclip::Attachment.default_options.merge!(@old_defaults)
|
813
|
+
end
|
814
|
+
|
815
|
+
should "return the real urls" do
|
816
|
+
assert_match %r{^/system/avatars/#{@instance.id}/original/5k\.png}, @attachment.url
|
817
|
+
assert_match %r{^/system/avatars/#{@instance.id}/small/5k\.png} , @attachment.url(:small)
|
818
|
+
end
|
819
|
+
|
820
|
+
should "commit the files to disk" do
|
821
|
+
assert File.exists?(@attachment.path(:original))
|
822
|
+
assert File.exists?(@attachment.path(:small ))
|
823
|
+
end
|
824
|
+
|
825
|
+
|
826
|
+
context "after assigning a new file" do
|
827
|
+
setup do
|
828
|
+
@previous_files_path = @attachment.styles.keys.collect do |style|
|
829
|
+
@attachment.path(style)
|
830
|
+
end
|
831
|
+
@attachment.assign @file_2
|
832
|
+
@attachment.save
|
833
|
+
end
|
834
|
+
|
835
|
+
should "NOT delete the previous files after assigning nil and saving" do
|
836
|
+
@previous_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
|
837
|
+
end
|
838
|
+
end
|
839
|
+
|
840
|
+
|
841
|
+
context "" do
|
842
|
+
setup do
|
843
|
+
@old_files_path = @attachment.styles.keys.collect do |style|
|
844
|
+
@attachment.path(style)
|
845
|
+
end
|
846
|
+
end
|
847
|
+
|
848
|
+
should "NOT delete the files after assigning nil and saving" do
|
849
|
+
@attachment.expects_instance_write_with_nil___in_the_4_paperclip_columns
|
850
|
+
@attachment.assign nil
|
851
|
+
@attachment.save
|
852
|
+
@old_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
|
853
|
+
end
|
854
|
+
|
855
|
+
should "NOT delete the files when you call #clear and #save" do
|
856
|
+
@attachment.expects_instance_write_with_nil___in_the_4_paperclip_columns
|
857
|
+
@attachment.clear
|
858
|
+
@attachment.save
|
859
|
+
@old_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
|
860
|
+
end
|
861
|
+
|
862
|
+
should "NOT delete the files when you call #delete" do
|
863
|
+
@attachment.expects_instance_write_with_nil___in_the_4_paperclip_columns
|
864
|
+
@attachment.destroy
|
865
|
+
@old_files_path.each{|f| assert File.exists?(f), "#{f} should NOT have been deleted" }
|
866
|
+
end
|
867
|
+
end
|
868
|
+
|
869
|
+
end
|
767
870
|
end
|
data/test/helper.rb
CHANGED
@@ -97,3 +97,14 @@ end
|
|
97
97
|
def attachment options
|
98
98
|
Paperclip::Attachment.new(:avatar, FakeModel.new, options)
|
99
99
|
end
|
100
|
+
|
101
|
+
module Paperclip
|
102
|
+
class Attachment
|
103
|
+
def expects_instance_write_with_nil___in_the_4_paperclip_columns
|
104
|
+
expects(:instance_write).with(:file_name , nil)
|
105
|
+
expects(:instance_write).with(:content_type , nil)
|
106
|
+
expects(:instance_write).with(:file_size , nil)
|
107
|
+
expects(:instance_write).with(:updated_at , nil)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/test/integration_test.rb
CHANGED
@@ -379,6 +379,11 @@ class IntegrationTest < Test::Unit::TestCase
|
|
379
379
|
@files_on_s3 = s3_files_for @dummy.avatar
|
380
380
|
end
|
381
381
|
|
382
|
+
should "have the same contents as the original" do
|
383
|
+
@file.rewind
|
384
|
+
assert_equal @file.read, @files_on_s3[:original].read
|
385
|
+
end
|
386
|
+
|
382
387
|
should "write and delete its files" do
|
383
388
|
[["434x66", :original],
|
384
389
|
["300x46", :large],
|
@@ -403,10 +408,8 @@ class IntegrationTest < Test::Unit::TestCase
|
|
403
408
|
assert @dummy.valid?
|
404
409
|
assert @dummy.save
|
405
410
|
|
406
|
-
|
407
|
-
|
408
|
-
saved_keys.each do |key|
|
409
|
-
assert key.exists?
|
411
|
+
[:thumb, :medium, :large, :original].each do |style|
|
412
|
+
assert @dummy.avatar.exists?(style)
|
410
413
|
end
|
411
414
|
|
412
415
|
@dummy.avatar.clear
|
@@ -414,8 +417,8 @@ class IntegrationTest < Test::Unit::TestCase
|
|
414
417
|
assert @dummy.valid?
|
415
418
|
assert @dummy.save
|
416
419
|
|
417
|
-
|
418
|
-
assert !
|
420
|
+
[:thumb, :medium, :large, :original].each do |style|
|
421
|
+
assert ! @dummy.avatar.exists?(style)
|
419
422
|
end
|
420
423
|
|
421
424
|
@d2 = Dummy.find(@dummy.id)
|
@@ -427,7 +430,7 @@ class IntegrationTest < Test::Unit::TestCase
|
|
427
430
|
|
428
431
|
assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
|
429
432
|
[:thumb, :medium, :large, :original].each do |style|
|
430
|
-
assert_equal @dummy.avatar.to_file(style).
|
433
|
+
assert_equal @dummy.avatar.to_file(style).read, @d2.avatar.to_file(style).read
|
431
434
|
end
|
432
435
|
|
433
436
|
saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
|
@@ -435,8 +438,8 @@ class IntegrationTest < Test::Unit::TestCase
|
|
435
438
|
@d2.avatar.clear
|
436
439
|
assert @d2.save
|
437
440
|
|
438
|
-
|
439
|
-
assert !
|
441
|
+
[:thumb, :medium, :large, :original].each do |style|
|
442
|
+
assert ! @dummy.avatar.exists?(style)
|
440
443
|
end
|
441
444
|
end
|
442
445
|
|
@@ -444,7 +447,7 @@ class IntegrationTest < Test::Unit::TestCase
|
|
444
447
|
expected = @dummy.avatar.to_file
|
445
448
|
@dummy.avatar = "not a file"
|
446
449
|
assert @dummy.valid?
|
447
|
-
assert_equal expected.
|
450
|
+
assert_equal expected.read, @dummy.avatar.to_file.read
|
448
451
|
|
449
452
|
@dummy.avatar = @bad_file
|
450
453
|
assert ! @dummy.valid?
|
@@ -472,7 +475,6 @@ class IntegrationTest < Test::Unit::TestCase
|
|
472
475
|
|
473
476
|
should "have the right content type" do
|
474
477
|
headers = s3_headers_for(@dummy.avatar, :original)
|
475
|
-
p headers
|
476
478
|
assert_equal 'image/png', headers['content-type']
|
477
479
|
end
|
478
480
|
end
|
data/test/paperclip_test.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
require 'test/helper'
|
2
2
|
|
3
3
|
class PaperclipTest < Test::Unit::TestCase
|
4
|
-
[:image_magick_path, :
|
5
|
-
context "Calling Paperclip.run with
|
4
|
+
[:image_magick_path, :command_path].each do |path|
|
5
|
+
context "Calling Paperclip.run with #{path} specified" do
|
6
6
|
setup do
|
7
7
|
Paperclip.options[:image_magick_path] = nil
|
8
|
-
Paperclip.options[:
|
8
|
+
Paperclip.options[:command_path] = nil
|
9
9
|
Paperclip.options[path] = "/usr/bin"
|
10
10
|
end
|
11
11
|
|
12
|
+
should "return the expected path for path_for_command" do
|
13
|
+
assert_equal "/usr/bin/convert", Paperclip.path_for_command("convert")
|
14
|
+
end
|
15
|
+
|
12
16
|
should "execute the right command" do
|
13
17
|
Paperclip.expects(:path_for_command).with("convert").returns("/usr/bin/convert")
|
14
18
|
Paperclip.expects(:bit_bucket).returns("/dev/null")
|
@@ -21,7 +25,11 @@ class PaperclipTest < Test::Unit::TestCase
|
|
21
25
|
context "Calling Paperclip.run with no path specified" do
|
22
26
|
setup do
|
23
27
|
Paperclip.options[:image_magick_path] = nil
|
24
|
-
Paperclip.options[:
|
28
|
+
Paperclip.options[:command_path] = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return the expected path fro path_for_command" do
|
32
|
+
assert_equal "convert", Paperclip.path_for_command("convert")
|
25
33
|
end
|
26
34
|
|
27
35
|
should "execute the right command" do
|
@@ -30,38 +38,38 @@ class PaperclipTest < Test::Unit::TestCase
|
|
30
38
|
Paperclip.expects(:"`").with("convert one.jpg two.jpg 2>/dev/null")
|
31
39
|
Paperclip.run("convert", "one.jpg two.jpg")
|
32
40
|
end
|
41
|
+
end
|
33
42
|
|
34
|
-
|
43
|
+
context "Calling Paperclip.run and logging" do
|
44
|
+
setup do
|
45
|
+
Paperclip.options[:image_magick_path] = nil
|
46
|
+
Paperclip.options[:command_path] = nil
|
47
|
+
Paperclip.stubs(:bit_bucket).returns("/dev/null")
|
48
|
+
Paperclip.stubs(:log)
|
49
|
+
Paperclip.stubs(:"`").with("this is the command 2>/dev/null")
|
50
|
+
end
|
51
|
+
|
52
|
+
should "log the command when :log_command is true" do
|
35
53
|
Paperclip.options[:log_command] = true
|
36
|
-
Paperclip.expects(:bit_bucket).returns("/dev/null")
|
37
|
-
Paperclip.expects(:log).with("this is the command 2>/dev/null")
|
38
|
-
Paperclip.expects(:"`").with("this is the command 2>/dev/null")
|
39
54
|
Paperclip.run("this","is the command")
|
55
|
+
assert_received(Paperclip, :log) do |p|
|
56
|
+
p.with("this is the command 2>/dev/null")
|
57
|
+
end
|
58
|
+
assert_received(Paperclip, :`) do |p|
|
59
|
+
p.with("this is the command 2>/dev/null")
|
60
|
+
end
|
40
61
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
|
44
|
-
assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
|
45
|
-
end
|
46
62
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
@dummy.expects(:one).returns(:one)
|
58
|
-
assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
|
59
|
-
end
|
60
|
-
|
61
|
-
should "call a method name sent to check_guard" do
|
62
|
-
@dummy = Dummy.new
|
63
|
-
@dummy.expects(:one).returns(:one)
|
64
|
-
assert_equal :one, @dummy.avatar.send(:check_guard, :one)
|
63
|
+
should "not log the command when :log_command is false" do
|
64
|
+
Paperclip.options[:log_command] = false
|
65
|
+
Paperclip.run("this","is the command")
|
66
|
+
assert_received(Paperclip, :log) do |p|
|
67
|
+
p.with("this is the command 2>/dev/null").never
|
68
|
+
end
|
69
|
+
assert_received(Paperclip, :`) do |p|
|
70
|
+
p.with("this is the command 2>/dev/null")
|
71
|
+
end
|
72
|
+
end
|
65
73
|
end
|
66
74
|
|
67
75
|
context "Paperclip.bit_bucket" do
|
@@ -86,6 +94,18 @@ class PaperclipTest < Test::Unit::TestCase
|
|
86
94
|
end
|
87
95
|
end
|
88
96
|
|
97
|
+
should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
|
98
|
+
assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
|
99
|
+
end
|
100
|
+
|
101
|
+
should "raise when sent #processor and the name of a class that doesn't exist" do
|
102
|
+
assert_raises(NameError){ Paperclip.processor(:boogey_man) }
|
103
|
+
end
|
104
|
+
|
105
|
+
should "return a class when sent #processor and the name of a class under Paperclip" do
|
106
|
+
assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
|
107
|
+
end
|
108
|
+
|
89
109
|
context "An ActiveRecord model with an 'avatar' attachment" do
|
90
110
|
setup do
|
91
111
|
rebuild_model :path => "tmp/:class/omg/:style.:extension"
|
@@ -139,7 +159,8 @@ class PaperclipTest < Test::Unit::TestCase
|
|
139
159
|
end
|
140
160
|
|
141
161
|
should "be able to see the attachment definition from the subclass's class" do
|
142
|
-
assert_equal "tmp/:class/omg/:style.:extension",
|
162
|
+
assert_equal "tmp/:class/omg/:style.:extension",
|
163
|
+
SubDummy.attachment_definitions[:avatar][:path]
|
143
164
|
end
|
144
165
|
|
145
166
|
teardown do
|
data/test/storage_test.rb
CHANGED
@@ -3,6 +3,7 @@ require 'test/helper'
|
|
3
3
|
class StorageTest < Test::Unit::TestCase
|
4
4
|
context "Parsing S3 credentials" do
|
5
5
|
setup do
|
6
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
6
7
|
rebuild_model :storage => :s3,
|
7
8
|
:bucket => "testing",
|
8
9
|
:s3_credentials => {:not => :important}
|
@@ -39,6 +40,7 @@ class StorageTest < Test::Unit::TestCase
|
|
39
40
|
|
40
41
|
context "" do
|
41
42
|
setup do
|
43
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
42
44
|
rebuild_model :storage => :s3,
|
43
45
|
:s3_credentials => {},
|
44
46
|
:bucket => "bucket",
|
@@ -54,6 +56,7 @@ class StorageTest < Test::Unit::TestCase
|
|
54
56
|
end
|
55
57
|
context "" do
|
56
58
|
setup do
|
59
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
57
60
|
rebuild_model :storage => :s3,
|
58
61
|
:s3_credentials => {},
|
59
62
|
:bucket => "bucket",
|
@@ -69,6 +72,7 @@ class StorageTest < Test::Unit::TestCase
|
|
69
72
|
end
|
70
73
|
context "" do
|
71
74
|
setup do
|
75
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
72
76
|
rebuild_model :storage => :s3,
|
73
77
|
:s3_credentials => {
|
74
78
|
:production => { :bucket => "prod_bucket" },
|
@@ -88,6 +92,7 @@ class StorageTest < Test::Unit::TestCase
|
|
88
92
|
|
89
93
|
context "Parsing S3 credentials with a bucket in them" do
|
90
94
|
setup do
|
95
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
91
96
|
rebuild_model :storage => :s3,
|
92
97
|
:s3_credentials => {
|
93
98
|
:production => { :bucket => "prod_bucket" },
|
@@ -146,14 +151,7 @@ class StorageTest < Test::Unit::TestCase
|
|
146
151
|
|
147
152
|
context "and saved" do
|
148
153
|
setup do
|
149
|
-
@
|
150
|
-
@bucket_mock = stub
|
151
|
-
RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
|
152
|
-
@s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
|
153
|
-
@key_mock = stub
|
154
|
-
@bucket_mock.expects(:key).returns(@key_mock)
|
155
|
-
@key_mock.expects(:data=)
|
156
|
-
@key_mock.expects(:put).with(nil, 'public-read', 'Content-type' => 'image/png')
|
154
|
+
AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path, anything, 'testing', :content_type => 'image/png', :access => :public_read)
|
157
155
|
@dummy.save
|
158
156
|
end
|
159
157
|
|
@@ -164,13 +162,8 @@ class StorageTest < Test::Unit::TestCase
|
|
164
162
|
|
165
163
|
context "and remove" do
|
166
164
|
setup do
|
167
|
-
|
168
|
-
|
169
|
-
RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
|
170
|
-
@s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
|
171
|
-
@key_mock = stub
|
172
|
-
@bucket_mock.expects(:key).at_least(2).returns(@key_mock)
|
173
|
-
@key_mock.expects(:delete)
|
165
|
+
AWS::S3::S3Object.stubs(:exists?).returns(true)
|
166
|
+
AWS::S3::S3Object.stubs(:delete)
|
174
167
|
@dummy.destroy_attached_files
|
175
168
|
end
|
176
169
|
|
@@ -183,6 +176,7 @@ class StorageTest < Test::Unit::TestCase
|
|
183
176
|
|
184
177
|
context "An attachment with S3 storage and bucket defined as a Proc" do
|
185
178
|
setup do
|
179
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
186
180
|
rebuild_model :storage => :s3,
|
187
181
|
:bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
|
188
182
|
:s3_credentials => {:not => :important}
|
@@ -196,6 +190,7 @@ class StorageTest < Test::Unit::TestCase
|
|
196
190
|
|
197
191
|
context "An attachment with S3 storage and specific s3 headers set" do
|
198
192
|
setup do
|
193
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
199
194
|
rebuild_model :storage => :s3,
|
200
195
|
:bucket => "testing",
|
201
196
|
:path => ":attachment/:style/:basename.:extension",
|
@@ -217,17 +212,13 @@ class StorageTest < Test::Unit::TestCase
|
|
217
212
|
|
218
213
|
context "and saved" do
|
219
214
|
setup do
|
220
|
-
|
221
|
-
@
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
@key_mock.expects(:put).with(nil,
|
228
|
-
'public-read',
|
229
|
-
'Content-type' => 'image/png',
|
230
|
-
'Cache-Control' => 'max-age=31557600')
|
215
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
216
|
+
AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path,
|
217
|
+
anything,
|
218
|
+
'testing',
|
219
|
+
:content_type => 'image/png',
|
220
|
+
:access => :public_read,
|
221
|
+
'Cache-Control' => 'max-age=31557600')
|
231
222
|
@dummy.save
|
232
223
|
end
|
233
224
|
|
@@ -263,8 +254,8 @@ class StorageTest < Test::Unit::TestCase
|
|
263
254
|
|
264
255
|
teardown { @file.close }
|
265
256
|
|
266
|
-
should "still return a Tempfile when sent #
|
267
|
-
assert_equal Tempfile, @dummy.avatar.
|
257
|
+
should "still return a Tempfile when sent #to_file" do
|
258
|
+
assert_equal Tempfile, @dummy.avatar.to_file.class
|
268
259
|
end
|
269
260
|
|
270
261
|
context "and saved" do
|
data/test/thumbnail_test.rb
CHANGED
@@ -103,6 +103,44 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
+
context "being thumbnailed with source file options set" do
|
107
|
+
setup do
|
108
|
+
@thumb = Paperclip::Thumbnail.new(@file,
|
109
|
+
:geometry => "100x50#",
|
110
|
+
:source_file_options => "-strip")
|
111
|
+
end
|
112
|
+
|
113
|
+
should "have source_file_options value set" do
|
114
|
+
assert_equal "-strip", @thumb.source_file_options
|
115
|
+
end
|
116
|
+
|
117
|
+
should "send the right command to convert when sent #make" do
|
118
|
+
Paperclip.expects(:"`").with do |arg|
|
119
|
+
arg.match %r{convert\s+-strip\s+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+"x50"\s+-crop\s+"100x50\+114\+0"\s+\+repage\s+".*?"}
|
120
|
+
end
|
121
|
+
@thumb.make
|
122
|
+
end
|
123
|
+
|
124
|
+
should "create the thumbnail when sent #make" do
|
125
|
+
dst = @thumb.make
|
126
|
+
assert_match /100x50/, `identify "#{dst.path}"`
|
127
|
+
end
|
128
|
+
|
129
|
+
context "redefined to have bad source_file_options setting" do
|
130
|
+
setup do
|
131
|
+
@thumb = Paperclip::Thumbnail.new(@file,
|
132
|
+
:geometry => "100x50#",
|
133
|
+
:source_file_options => "-this-aint-no-option")
|
134
|
+
end
|
135
|
+
|
136
|
+
should "error when trying to create the thumbnail" do
|
137
|
+
assert_raises(Paperclip::PaperclipError) do
|
138
|
+
@thumb.make
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
106
144
|
context "being thumbnailed with convert options set" do
|
107
145
|
setup do
|
108
146
|
@thumb = Paperclip::Thumbnail.new(@file,
|
@@ -140,6 +178,18 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
140
178
|
end
|
141
179
|
end
|
142
180
|
end
|
181
|
+
|
182
|
+
context "being thumbnailed with a blank geometry string" do
|
183
|
+
setup do
|
184
|
+
@thumb = Paperclip::Thumbnail.new(@file,
|
185
|
+
:geometry => "",
|
186
|
+
:convert_options => "-gravity center -crop \"300x300+0-0\"")
|
187
|
+
end
|
188
|
+
|
189
|
+
should "not get resized by default" do
|
190
|
+
assert_no_match(/-resize/, @thumb.transformation_command)
|
191
|
+
end
|
192
|
+
end
|
143
193
|
end
|
144
194
|
|
145
195
|
context "A multipage PDF" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joshpuetz-paperclip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.0.
|
4
|
+
version: 2.3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Yurek
|
@@ -95,7 +95,6 @@ files:
|
|
95
95
|
- shoulda_macros/paperclip.rb
|
96
96
|
has_rdoc: true
|
97
97
|
homepage: http://www.thoughtbot.com/projects/paperclip
|
98
|
-
licenses:
|
99
98
|
post_install_message:
|
100
99
|
rdoc_options:
|
101
100
|
- --line-numbers
|
@@ -117,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
116
|
requirements:
|
118
117
|
- ImageMagick
|
119
118
|
rubyforge_project: paperclip
|
120
|
-
rubygems_version: 1.
|
119
|
+
rubygems_version: 1.2.0
|
121
120
|
signing_key:
|
122
121
|
specification_version: 2
|
123
122
|
summary: File attachments as attributes for ActiveRecord
|