bteitelb-paperclip 2.3.1.13 → 2.3.1.14
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/lib/paperclip.rb +14 -18
- data/lib/paperclip/attachment.rb +125 -46
- data/lib/paperclip/interpolations.rb +17 -17
- data/lib/paperclip/iostream.rb +1 -2
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +3 -2
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +6 -6
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +3 -5
- data/lib/paperclip/storage.rb +9 -13
- data/lib/paperclip/thumbnail.rb +0 -2
- data/test/attachment_test.rb +38 -22
- data/test/helper.rb +1 -1
- data/test/iostream_test.rb +2 -9
- data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -1
- data/test/matchers/validate_attachment_presence_matcher_test.rb +1 -3
- data/test/matchers/validate_attachment_size_matcher_test.rb +0 -1
- data/test/paperclip_test.rb +41 -12
- data/test/storage_test.rb +0 -27
- data/test/thumbnail_test.rb +1 -1
- metadata +1 -2
- data/lib/paperclip/style.rb +0 -90
data/Rakefile
CHANGED
@@ -75,8 +75,8 @@ spec = Gem::Specification.new do |s|
|
|
75
75
|
s.extra_rdoc_files = FileList["README*"].to_a
|
76
76
|
s.rdoc_options << '--line-numbers' << '--inline-source'
|
77
77
|
s.requirements << "ImageMagick"
|
78
|
-
s.add_development_dependency 'shoulda'
|
79
|
-
s.add_development_dependency 'jferris-mocha', '
|
78
|
+
s.add_development_dependency 'thoughtbot-shoulda'
|
79
|
+
s.add_development_dependency 'jferris-mocha', '= 0.9.5.0.1241126838'
|
80
80
|
s.add_development_dependency 'aws-s3'
|
81
81
|
s.add_development_dependency 'sqlite3-ruby'
|
82
82
|
s.add_development_dependency 'activerecord'
|
data/lib/paperclip.rb
CHANGED
@@ -34,7 +34,6 @@ require 'paperclip/processor'
|
|
34
34
|
require 'paperclip/thumbnail'
|
35
35
|
require 'paperclip/storage'
|
36
36
|
require 'paperclip/interpolations'
|
37
|
-
require 'paperclip/style'
|
38
37
|
require 'paperclip/attachment'
|
39
38
|
if defined? RAILS_ROOT
|
40
39
|
Dir.glob(File.join(File.expand_path(RAILS_ROOT), "lib", "paperclip_processors", "*.rb")).each do |processor|
|
@@ -240,7 +239,7 @@ module Paperclip
|
|
240
239
|
|
241
240
|
validates_each(name) do |record, attr, value|
|
242
241
|
attachment = record.attachment_for(name)
|
243
|
-
attachment.send(:flush_errors)
|
242
|
+
attachment.send(:flush_errors) unless attachment.valid?
|
244
243
|
end
|
245
244
|
end
|
246
245
|
|
@@ -258,13 +257,13 @@ module Paperclip
|
|
258
257
|
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
|
259
258
|
range = (min..max)
|
260
259
|
message = options[:message] || "file size must be between :min and :max bytes."
|
261
|
-
message = message.gsub(/:min/, min.to_s).gsub(/:max/, max.to_s)
|
262
260
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
261
|
+
attachment_definitions[name][:validations] << [:size, {:min => min,
|
262
|
+
:max => max,
|
263
|
+
:range => range,
|
264
|
+
:message => message,
|
265
|
+
:if => options[:if],
|
266
|
+
:unless => options[:unless]}]
|
268
267
|
end
|
269
268
|
|
270
269
|
# Adds errors if thumbnail creation fails. The same as specifying :whiny_thumbnails => true.
|
@@ -282,10 +281,9 @@ module Paperclip
|
|
282
281
|
# * +unless+: Same as +if+ but validates if lambda or method returns false.
|
283
282
|
def validates_attachment_presence name, options = {}
|
284
283
|
message = options[:message] || "must be set."
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
:unless => options[:unless]
|
284
|
+
attachment_definitions[name][:validations] << [:presence, {:message => message,
|
285
|
+
:if => options[:if],
|
286
|
+
:unless => options[:unless]}]
|
289
287
|
end
|
290
288
|
|
291
289
|
# Places ActiveRecord-style validations on the content type of the file
|
@@ -305,12 +303,10 @@ module Paperclip
|
|
305
303
|
# model, content_type validation will work _ONLY upon assignment_ and
|
306
304
|
# re-validation after the instance has been reloaded will always succeed.
|
307
305
|
def validates_attachment_content_type name, options = {}
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
end
|
313
|
-
end
|
306
|
+
attachment_definitions[name][:validations] << [:content_type, {:content_type => options[:content_type],
|
307
|
+
:message => options[:message],
|
308
|
+
:if => options[:if],
|
309
|
+
:unless => options[:unless]}]
|
314
310
|
end
|
315
311
|
|
316
312
|
# Returns the attachment definitions defined by each call to
|
data/lib/paperclip/attachment.rb
CHANGED
@@ -9,19 +9,18 @@ module Paperclip
|
|
9
9
|
|
10
10
|
def self.default_options
|
11
11
|
@default_options ||= {
|
12
|
-
:url
|
13
|
-
:path
|
14
|
-
:styles
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
|
12
|
+
:url => "/system/:attachment/:id/:style/:filename",
|
13
|
+
:path => ":rails_root/public:url",
|
14
|
+
:styles => {},
|
15
|
+
:default_url => "/:attachment/:style/missing.png",
|
16
|
+
:default_style => :original,
|
17
|
+
:validations => [],
|
18
|
+
:storage => :filesystem,
|
19
|
+
:whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
|
21
20
|
}
|
22
21
|
end
|
23
22
|
|
24
|
-
attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :
|
23
|
+
attr_reader :name, :instance, :styles, :default_style, :convert_options, :queued_for_write, :options
|
25
24
|
|
26
25
|
# Creates an Attachment object. +name+ is the name of the attachment,
|
27
26
|
# +instance+ is the ActiveRecord object instance it's attached to, and
|
@@ -37,13 +36,14 @@ module Paperclip
|
|
37
36
|
@path = options[:path]
|
38
37
|
@path = @path.call(self) if @path.is_a?(Proc)
|
39
38
|
@styles = options[:styles]
|
40
|
-
@
|
39
|
+
@styles = @styles.call(self) if @styles.is_a?(Proc)
|
41
40
|
@default_url = options[:default_url]
|
41
|
+
@validations = options[:validations]
|
42
42
|
@default_style = options[:default_style]
|
43
43
|
@storage = options[:storage]
|
44
44
|
@whiny = options[:whiny_thumbnails] || options[:whiny]
|
45
|
-
@convert_options = options[:convert_options]
|
46
|
-
@processors = options[:processors]
|
45
|
+
@convert_options = options[:convert_options] || {}
|
46
|
+
@processors = options[:processors] || [:thumbnail]
|
47
47
|
@options = options
|
48
48
|
@queued_for_delete = []
|
49
49
|
@queued_for_write = {}
|
@@ -52,29 +52,18 @@ module Paperclip
|
|
52
52
|
@validation_errors = nil
|
53
53
|
@dirty = false
|
54
54
|
|
55
|
+
normalize_style_definition
|
55
56
|
initialize_storage
|
56
57
|
end
|
57
|
-
|
58
|
-
def styles
|
59
|
-
unless @normalized_styles
|
60
|
-
@normalized_styles = {}
|
61
|
-
(@styles.respond_to?(:call) ? @styles.call(self) : @styles).each do |name, args|
|
62
|
-
@normalized_styles[name] = Paperclip::Style.new(name, args, self)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
@normalized_styles
|
66
|
-
end
|
67
|
-
|
68
|
-
def processors
|
69
|
-
@processors.respond_to?(:call) ? @processors.call(instance) : @processors
|
70
|
-
end
|
71
58
|
|
72
59
|
# What gets called when you call instance.attachment = File. It clears
|
73
|
-
# errors, assigns attributes,
|
60
|
+
# errors, assigns attributes, processes the file, and runs validations. It
|
74
61
|
# also queues up the previous file for deletion, to be flushed away on
|
75
62
|
# #save of its host. In addition to form uploads, you can also assign
|
76
63
|
# another Paperclip attachment:
|
77
64
|
# new_user.avatar = old_user.avatar
|
65
|
+
# If the file that is assigned is not valid, the processing (i.e.
|
66
|
+
# thumbnailing, etc) will NOT be run.
|
78
67
|
def assign uploaded_file
|
79
68
|
ensure_required_accessors!
|
80
69
|
|
@@ -104,7 +93,7 @@ module Paperclip
|
|
104
93
|
|
105
94
|
@dirty = true
|
106
95
|
|
107
|
-
post_process
|
96
|
+
post_process if valid?
|
108
97
|
|
109
98
|
# Reset the file size if the original file was reprocessed.
|
110
99
|
instance_write(:file_size, @queued_for_write[:original].size.to_i)
|
@@ -126,6 +115,7 @@ module Paperclip
|
|
126
115
|
end
|
127
116
|
ensure
|
128
117
|
uploaded_file.close if close_uploaded_file
|
118
|
+
validate
|
129
119
|
end
|
130
120
|
|
131
121
|
# Returns the public URL of the attachment, with a given style. Note that
|
@@ -135,8 +125,8 @@ module Paperclip
|
|
135
125
|
# security, however, for performance reasons. set
|
136
126
|
# include_updated_timestamp to false if you want to stop the attachment
|
137
127
|
# update time appended to the url
|
138
|
-
def url
|
139
|
-
url = original_filename.nil? ? interpolate(@default_url,
|
128
|
+
def url style = default_style, include_updated_timestamp = true
|
129
|
+
url = original_filename.nil? ? interpolate(@default_url, style) : interpolate(@url, style)
|
140
130
|
include_updated_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url
|
141
131
|
end
|
142
132
|
|
@@ -144,13 +134,19 @@ module Paperclip
|
|
144
134
|
# file is stored in the filesystem the path refers to the path of the file
|
145
135
|
# on disk. If the file is stored in S3, the path is the "key" part of the
|
146
136
|
# URL, and the :bucket option refers to the S3 bucket.
|
147
|
-
def path
|
148
|
-
original_filename.nil? ? nil : interpolate(@path,
|
137
|
+
def path style = default_style
|
138
|
+
original_filename.nil? ? nil : interpolate(@path, style)
|
149
139
|
end
|
150
140
|
|
151
141
|
# Alias to +url+
|
152
|
-
def to_s
|
153
|
-
url(
|
142
|
+
def to_s style = nil
|
143
|
+
url(style)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns true if there are no errors on this attachment.
|
147
|
+
def valid?
|
148
|
+
validate
|
149
|
+
errors.empty?
|
154
150
|
end
|
155
151
|
|
156
152
|
# Returns an array containing the errors on this attachment.
|
@@ -166,10 +162,15 @@ module Paperclip
|
|
166
162
|
# Saves the file, if there are no errors. If there are, it flushes them to
|
167
163
|
# the instance's errors and returns false, cancelling the save.
|
168
164
|
def save
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
165
|
+
if valid?
|
166
|
+
flush_deletes
|
167
|
+
flush_writes
|
168
|
+
@dirty = false
|
169
|
+
true
|
170
|
+
else
|
171
|
+
flush_errors
|
172
|
+
false
|
173
|
+
end
|
173
174
|
end
|
174
175
|
|
175
176
|
# Clears out the attachment. Has the same effect as previously assigning
|
@@ -178,6 +179,7 @@ module Paperclip
|
|
178
179
|
def clear
|
179
180
|
queue_existing_for_delete
|
180
181
|
@errors = {}
|
182
|
+
@validation_errors = nil
|
181
183
|
end
|
182
184
|
|
183
185
|
# Destroys the attachment. Has the same effect as previously assigning
|
@@ -309,6 +311,82 @@ module Paperclip
|
|
309
311
|
file.nil? || (file.respond_to?(:original_filename) && file.respond_to?(:content_type))
|
310
312
|
end
|
311
313
|
|
314
|
+
def validate #:nodoc:
|
315
|
+
unless @validation_errors
|
316
|
+
@validation_errors = @validations.inject({}) do |errors, validation|
|
317
|
+
name, options = validation
|
318
|
+
errors[name] = send(:"validate_#{name}", options) if allow_validation?(options)
|
319
|
+
errors
|
320
|
+
end
|
321
|
+
@validation_errors.reject!{|k,v| v == nil }
|
322
|
+
@errors.merge!(@validation_errors)
|
323
|
+
end
|
324
|
+
@validation_errors
|
325
|
+
end
|
326
|
+
|
327
|
+
def allow_validation? options #:nodoc:
|
328
|
+
(options[:if].nil? || check_guard(options[:if])) && (options[:unless].nil? || !check_guard(options[:unless]))
|
329
|
+
end
|
330
|
+
|
331
|
+
def check_guard guard #:nodoc:
|
332
|
+
if guard.respond_to? :call
|
333
|
+
guard.call(instance)
|
334
|
+
elsif ! guard.blank?
|
335
|
+
instance.send(guard.to_s)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def validate_size options #:nodoc:
|
340
|
+
if file? && !options[:range].include?(size.to_i)
|
341
|
+
options[:message].gsub(/:min/, options[:min].to_s).gsub(/:max/, options[:max].to_s)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def validate_presence options #:nodoc:
|
346
|
+
options[:message] unless file?
|
347
|
+
end
|
348
|
+
|
349
|
+
def validate_content_type options #:nodoc:
|
350
|
+
valid_types = [options[:content_type]].flatten
|
351
|
+
unless original_filename.blank?
|
352
|
+
unless valid_types.blank?
|
353
|
+
content_type = instance_read(:content_type)
|
354
|
+
unless valid_types.any?{|t| content_type.nil? || t === content_type }
|
355
|
+
options[:message] || "is not one of the allowed file types."
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def normalize_style_definition #:nodoc:
|
362
|
+
@styles.each do |name, args|
|
363
|
+
unless args.is_a? Hash
|
364
|
+
dimensions, format = [args, nil].flatten[0..1]
|
365
|
+
format = nil if format.blank?
|
366
|
+
@styles[name] = {
|
367
|
+
:processors => @processors,
|
368
|
+
:geometry => dimensions,
|
369
|
+
:format => format,
|
370
|
+
:whiny => @whiny,
|
371
|
+
:convert_options => extra_options_for(name)
|
372
|
+
}
|
373
|
+
else
|
374
|
+
@styles[name] = {
|
375
|
+
:processors => @processors,
|
376
|
+
:whiny => @whiny,
|
377
|
+
:convert_options => extra_options_for(name)
|
378
|
+
}.merge(@styles[name])
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
def solidify_style_definitions #:nodoc:
|
384
|
+
@styles.each do |name, args|
|
385
|
+
@styles[name][:geometry] = @styles[name][:geometry].call(instance) if @styles[name][:geometry].respond_to?(:call)
|
386
|
+
@styles[name][:processors] = @styles[name][:processors].call(instance) if @styles[name][:processors].respond_to?(:call)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
312
390
|
def initialize_storage #:nodoc:
|
313
391
|
@storage_module = Paperclip::Storage.const_get(@storage.to_s.capitalize)
|
314
392
|
self.extend(@storage_module)
|
@@ -325,6 +403,7 @@ module Paperclip
|
|
325
403
|
|
326
404
|
def post_process #:nodoc:
|
327
405
|
return if @queued_for_write[:original].nil?
|
406
|
+
solidify_style_definitions
|
328
407
|
return if fire_events(:before)
|
329
408
|
post_process_styles
|
330
409
|
return if fire_events(:after)
|
@@ -340,11 +419,11 @@ module Paperclip
|
|
340
419
|
end
|
341
420
|
|
342
421
|
def post_process_styles #:nodoc:
|
343
|
-
styles.each do |name,
|
422
|
+
@styles.each do |name, args|
|
344
423
|
begin
|
345
|
-
raise RuntimeError.new("Style #{name} has no processors defined.") if
|
346
|
-
@queued_for_write[name] =
|
347
|
-
Paperclip.processor(processor).make(file,
|
424
|
+
raise RuntimeError.new("Style #{name} has no processors defined.") if args[:processors].blank?
|
425
|
+
@queued_for_write[name] = args[:processors].inject(@queued_for_write[:original]) do |file, processor|
|
426
|
+
Paperclip.processor(processor).make(file, args, self)
|
348
427
|
end
|
349
428
|
rescue PaperclipError => e
|
350
429
|
log("An error was received while processing: #{e.inspect}")
|
@@ -353,8 +432,8 @@ module Paperclip
|
|
353
432
|
end
|
354
433
|
end
|
355
434
|
|
356
|
-
def interpolate pattern,
|
357
|
-
Paperclip::Interpolations.interpolate(pattern, self,
|
435
|
+
def interpolate pattern, style = default_style #:nodoc:
|
436
|
+
Paperclip::Interpolations.interpolate(pattern, self, style)
|
358
437
|
end
|
359
438
|
|
360
439
|
def mime_type
|
@@ -381,7 +460,7 @@ module Paperclip
|
|
381
460
|
|
382
461
|
def queue_existing_for_delete #:nodoc:
|
383
462
|
return unless file?
|
384
|
-
@queued_for_delete += [:original,
|
463
|
+
@queued_for_delete += [:original, *@styles.keys].uniq.map do |style|
|
385
464
|
path(style) if exists?(style)
|
386
465
|
end.compact
|
387
466
|
instance_write(:file_name, nil)
|
@@ -34,30 +34,30 @@ module Paperclip
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# Returns the filename, the same way as ":basename.:extension" would.
|
37
|
-
def filename attachment,
|
38
|
-
"#{basename(attachment,
|
37
|
+
def filename attachment, style
|
38
|
+
"#{basename(attachment, style)}.#{extension(attachment, style)}"
|
39
39
|
end
|
40
40
|
|
41
41
|
# Returns the interpolated URL. Will raise an error if the url itself
|
42
42
|
# contains ":url" to prevent infinite recursion. This interpolation
|
43
43
|
# is used in the default :path to ease default specifications.
|
44
|
-
def url attachment,
|
44
|
+
def url attachment, style
|
45
45
|
raise InfiniteInterpolationError if attachment.options[:url].include?(":url")
|
46
|
-
attachment.url(
|
46
|
+
attachment.url(style, false)
|
47
47
|
end
|
48
48
|
|
49
49
|
# Returns the timestamp as defined by the <attachment>_updated_at field
|
50
|
-
def timestamp attachment,
|
50
|
+
def timestamp attachment, style
|
51
51
|
attachment.instance_read(:updated_at).to_s
|
52
52
|
end
|
53
53
|
|
54
54
|
# Returns the RAILS_ROOT constant.
|
55
|
-
def rails_root attachment,
|
55
|
+
def rails_root attachment, style
|
56
56
|
RAILS_ROOT
|
57
57
|
end
|
58
58
|
|
59
59
|
# Returns the RAILS_ENV constant.
|
60
|
-
def rails_env attachment,
|
60
|
+
def rails_env attachment, style
|
61
61
|
RAILS_ENV
|
62
62
|
end
|
63
63
|
|
@@ -65,44 +65,44 @@ module Paperclip
|
|
65
65
|
# e.g. "users" for the User class.
|
66
66
|
# NOTE: The arguments need to be optional, because some tools fetch
|
67
67
|
# all class names. Calling #class will return the expected class.
|
68
|
-
def class attachment = nil,
|
69
|
-
return super() if attachment.nil? &&
|
68
|
+
def class attachment = nil, style = nil
|
69
|
+
return super() if attachment.nil? && style.nil?
|
70
70
|
attachment.instance.class.to_s.underscore.pluralize
|
71
71
|
end
|
72
72
|
|
73
73
|
# Returns the basename of the file. e.g. "file" for "file.jpg"
|
74
|
-
def basename attachment,
|
74
|
+
def basename attachment, style
|
75
75
|
attachment.original_filename.gsub(/#{File.extname(attachment.original_filename)}$/, "")
|
76
76
|
end
|
77
77
|
|
78
78
|
# Returns the extension of the file. e.g. "jpg" for "file.jpg"
|
79
79
|
# If the style has a format defined, it will return the format instead
|
80
80
|
# of the actual extension.
|
81
|
-
def extension attachment,
|
82
|
-
((style = attachment.styles[
|
81
|
+
def extension attachment, style
|
82
|
+
((style = attachment.styles[style]) && style[:format]) ||
|
83
83
|
File.extname(attachment.original_filename).gsub(/^\.+/, "")
|
84
84
|
end
|
85
85
|
|
86
86
|
# Returns the id of the instance.
|
87
|
-
def id attachment,
|
87
|
+
def id attachment, style
|
88
88
|
attachment.instance.id
|
89
89
|
end
|
90
90
|
|
91
91
|
# Returns the id of the instance in a split path form. e.g. returns
|
92
92
|
# 000/001/234 for an id of 1234.
|
93
|
-
def id_partition attachment,
|
93
|
+
def id_partition attachment, style
|
94
94
|
("%09d" % attachment.instance.id).scan(/\d{3}/).join("/")
|
95
95
|
end
|
96
96
|
|
97
97
|
# Returns the pluralized form of the attachment name. e.g.
|
98
98
|
# "avatars" for an attachment of :avatar
|
99
|
-
def attachment attachment,
|
99
|
+
def attachment attachment, style
|
100
100
|
attachment.name.to_s.downcase.pluralize
|
101
101
|
end
|
102
102
|
|
103
103
|
# Returns the style, or the default style if nil is supplied.
|
104
|
-
def style attachment,
|
105
|
-
|
104
|
+
def style attachment, style
|
105
|
+
style || attachment.default_style
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
data/lib/paperclip/iostream.rb
CHANGED
@@ -4,8 +4,7 @@ module IOStream
|
|
4
4
|
|
5
5
|
# Returns a Tempfile containing the contents of the readable object.
|
6
6
|
def to_tempfile
|
7
|
-
|
8
|
-
tempfile = Paperclip::Tempfile.new(File.basename(name))
|
7
|
+
tempfile = Tempfile.new("stream")
|
9
8
|
tempfile.binmode
|
10
9
|
self.stream_to(tempfile)
|
11
10
|
end
|
@@ -46,8 +46,9 @@ module Paperclip
|
|
46
46
|
types.all? do |type|
|
47
47
|
file = StringIO.new(".")
|
48
48
|
file.content_type = type
|
49
|
-
|
50
|
-
|
49
|
+
attachment = @subject.new.attachment_for(@attachment_name)
|
50
|
+
attachment.assign(file)
|
51
|
+
attachment.errors[:content_type].nil?
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
@@ -30,16 +30,16 @@ module Paperclip
|
|
30
30
|
protected
|
31
31
|
|
32
32
|
def error_when_not_valid?
|
33
|
-
|
34
|
-
|
35
|
-
not
|
33
|
+
@attachment = @subject.new.send(@attachment_name)
|
34
|
+
@attachment.assign(nil)
|
35
|
+
not @attachment.errors[:presence].nil?
|
36
36
|
end
|
37
37
|
|
38
38
|
def no_error_when_valid?
|
39
39
|
@file = StringIO.new(".")
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
@attachment = @subject.new.send(@attachment_name)
|
41
|
+
@attachment.assign(@file)
|
42
|
+
@attachment.errors[:presence].nil?
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -54,11 +54,9 @@ module Paperclip
|
|
54
54
|
def passes_validation_with_size(new_size)
|
55
55
|
file = StringIO.new(".")
|
56
56
|
override_method(file, :size){ new_size }
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
subject.valid?
|
61
|
-
subject.errors.on(:"#{@attachment_name}_file_size").blank?
|
57
|
+
attachment = @subject.new.attachment_for(@attachment_name)
|
58
|
+
attachment.assign(file)
|
59
|
+
attachment.errors[:size].nil?
|
62
60
|
end
|
63
61
|
|
64
62
|
def lower_than_low?
|
data/lib/paperclip/storage.rb
CHANGED
@@ -20,9 +20,9 @@ module Paperclip
|
|
20
20
|
def self.extended base
|
21
21
|
end
|
22
22
|
|
23
|
-
def exists?(
|
23
|
+
def exists?(style = default_style)
|
24
24
|
if original_filename
|
25
|
-
File.exist?(path(
|
25
|
+
File.exist?(path(style))
|
26
26
|
else
|
27
27
|
false
|
28
28
|
end
|
@@ -30,17 +30,17 @@ module Paperclip
|
|
30
30
|
|
31
31
|
# Returns representation of the data of the file assigned to the given
|
32
32
|
# style, in the format most representative of the current storage.
|
33
|
-
def to_file
|
34
|
-
@queued_for_write[
|
33
|
+
def to_file style = default_style
|
34
|
+
@queued_for_write[style] || (File.new(path(style), 'rb') if exists?(style))
|
35
35
|
end
|
36
36
|
|
37
37
|
def flush_writes #:nodoc:
|
38
|
-
@queued_for_write.each do |
|
38
|
+
@queued_for_write.each do |style, file|
|
39
39
|
file.close
|
40
|
-
FileUtils.mkdir_p(File.dirname(path(
|
41
|
-
log("saving #{path(
|
42
|
-
FileUtils.mv(file.path, path(
|
43
|
-
FileUtils.chmod(0644, path(
|
40
|
+
FileUtils.mkdir_p(File.dirname(path(style)))
|
41
|
+
log("saving #{path(style)}")
|
42
|
+
FileUtils.mv(file.path, path(style))
|
43
|
+
FileUtils.chmod(0644, path(style))
|
44
44
|
end
|
45
45
|
@queued_for_write = {}
|
46
46
|
end
|
@@ -159,10 +159,6 @@ module Paperclip
|
|
159
159
|
"#{attachment.s3_protocol}://#{attachment.bucket_name}.s3.amazonaws.com/#{attachment.path(style).gsub(%r{^/}, "")}"
|
160
160
|
end
|
161
161
|
end
|
162
|
-
|
163
|
-
def expiring_url(time = 3600)
|
164
|
-
AWS::S3::S3Object.url_for(path, bucket_name, :expires_in => time )
|
165
|
-
end
|
166
162
|
|
167
163
|
def bucket_name
|
168
164
|
@bucket
|
data/lib/paperclip/thumbnail.rb
CHANGED
@@ -12,7 +12,6 @@ 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
|
-
|
16
15
|
geometry = options[:geometry]
|
17
16
|
@file = file
|
18
17
|
@crop = geometry[-1,1] == '#'
|
@@ -25,7 +24,6 @@ module Paperclip
|
|
25
24
|
|
26
25
|
@current_format = File.extname(@file.path)
|
27
26
|
@basename = File.basename(@file.path, @current_format)
|
28
|
-
|
29
27
|
end
|
30
28
|
|
31
29
|
# Returns true if the +target_geometry+ is meant to crop.
|
data/test/attachment_test.rb
CHANGED
@@ -14,6 +14,18 @@ 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
|
@@ -121,7 +133,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
121
133
|
:styles => { :default => ["100x100", :png] },
|
122
134
|
:default_style => :default
|
123
135
|
@file = StringIO.new("...")
|
124
|
-
@file.
|
136
|
+
@file.expects(:original_filename).returns("file.jpg")
|
125
137
|
end
|
126
138
|
should "return the right extension for the path" do
|
127
139
|
@attachment.assign(@file)
|
@@ -150,6 +162,11 @@ class AttachmentTest < Test::Unit::TestCase
|
|
150
162
|
should "report the correct options when sent #extra_options_for(:large)" do
|
151
163
|
assert_equal "-do_stuff", @dummy.avatar.send(:extra_options_for, :large)
|
152
164
|
end
|
165
|
+
|
166
|
+
before_should "call extra_options_for(:thumb/:large)" do
|
167
|
+
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:thumb)
|
168
|
+
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:large)
|
169
|
+
end
|
153
170
|
end
|
154
171
|
|
155
172
|
context "An attachment with :convert_options that is a proc" do
|
@@ -177,6 +194,11 @@ class AttachmentTest < Test::Unit::TestCase
|
|
177
194
|
should "report the correct options when sent #extra_options_for(:large)" do
|
178
195
|
assert_equal "-all", @dummy.avatar.send(:extra_options_for, :large)
|
179
196
|
end
|
197
|
+
|
198
|
+
before_should "call extra_options_for(:thumb/:large)" do
|
199
|
+
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:thumb)
|
200
|
+
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:large)
|
201
|
+
end
|
180
202
|
end
|
181
203
|
|
182
204
|
context "An attachment with :path that is a proc" do
|
@@ -245,6 +267,10 @@ class AttachmentTest < Test::Unit::TestCase
|
|
245
267
|
@attachment = Dummy.new.avatar
|
246
268
|
end
|
247
269
|
|
270
|
+
should "not run the procs immediately" do
|
271
|
+
assert_kind_of Proc, @attachment.styles[:normal][:geometry]
|
272
|
+
end
|
273
|
+
|
248
274
|
context "when assigned" do
|
249
275
|
setup do
|
250
276
|
@file = StringIO.new(".")
|
@@ -281,6 +307,10 @@ class AttachmentTest < Test::Unit::TestCase
|
|
281
307
|
@attachment = Dummy.new.avatar
|
282
308
|
end
|
283
309
|
|
310
|
+
should "not run the proc immediately" do
|
311
|
+
assert_kind_of Proc, @attachment.styles[:normal][:processors]
|
312
|
+
end
|
313
|
+
|
284
314
|
context "when assigned" do
|
285
315
|
setup do
|
286
316
|
@attachment.assign(StringIO.new("."))
|
@@ -324,22 +354,19 @@ class AttachmentTest < Test::Unit::TestCase
|
|
324
354
|
setup { @dummy.avatar = @file }
|
325
355
|
|
326
356
|
before_should "call #make on all specified processors" do
|
327
|
-
Paperclip::Thumbnail.expects(:make).with(any_parameters).returns(@file)
|
328
|
-
Paperclip::Test.expects(:make).with(any_parameters).returns(@file)
|
329
|
-
end
|
330
|
-
|
331
|
-
before_should "call #make with the right parameters passed as second argument" do
|
332
357
|
expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => true, :convert_options => ""})
|
333
|
-
Paperclip::Thumbnail.expects(:make).with(
|
358
|
+
Paperclip::Thumbnail.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
359
|
+
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
334
360
|
end
|
335
361
|
|
336
362
|
before_should "call #make with attachment passed as third argument" do
|
337
|
-
|
363
|
+
expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => true, :convert_options => ""})
|
364
|
+
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
338
365
|
end
|
339
366
|
end
|
340
367
|
end
|
341
368
|
|
342
|
-
context "An attachment with
|
369
|
+
context "An attachment with no processors defined" do
|
343
370
|
setup do
|
344
371
|
rebuild_model :processors => [], :styles => {:something => 1}
|
345
372
|
@dummy = Dummy.new
|
@@ -350,17 +377,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
350
377
|
end
|
351
378
|
end
|
352
379
|
|
353
|
-
context "An attachment without styles and with no processors defined" do
|
354
|
-
setup do
|
355
|
-
rebuild_model :processors => [], :styles => {}
|
356
|
-
@dummy = Dummy.new
|
357
|
-
@file = StringIO.new("...")
|
358
|
-
end
|
359
|
-
should "not raise when assigned to" do
|
360
|
-
@dummy.avatar = @file
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
380
|
context "Assigning an attachment with post_process hooks" do
|
365
381
|
setup do
|
366
382
|
rebuild_model :styles => { :something => "100x100#" }
|
@@ -462,6 +478,8 @@ class AttachmentTest < Test::Unit::TestCase
|
|
462
478
|
@attachment.expects(:valid_assignment?).with(@not_file).returns(true)
|
463
479
|
@attachment.expects(:queue_existing_for_delete)
|
464
480
|
@attachment.expects(:post_process)
|
481
|
+
@attachment.expects(:valid?).returns(true)
|
482
|
+
@attachment.expects(:validate)
|
465
483
|
@dummy.avatar = @not_file
|
466
484
|
end
|
467
485
|
|
@@ -480,7 +498,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
480
498
|
FileUtils.rm_rf("tmp")
|
481
499
|
rebuild_model
|
482
500
|
@instance = Dummy.new
|
483
|
-
@instance.stubs(:id).returns 123
|
484
501
|
@attachment = Paperclip::Attachment.new(:avatar, @instance)
|
485
502
|
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
|
486
503
|
end
|
@@ -589,7 +606,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
589
606
|
should "commit the files to disk" do
|
590
607
|
[:large, :medium, :small].each do |style|
|
591
608
|
io = @attachment.to_file(style)
|
592
|
-
# p "in commit to disk test, io is #{io.inspect} and @instance.id is #{@instance.id}"
|
593
609
|
assert File.exists?(io)
|
594
610
|
assert ! io.is_a?(::Tempfile)
|
595
611
|
io.close
|
data/test/helper.rb
CHANGED
data/test/iostream_test.rb
CHANGED
@@ -58,15 +58,8 @@ class IOStreamTest < Test::Unit::TestCase
|
|
58
58
|
assert @tempfile = @file.to_tempfile
|
59
59
|
end
|
60
60
|
|
61
|
-
should "convert it to a
|
62
|
-
assert @tempfile.is_a?(
|
63
|
-
end
|
64
|
-
|
65
|
-
should "have the name be based on the original_filename" do
|
66
|
-
name = File.basename(@file.path)
|
67
|
-
extension = File.extname(name)
|
68
|
-
basename = File.basename(name, extension)
|
69
|
-
assert_match %r[^#{Regexp.quote(basename)}.*?#{Regexp.quote(extension)}], File.basename(@tempfile.path)
|
61
|
+
should "convert it to a Tempfile" do
|
62
|
+
assert @tempfile.is_a?(Tempfile)
|
70
63
|
end
|
71
64
|
|
72
65
|
should "have the Tempfile contain the same data as the file" do
|
@@ -3,9 +3,7 @@ require 'test/helper'
|
|
3
3
|
class ValidateAttachmentPresenceMatcherTest < Test::Unit::TestCase
|
4
4
|
context "validate_attachment_presence" do
|
5
5
|
setup do
|
6
|
-
reset_table("dummies")
|
7
|
-
d.string :avatar_file_name
|
8
|
-
end
|
6
|
+
reset_table("dummies"){|d| d.string :avatar_file_name }
|
9
7
|
@dummy_class = reset_class "Dummy"
|
10
8
|
@dummy_class.has_attached_file :avatar
|
11
9
|
@matcher = self.class.validate_attachment_presence(:avatar)
|
data/test/paperclip_test.rb
CHANGED
@@ -185,23 +185,45 @@ class PaperclipTest < Test::Unit::TestCase
|
|
185
185
|
should "be valid" do
|
186
186
|
assert @dummy.valid?
|
187
187
|
end
|
188
|
+
|
189
|
+
context "then has a validation added that makes it invalid" do
|
190
|
+
setup do
|
191
|
+
assert @dummy.save
|
192
|
+
Dummy.class_eval do
|
193
|
+
validates_attachment_content_type :avatar, :content_type => ["text/plain"]
|
194
|
+
end
|
195
|
+
@dummy2 = Dummy.find(@dummy.id)
|
196
|
+
end
|
197
|
+
|
198
|
+
should "be invalid when reloaded" do
|
199
|
+
assert ! @dummy2.valid?, @dummy2.errors.inspect
|
200
|
+
end
|
201
|
+
|
202
|
+
should "be able to call #valid? twice without having duplicate errors" do
|
203
|
+
@dummy2.avatar.valid?
|
204
|
+
first_errors = @dummy2.avatar.errors
|
205
|
+
@dummy2.avatar.valid?
|
206
|
+
assert_equal first_errors, @dummy2.avatar.errors
|
207
|
+
end
|
208
|
+
end
|
188
209
|
end
|
189
210
|
|
190
211
|
context "a validation with an if guard clause" do
|
191
212
|
setup do
|
192
213
|
Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo })
|
193
214
|
@dummy = Dummy.new
|
194
|
-
@dummy.stubs(:avatar_file_name).returns(nil)
|
195
215
|
end
|
196
216
|
|
197
217
|
should "attempt validation if the guard returns true" do
|
198
218
|
@dummy.expects(:foo).returns(true)
|
199
|
-
|
219
|
+
@dummy.avatar.expects(:validate_presence).returns(nil)
|
220
|
+
@dummy.valid?
|
200
221
|
end
|
201
222
|
|
202
223
|
should "not attempt validation if the guard returns false" do
|
203
224
|
@dummy.expects(:foo).returns(false)
|
204
|
-
|
225
|
+
@dummy.avatar.expects(:validate_presence).never
|
226
|
+
@dummy.valid?
|
205
227
|
end
|
206
228
|
end
|
207
229
|
|
@@ -209,17 +231,18 @@ class PaperclipTest < Test::Unit::TestCase
|
|
209
231
|
setup do
|
210
232
|
Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo })
|
211
233
|
@dummy = Dummy.new
|
212
|
-
@dummy.stubs(:avatar_file_name).returns(nil)
|
213
234
|
end
|
214
235
|
|
215
236
|
should "attempt validation if the guard returns true" do
|
216
237
|
@dummy.expects(:foo).returns(false)
|
217
|
-
|
238
|
+
@dummy.avatar.expects(:validate_presence).returns(nil)
|
239
|
+
@dummy.valid?
|
218
240
|
end
|
219
241
|
|
220
242
|
should "not attempt validation if the guard returns false" do
|
221
243
|
@dummy.expects(:foo).returns(true)
|
222
|
-
|
244
|
+
@dummy.avatar.expects(:validate_presence).never
|
245
|
+
@dummy.valid?
|
223
246
|
end
|
224
247
|
end
|
225
248
|
|
@@ -236,11 +259,11 @@ class PaperclipTest < Test::Unit::TestCase
|
|
236
259
|
end
|
237
260
|
if validation == :presence
|
238
261
|
should "have an error on the attachment" do
|
239
|
-
assert @dummy.errors.on(:
|
262
|
+
assert @dummy.errors.on(:avatar)
|
240
263
|
end
|
241
264
|
else
|
242
265
|
should "not have an error on the attachment" do
|
243
|
-
assert_nil @dummy.errors.on(:
|
266
|
+
assert_nil @dummy.errors.on(:avatar)
|
244
267
|
end
|
245
268
|
end
|
246
269
|
end
|
@@ -250,7 +273,10 @@ class PaperclipTest < Test::Unit::TestCase
|
|
250
273
|
@dummy.valid?
|
251
274
|
end
|
252
275
|
should "not have an error when assigned a valid file" do
|
253
|
-
|
276
|
+
assert ! @dummy.avatar.errors.key?(validation)
|
277
|
+
end
|
278
|
+
should "not have an error on the attachment" do
|
279
|
+
assert_nil @dummy.errors.on(:avatar)
|
254
280
|
end
|
255
281
|
end
|
256
282
|
context "and assigned an invalid file" do
|
@@ -259,14 +285,17 @@ class PaperclipTest < Test::Unit::TestCase
|
|
259
285
|
@dummy.valid?
|
260
286
|
end
|
261
287
|
should "have an error when assigned a valid file" do
|
262
|
-
|
288
|
+
assert_not_nil @dummy.avatar.errors[validation]
|
289
|
+
end
|
290
|
+
should "have an error on the attachment" do
|
291
|
+
assert @dummy.errors.on(:avatar)
|
263
292
|
end
|
264
293
|
end
|
265
294
|
end
|
266
295
|
end
|
267
296
|
|
268
297
|
[[:presence, {}, "5k.png", nil],
|
269
|
-
[:size, {:in => 1..10240},
|
298
|
+
[:size, {:in => 1..10240}, nil, "12k.png"],
|
270
299
|
[:size, {:less_than => 10240}, "5k.png", "12k.png"],
|
271
300
|
[:size, {:greater_than => 8096}, "12k.png", "5k.png"],
|
272
301
|
[:content_type, {:content_type => "image/png"}, "5k.png", "text.txt"],
|
@@ -289,7 +318,7 @@ class PaperclipTest < Test::Unit::TestCase
|
|
289
318
|
end
|
290
319
|
|
291
320
|
should "have a file size min/max error message" do
|
292
|
-
assert_match
|
321
|
+
assert_match /between 0 and 10240 bytes/, @dummy.errors.on(:avatar)
|
293
322
|
end
|
294
323
|
end
|
295
324
|
end
|
data/test/storage_test.rb
CHANGED
@@ -96,33 +96,6 @@ class StorageTest < Test::Unit::TestCase
|
|
96
96
|
assert_match %r{^http://something.something.com/avatars/stringio.txt}, @dummy.avatar.url
|
97
97
|
end
|
98
98
|
end
|
99
|
-
|
100
|
-
context "Generating a url with an expiration" do
|
101
|
-
setup do
|
102
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
103
|
-
rebuild_model :storage => :s3,
|
104
|
-
:s3_credentials => {
|
105
|
-
:production => { :bucket => "prod_bucket" },
|
106
|
-
:development => { :bucket => "dev_bucket" }
|
107
|
-
},
|
108
|
-
:s3_host_alias => "something.something.com",
|
109
|
-
:path => ":attachment/:basename.:extension",
|
110
|
-
:url => ":s3_alias_url"
|
111
|
-
|
112
|
-
rails_env("production")
|
113
|
-
|
114
|
-
@dummy = Dummy.new
|
115
|
-
@dummy.avatar = StringIO.new(".")
|
116
|
-
|
117
|
-
AWS::S3::S3Object.expects(:url_for).with("avatars/stringio.txt", "prod_bucket", { :expires_in => 3600 })
|
118
|
-
|
119
|
-
@dummy.avatar.expiring_url
|
120
|
-
end
|
121
|
-
|
122
|
-
should "should succeed" do
|
123
|
-
assert true
|
124
|
-
end
|
125
|
-
end
|
126
99
|
|
127
100
|
context "Parsing S3 credentials with a bucket in them" do
|
128
101
|
setup do
|
data/test/thumbnail_test.rb
CHANGED
@@ -200,7 +200,7 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
200
200
|
teardown { @file.close }
|
201
201
|
|
202
202
|
should "start with two pages with dimensions 612x792" do
|
203
|
-
cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
|
203
|
+
cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
|
204
204
|
assert_equal "612x792"*2, `#{cmd}`.chomp
|
205
205
|
end
|
206
206
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bteitelb-paperclip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.1.
|
4
|
+
version: 2.3.1.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Yurek
|
@@ -100,7 +100,6 @@ files:
|
|
100
100
|
- lib/paperclip/matchers.rb
|
101
101
|
- lib/paperclip/processor.rb
|
102
102
|
- lib/paperclip/storage.rb
|
103
|
-
- lib/paperclip/style.rb
|
104
103
|
- lib/paperclip/thumbnail.rb
|
105
104
|
- lib/paperclip/upfile.rb
|
106
105
|
- lib/paperclip.rb
|
data/lib/paperclip/style.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
module Paperclip
|
3
|
-
# The Style class holds the definition of a thumbnail style, applying
|
4
|
-
# whatever processing is required to normalize the definition and delaying
|
5
|
-
# the evaluation of block parameters until useful context is available.
|
6
|
-
|
7
|
-
class Style
|
8
|
-
|
9
|
-
attr_reader :name, :attachment, :format
|
10
|
-
|
11
|
-
# Creates a Style object. +name+ is the name of the attachment,
|
12
|
-
# +definition+ is the style definition from has_attached_file, which
|
13
|
-
# can be string, array or hash
|
14
|
-
def initialize name, definition, attachment
|
15
|
-
@name = name
|
16
|
-
@attachment = attachment
|
17
|
-
if definition.is_a? Hash
|
18
|
-
@geometry = definition.delete(:geometry)
|
19
|
-
@format = definition.delete(:format)
|
20
|
-
@processors = definition.delete(:processors)
|
21
|
-
@other_args = definition
|
22
|
-
else
|
23
|
-
@geometry, @format = [definition, nil].flatten[0..1]
|
24
|
-
@other_args = {}
|
25
|
-
end
|
26
|
-
@format = nil if @format.blank?
|
27
|
-
end
|
28
|
-
|
29
|
-
# retrieves from the attachment the processors defined in the has_attached_file call
|
30
|
-
# (which method (in the attachment) will call any supplied procs)
|
31
|
-
# There is an important change of interface here: a style rule can set its own processors
|
32
|
-
# by default we behave as before, though.
|
33
|
-
def processors
|
34
|
-
@processors || attachment.processors
|
35
|
-
end
|
36
|
-
|
37
|
-
# retrieves from the attachment the whiny setting
|
38
|
-
def whiny
|
39
|
-
attachment.whiny
|
40
|
-
end
|
41
|
-
|
42
|
-
# returns true if we're inclined to grumble
|
43
|
-
def whiny?
|
44
|
-
!!whiny
|
45
|
-
end
|
46
|
-
|
47
|
-
def convert_options
|
48
|
-
attachment.send(:extra_options_for, name)
|
49
|
-
end
|
50
|
-
|
51
|
-
# returns the geometry string for this style
|
52
|
-
# if a proc has been supplied, we call it here
|
53
|
-
def geometry
|
54
|
-
@geometry.respond_to?(:call) ? @geometry.call(attachment.instance) : @geometry
|
55
|
-
end
|
56
|
-
|
57
|
-
# Supplies the hash of options that processors expect to receive as their second argument
|
58
|
-
# Arguments other than the standard geometry, format etc are just passed through from
|
59
|
-
# initialization and any procs are called here, just before post-processing.
|
60
|
-
def processor_options
|
61
|
-
args = {}
|
62
|
-
@other_args.each do |k,v|
|
63
|
-
args[k] = v.respond_to?(:call) ? v.call(attachment) : v
|
64
|
-
end
|
65
|
-
[:processors, :geometry, :format, :whiny, :convert_options].each do |k|
|
66
|
-
(arg = send(k)) && args[k] = arg
|
67
|
-
end
|
68
|
-
args
|
69
|
-
end
|
70
|
-
|
71
|
-
# Supports getting and setting style properties with hash notation to ensure backwards-compatibility
|
72
|
-
# eg. @attachment.styles[:large][:geometry]@ will still work
|
73
|
-
def [](key)
|
74
|
-
if [:name, :convert_options, :whiny, :processors, :geometry, :format].include?(key)
|
75
|
-
send(key)
|
76
|
-
elsif defined? @other_args[key]
|
77
|
-
@other_args[key]
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def []=(key, value)
|
82
|
-
if [:name, :convert_options, :whiny, :processors, :geometry, :format].include?(key)
|
83
|
-
send("#{key}=".intern, value)
|
84
|
-
else
|
85
|
-
@other_args[key] = value
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
end
|