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.

@@ -43,7 +43,7 @@ end
43
43
  # documentation for Paperclip::ClassMethods for more useful information.
44
44
  module Paperclip
45
45
 
46
- VERSION = "2.2.3"
46
+ VERSION = "2.2.4"
47
47
 
48
48
  class << self
49
49
  # Provides configurability to Paperclip. There are a number of options available, such as:
@@ -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 => lambda{|attachment,style| RAILS_ROOT },
192
- :rails_env => lambda{|attachment,style| RAILS_ENV },
193
- :class => lambda do |attachment,style|
194
- attachment.instance.class.name.underscore.pluralize
195
- end,
196
- :basename => lambda do |attachment,style|
197
- attachment.original_filename.gsub(/#{File.extname(attachment.original_filename)}$/, "")
198
- end,
199
- :extension => lambda do |attachment,style|
200
- ((style = attachment.styles[style]) && style[:format]) ||
201
- File.extname(attachment.original_filename).gsub(/^\.+/, "")
202
- end,
203
- :id => lambda{|attachment,style| attachment.instance.id },
204
- :id_partition => lambda do |attachment, style|
205
- ("%09d" % attachment.instance.id).scan(/\d{3}/).join("/")
206
- end,
207
- :attachment => lambda{|attachment,style| attachment.name.to_s.downcase.pluralize },
208
- :style => lambda{|attachment,style| style || attachment.default_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, message) if message
400
+ [message].flatten.each {|m| instance.errors.add(name, m) }
391
401
  end
392
402
  end
393
403
 
@@ -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
 
@@ -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')
@@ -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
@@ -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
@@ -9,6 +9,7 @@ gem 'sqlite3-ruby'
9
9
 
10
10
  require 'active_record'
11
11
  require 'active_support'
12
+ require 'action_controller'
12
13
  begin
13
14
  require 'ruby-debug'
14
15
  rescue LoadError
@@ -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
@@ -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.3
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-07 00:00:00 -05:00
12
+ date: 2009-02-09 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency