joshpuetz-paperclip 2.3.0.1 → 2.3.0.2
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/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
|