paperclip 2.2.3 → 2.2.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of paperclip might be problematic. Click here for more details.
- data/lib/paperclip.rb +1 -1
- data/lib/paperclip/attachment.rb +30 -20
- data/lib/paperclip/processor.rb +5 -4
- data/lib/paperclip/storage.rb +3 -0
- data/lib/paperclip/thumbnail.rb +1 -1
- data/test/attachment_test.rb +107 -2
- data/test/helper.rb +1 -0
- data/test/processor_test.rb +2 -2
- data/test/storage_test.rb +13 -0
- metadata +2 -2
data/lib/paperclip.rb
CHANGED
data/lib/paperclip/attachment.rb
CHANGED
@@ -28,8 +28,11 @@ module Paperclip
|
|
28
28
|
options = self.class.default_options.merge(options)
|
29
29
|
|
30
30
|
@url = options[:url]
|
31
|
+
@url = @url.call(self) if @url.is_a?(Proc)
|
31
32
|
@path = options[:path]
|
33
|
+
@path = @path.call(self) if @path.is_a?(Proc)
|
32
34
|
@styles = options[:styles]
|
35
|
+
@styles = @styles.call(self) if @styles.is_a?(Proc)
|
33
36
|
@default_url = options[:default_url]
|
34
37
|
@validations = options[:validations]
|
35
38
|
@default_style = options[:default_style]
|
@@ -188,24 +191,31 @@ module Paperclip
|
|
188
191
|
# necessary.
|
189
192
|
def self.interpolations
|
190
193
|
@interpolations ||= {
|
191
|
-
:rails_root
|
192
|
-
:rails_env
|
193
|
-
:class
|
194
|
-
|
195
|
-
|
196
|
-
:basename
|
197
|
-
|
198
|
-
|
199
|
-
:extension
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
:id
|
204
|
-
:id_partition
|
205
|
-
|
206
|
-
|
207
|
-
:attachment
|
208
|
-
:style
|
194
|
+
:rails_root => lambda{|attachment,style| RAILS_ROOT },
|
195
|
+
:rails_env => lambda{|attachment,style| RAILS_ENV },
|
196
|
+
:class => lambda do |attachment,style|
|
197
|
+
attachment.instance.class.name.underscore.pluralize
|
198
|
+
end,
|
199
|
+
:basename => lambda do |attachment,style|
|
200
|
+
attachment.original_filename.gsub(/#{File.extname(attachment.original_filename)}$/, "")
|
201
|
+
end,
|
202
|
+
:extension => lambda do |attachment,style|
|
203
|
+
((style = attachment.styles[style]) && style[:format]) ||
|
204
|
+
File.extname(attachment.original_filename).gsub(/^\.+/, "")
|
205
|
+
end,
|
206
|
+
:id => lambda{|attachment,style| attachment.instance.id },
|
207
|
+
:id_partition => lambda do |attachment, style|
|
208
|
+
("%09d" % attachment.instance.id).scan(/\d{3}/).join("/")
|
209
|
+
end,
|
210
|
+
:attachment => lambda{|attachment,style| attachment.name.to_s.downcase.pluralize },
|
211
|
+
:style => lambda{|attachment,style| style || attachment.default_style },
|
212
|
+
:relative_root => lambda do |attachment,style|
|
213
|
+
if ActionController::AbstractRequest.respond_to?(:relative_url_root)
|
214
|
+
ActionController::AbstractRequest.relative_url_root
|
215
|
+
elsif ActionController::Base.respond_to?(:relative_url_root)
|
216
|
+
ActionController::Base.relative_url_root
|
217
|
+
end
|
218
|
+
end
|
209
219
|
}
|
210
220
|
end
|
211
221
|
|
@@ -350,7 +360,7 @@ module Paperclip
|
|
350
360
|
raise RuntimeError.new("Style #{name} has no processors defined.") if args[:processors].blank?
|
351
361
|
@queued_for_write[name] = args[:processors].inject(@queued_for_write[:original]) do |file, processor|
|
352
362
|
log("Processing #{name} #{file} in the #{processor} processor.")
|
353
|
-
Paperclip.processor(processor).make(file, args)
|
363
|
+
Paperclip.processor(processor).make(file, args, self)
|
354
364
|
end
|
355
365
|
rescue PaperclipError => e
|
356
366
|
log("An error was received while processing: #{e.inspect}")
|
@@ -387,7 +397,7 @@ module Paperclip
|
|
387
397
|
|
388
398
|
def flush_errors #:nodoc:
|
389
399
|
@errors.each do |error, message|
|
390
|
-
instance.errors.add(name,
|
400
|
+
[message].flatten.each {|m| instance.errors.add(name, m) }
|
391
401
|
end
|
392
402
|
end
|
393
403
|
|
data/lib/paperclip/processor.rb
CHANGED
@@ -17,18 +17,19 @@ module Paperclip
|
|
17
17
|
# See Paperclip.run for more information about using command-line
|
18
18
|
# utilities from within Processors.
|
19
19
|
class Processor
|
20
|
-
attr_accessor :file, :options
|
20
|
+
attr_accessor :file, :options, :attachment
|
21
21
|
|
22
|
-
def initialize file, options = {}
|
22
|
+
def initialize file, options = {}, attachment = nil
|
23
23
|
@file = file
|
24
24
|
@options = options
|
25
|
+
@attachment = attachment
|
25
26
|
end
|
26
27
|
|
27
28
|
def make
|
28
29
|
end
|
29
30
|
|
30
|
-
def self.make file, options = {}
|
31
|
-
new(file, options).make
|
31
|
+
def self.make file, options = {}, attachment = nil
|
32
|
+
new(file, options, attachment).make
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
data/lib/paperclip/storage.rb
CHANGED
@@ -106,6 +106,8 @@ module Paperclip
|
|
106
106
|
# * +bucket+: This is the name of the S3 bucket that will store your files. Remember
|
107
107
|
# that the bucket must be unique across all of Amazon S3. If the bucket does not exist
|
108
108
|
# Paperclip will attempt to create it. The bucket name will not be interpolated.
|
109
|
+
# You can define the bucket as a Proc if you want to determine it's name at runtime.
|
110
|
+
# Paperclip will call that Proc with attachment as the only argument.
|
109
111
|
# * +url+: There are two options for the S3 url. You can choose to have the bucket's name
|
110
112
|
# placed domain-style (bucket.s3.amazonaws.com) or path-style (s3.amazonaws.com/bucket).
|
111
113
|
# Normally, this won't matter in the slightest and you can leave the default (which is
|
@@ -122,6 +124,7 @@ module Paperclip
|
|
122
124
|
base.instance_eval do
|
123
125
|
@s3_credentials = parse_credentials(@options[:s3_credentials])
|
124
126
|
@bucket = @options[:bucket] || @s3_credentials[:bucket]
|
127
|
+
@bucket = @bucket.call(self) if @bucket.is_a?(Proc)
|
125
128
|
@s3_options = @options[:s3_options] || {}
|
126
129
|
@s3_permissions = @options[:s3_permissions] || 'public-read'
|
127
130
|
@s3_protocol = @options[:s3_protocol] || (@s3_permissions == 'public-read' ? 'http' : 'https')
|
data/lib/paperclip/thumbnail.rb
CHANGED
@@ -10,7 +10,7 @@ module Paperclip
|
|
10
10
|
# unless specified. Thumbnail creation will raise no errors unless
|
11
11
|
# +whiny+ is true (which it is, by default. If +convert_options+ is
|
12
12
|
# set, the options will be appended to the convert command upon image conversion
|
13
|
-
def initialize file, options = {}
|
13
|
+
def initialize file, options = {}, attachment = nil
|
14
14
|
super
|
15
15
|
geometry = options[:geometry]
|
16
16
|
@file = file
|
data/test/attachment_test.rb
CHANGED
@@ -106,6 +106,36 @@ class AttachmentTest < Test::Unit::TestCase
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
+
context "An attachment with a :relative_root interpolation" do
|
110
|
+
setup do
|
111
|
+
rebuild_model :url => ":relative_root/:id.png"
|
112
|
+
@dummy = Dummy.new
|
113
|
+
@dummy.stubs(:id).returns(1024)
|
114
|
+
@dummy.avatar = StringIO.new(".")
|
115
|
+
|
116
|
+
ActionController::Base.stubs(:respond_to?).with(:relative_url_root).returns(false)
|
117
|
+
ActionController::Base.stubs(:relative_url_root).returns("/base")
|
118
|
+
ActionController::AbstractRequest.stubs(:respond_to?).with(:relative_url_root).returns(false)
|
119
|
+
ActionController::AbstractRequest.stubs(:relative_url_root).returns("/request")
|
120
|
+
end
|
121
|
+
|
122
|
+
should "return the proper path when the path is nil" do
|
123
|
+
assert_equal "/1024.png", @dummy.avatar.url(:original, false)
|
124
|
+
end
|
125
|
+
|
126
|
+
should "return the proper path when using Rails < 2.1" do
|
127
|
+
ActionController::AbstractRequest.expects(:respond_to?).with(:relative_url_root).returns(true)
|
128
|
+
ActionController::AbstractRequest.expects(:relative_url_root).returns("/request")
|
129
|
+
assert_equal "/request/1024.png", @dummy.avatar.url(:original, false)
|
130
|
+
end
|
131
|
+
|
132
|
+
should "return the proper path when using Rails >= 2.1" do
|
133
|
+
ActionController::Base.expects(:respond_to?).with(:relative_url_root).returns(true)
|
134
|
+
ActionController::Base.expects(:relative_url_root).returns("/base")
|
135
|
+
assert_equal "/base/1024.png", @dummy.avatar.url(:original, false)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
109
139
|
context "An attachment with :convert_options" do
|
110
140
|
setup do
|
111
141
|
rebuild_model :styles => {
|
@@ -165,6 +195,60 @@ class AttachmentTest < Test::Unit::TestCase
|
|
165
195
|
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:large)
|
166
196
|
end
|
167
197
|
end
|
198
|
+
|
199
|
+
context "An attachment with :path that is a proc" do
|
200
|
+
setup do
|
201
|
+
rebuild_model :path => lambda{ |attachment| "path/#{attachment.instance.other}.:extension" }
|
202
|
+
|
203
|
+
@file = File.new(File.join(File.dirname(__FILE__),
|
204
|
+
"fixtures",
|
205
|
+
"5k.png"), 'rb')
|
206
|
+
@dummyA = Dummy.new(:other => 'a')
|
207
|
+
@dummyA.avatar = @file
|
208
|
+
@dummyB = Dummy.new(:other => 'b')
|
209
|
+
@dummyB.avatar = @file
|
210
|
+
end
|
211
|
+
|
212
|
+
teardown { @file.close }
|
213
|
+
|
214
|
+
should "return correct path" do
|
215
|
+
assert_equal "path/a.png", @dummyA.avatar.path
|
216
|
+
assert_equal "path/b.png", @dummyB.avatar.path
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "An attachment with :styles that is a proc" do
|
221
|
+
setup do
|
222
|
+
rebuild_model :styles => lambda{ |attachment| {:thumb => "50x50#", :large => "400x400"} }
|
223
|
+
|
224
|
+
@attachment = Dummy.new.avatar
|
225
|
+
end
|
226
|
+
|
227
|
+
should "have the correct geometry" do
|
228
|
+
assert_equal "50x50#", @attachment.styles[:thumb][:geometry]
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "An attachment with :url that is a proc" do
|
233
|
+
setup do
|
234
|
+
rebuild_model :url => lambda{ |attachment| "path/#{attachment.instance.other}.:extension" }
|
235
|
+
|
236
|
+
@file = File.new(File.join(File.dirname(__FILE__),
|
237
|
+
"fixtures",
|
238
|
+
"5k.png"), 'rb')
|
239
|
+
@dummyA = Dummy.new(:other => 'a')
|
240
|
+
@dummyA.avatar = @file
|
241
|
+
@dummyB = Dummy.new(:other => 'b')
|
242
|
+
@dummyB.avatar = @file
|
243
|
+
end
|
244
|
+
|
245
|
+
teardown { @file.close }
|
246
|
+
|
247
|
+
should "return correct url" do
|
248
|
+
assert_equal "path/a.png", @dummyA.avatar.url(:original, false)
|
249
|
+
assert_equal "path/b.png", @dummyB.avatar.url(:original, false)
|
250
|
+
end
|
251
|
+
end
|
168
252
|
|
169
253
|
geometry_specs = [
|
170
254
|
[ lambda{|z| "50x50#" }, :png ],
|
@@ -211,6 +295,22 @@ class AttachmentTest < Test::Unit::TestCase
|
|
211
295
|
end
|
212
296
|
end
|
213
297
|
end
|
298
|
+
|
299
|
+
context "An attachment with erroring processor" do
|
300
|
+
setup do
|
301
|
+
rebuild_model :processor => [:thumbnail], :styles => { :small => '' }, :whiny_thumbnails => true
|
302
|
+
@dummy = Dummy.new
|
303
|
+
Paperclip::Thumbnail.expects(:make).raises(Paperclip::PaperclipError, "cannot be processed.")
|
304
|
+
@file = StringIO.new("...")
|
305
|
+
@file.stubs(:to_tempfile).returns(@file)
|
306
|
+
@dummy.avatar = @file
|
307
|
+
end
|
308
|
+
|
309
|
+
should "correctly forward processing error message to the instance" do
|
310
|
+
@dummy.valid?
|
311
|
+
assert_contains @dummy.errors.full_messages, "Avatar cannot be processed."
|
312
|
+
end
|
313
|
+
end
|
214
314
|
|
215
315
|
context "An attachment with multiple processors" do
|
216
316
|
setup do
|
@@ -229,8 +329,13 @@ class AttachmentTest < Test::Unit::TestCase
|
|
229
329
|
|
230
330
|
before_should "call #make on all specified processors" do
|
231
331
|
expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => nil, :convert_options => ""})
|
232
|
-
Paperclip::Thumbnail.expects(:make).with(@file, expected_params).returns(@file)
|
233
|
-
Paperclip::Test.expects(:make).with(@file, expected_params).returns(@file)
|
332
|
+
Paperclip::Thumbnail.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
333
|
+
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
334
|
+
end
|
335
|
+
|
336
|
+
before_should "call #make with attachment passed as third argument" do
|
337
|
+
expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => nil, :convert_options => ""})
|
338
|
+
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
234
339
|
end
|
235
340
|
end
|
236
341
|
end
|
data/test/helper.rb
CHANGED
data/test/processor_test.rb
CHANGED
@@ -4,7 +4,7 @@ class ProcessorTest < Test::Unit::TestCase
|
|
4
4
|
should "instantiate and call #make when sent #make to the class" do
|
5
5
|
processor = mock
|
6
6
|
processor.expects(:make).with()
|
7
|
-
Paperclip::Processor.expects(:new).with(:one, :two).returns(processor)
|
8
|
-
Paperclip::Processor.make(:one, :two)
|
7
|
+
Paperclip::Processor.expects(:new).with(:one, :two, :three).returns(processor)
|
8
|
+
Paperclip::Processor.make(:one, :two, :three)
|
9
9
|
end
|
10
10
|
end
|
data/test/storage_test.rb
CHANGED
@@ -126,6 +126,19 @@ class StorageTest < Test::Unit::TestCase
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
129
|
+
|
130
|
+
context "An attachment with S3 storage and bucket defined as a Proc" do
|
131
|
+
setup do
|
132
|
+
rebuild_model :storage => :s3,
|
133
|
+
:bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
|
134
|
+
:s3_credentials => {:not => :important}
|
135
|
+
end
|
136
|
+
|
137
|
+
should "get the right bucket name" do
|
138
|
+
assert "bucket_a", Dummy.new(:other => 'a').avatar.bucket_name
|
139
|
+
assert "bucket_b", Dummy.new(:other => 'b').avatar.bucket_name
|
140
|
+
end
|
141
|
+
end
|
129
142
|
|
130
143
|
context "An attachment with S3 storage and specific s3 headers set" do
|
131
144
|
setup do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paperclip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Yurek
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-02-
|
12
|
+
date: 2009-02-09 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|