paperclip 2.3.1.1 → 2.3.2
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/README.rdoc +6 -1
- data/Rakefile +11 -38
- data/generators/paperclip/USAGE +2 -2
- data/generators/paperclip/paperclip_generator.rb +8 -8
- data/lib/generators/paperclip/USAGE +8 -0
- data/lib/generators/paperclip/paperclip_generator.rb +31 -0
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
- data/lib/paperclip.rb +113 -69
- data/lib/paperclip/attachment.rb +58 -146
- data/lib/paperclip/callback_compatability.rb +50 -22
- data/lib/paperclip/geometry.rb +7 -7
- data/lib/paperclip/interpolations.rb +21 -21
- data/lib/paperclip/iostream.rb +3 -2
- data/lib/paperclip/matchers.rb +29 -0
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +8 -0
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +13 -5
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +13 -7
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +16 -4
- data/lib/paperclip/processor.rb +2 -2
- data/lib/paperclip/railtie.rb +22 -0
- data/lib/paperclip/storage.rb +29 -25
- data/lib/paperclip/style.rb +90 -0
- data/lib/paperclip/thumbnail.rb +20 -15
- data/lib/paperclip/upfile.rb +5 -2
- data/lib/paperclip/version.rb +3 -0
- data/{tasks/paperclip_tasks.rake → lib/tasks/paperclip.rake} +0 -0
- data/rails/init.rb +2 -0
- data/shoulda_macros/paperclip.rb +5 -3
- data/test/attachment_test.rb +52 -74
- data/test/geometry_test.rb +1 -1
- data/test/helper.rb +62 -22
- data/test/integration_test.rb +8 -8
- data/test/interpolations_test.rb +4 -4
- data/test/iostream_test.rb +9 -2
- data/test/matchers/have_attached_file_matcher_test.rb +9 -6
- data/test/matchers/validate_attachment_content_type_matcher_test.rb +15 -8
- data/test/matchers/validate_attachment_presence_matcher_test.rb +11 -6
- data/test/matchers/validate_attachment_size_matcher_test.rb +18 -17
- data/test/paperclip_test.rb +58 -68
- data/test/storage_test.rb +53 -13
- data/test/style_test.rb +141 -0
- data/test/thumbnail_test.rb +17 -17
- data/test/upfile_test.rb +8 -0
- metadata +69 -42
data/lib/paperclip/attachment.rb
CHANGED
@@ -4,21 +4,22 @@ module Paperclip
|
|
4
4
|
# when the model saves, deletes when the model is destroyed, and processes
|
5
5
|
# the file upon assignment.
|
6
6
|
class Attachment
|
7
|
-
|
7
|
+
|
8
8
|
def self.default_options
|
9
9
|
@default_options ||= {
|
10
|
-
:url
|
11
|
-
:path
|
12
|
-
:styles
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
10
|
+
:url => "/system/:attachment/:id/:style/:filename",
|
11
|
+
:path => ":rails_root/public:url",
|
12
|
+
:styles => {},
|
13
|
+
:processors => [:thumbnail],
|
14
|
+
:convert_options => {},
|
15
|
+
:default_url => "/:attachment/:style/missing.png",
|
16
|
+
:default_style => :original,
|
17
|
+
:storage => :filesystem,
|
18
|
+
:whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
|
18
19
|
}
|
19
20
|
end
|
20
21
|
|
21
|
-
attr_reader :name, :instance, :
|
22
|
+
attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny, :options
|
22
23
|
|
23
24
|
# Creates an Attachment object. +name+ is the name of the attachment,
|
24
25
|
# +instance+ is the ActiveRecord object instance it's attached to, and
|
@@ -34,33 +35,42 @@ module Paperclip
|
|
34
35
|
@path = options[:path]
|
35
36
|
@path = @path.call(self) if @path.is_a?(Proc)
|
36
37
|
@styles = options[:styles]
|
37
|
-
@
|
38
|
+
@normalized_styles = nil
|
38
39
|
@default_url = options[:default_url]
|
39
|
-
@validations = options[:validations]
|
40
40
|
@default_style = options[:default_style]
|
41
41
|
@storage = options[:storage]
|
42
42
|
@whiny = options[:whiny_thumbnails] || options[:whiny]
|
43
|
-
@convert_options = options[:convert_options]
|
44
|
-
@processors = options[:processors]
|
43
|
+
@convert_options = options[:convert_options]
|
44
|
+
@processors = options[:processors]
|
45
45
|
@options = options
|
46
46
|
@queued_for_delete = []
|
47
47
|
@queued_for_write = {}
|
48
48
|
@errors = {}
|
49
|
-
@validation_errors = nil
|
50
49
|
@dirty = false
|
51
50
|
|
52
|
-
normalize_style_definition
|
53
51
|
initialize_storage
|
54
52
|
end
|
55
53
|
|
54
|
+
def styles
|
55
|
+
unless @normalized_styles
|
56
|
+
@normalized_styles = {}
|
57
|
+
(@styles.respond_to?(:call) ? @styles.call(self) : @styles).each do |name, args|
|
58
|
+
@normalized_styles[name] = Paperclip::Style.new(name, args, self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
@normalized_styles
|
62
|
+
end
|
63
|
+
|
64
|
+
def processors
|
65
|
+
@processors.respond_to?(:call) ? @processors.call(instance) : @processors
|
66
|
+
end
|
67
|
+
|
56
68
|
# What gets called when you call instance.attachment = File. It clears
|
57
|
-
# errors, assigns attributes, processes the file
|
69
|
+
# errors, assigns attributes, and processes the file. It
|
58
70
|
# also queues up the previous file for deletion, to be flushed away on
|
59
71
|
# #save of its host. In addition to form uploads, you can also assign
|
60
|
-
# another Paperclip attachment:
|
72
|
+
# another Paperclip attachment:
|
61
73
|
# new_user.avatar = old_user.avatar
|
62
|
-
# If the file that is assigned is not valid, the processing (i.e.
|
63
|
-
# thumbnailing, etc) will NOT be run.
|
64
74
|
def assign uploaded_file
|
65
75
|
ensure_required_accessors!
|
66
76
|
|
@@ -77,20 +87,19 @@ module Paperclip
|
|
77
87
|
return nil if uploaded_file.nil?
|
78
88
|
|
79
89
|
@queued_for_write[:original] = uploaded_file.to_tempfile
|
80
|
-
instance_write(:file_name, uploaded_file.original_filename.strip
|
90
|
+
instance_write(:file_name, uploaded_file.original_filename.strip)
|
81
91
|
instance_write(:content_type, uploaded_file.content_type.to_s.strip)
|
82
92
|
instance_write(:file_size, uploaded_file.size.to_i)
|
83
93
|
instance_write(:updated_at, Time.now)
|
84
94
|
|
85
95
|
@dirty = true
|
86
96
|
|
87
|
-
post_process
|
88
|
-
|
97
|
+
post_process
|
98
|
+
|
89
99
|
# Reset the file size if the original file was reprocessed.
|
90
100
|
instance_write(:file_size, @queued_for_write[:original].size.to_i)
|
91
101
|
ensure
|
92
102
|
uploaded_file.close if close_uploaded_file
|
93
|
-
validate
|
94
103
|
end
|
95
104
|
|
96
105
|
# Returns the public URL of the attachment, with a given style. Note that
|
@@ -100,8 +109,8 @@ module Paperclip
|
|
100
109
|
# security, however, for performance reasons. set
|
101
110
|
# include_updated_timestamp to false if you want to stop the attachment
|
102
111
|
# update time appended to the url
|
103
|
-
def url
|
104
|
-
url = original_filename.nil? ? interpolate(@default_url,
|
112
|
+
def url style_name = default_style, include_updated_timestamp = true
|
113
|
+
url = original_filename.nil? ? interpolate(@default_url, style_name) : interpolate(@url, style_name)
|
105
114
|
include_updated_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url
|
106
115
|
end
|
107
116
|
|
@@ -109,19 +118,13 @@ module Paperclip
|
|
109
118
|
# file is stored in the filesystem the path refers to the path of the file
|
110
119
|
# on disk. If the file is stored in S3, the path is the "key" part of the
|
111
120
|
# URL, and the :bucket option refers to the S3 bucket.
|
112
|
-
def path
|
113
|
-
original_filename.nil? ? nil : interpolate(@path,
|
121
|
+
def path style_name = default_style
|
122
|
+
original_filename.nil? ? nil : interpolate(@path, style_name)
|
114
123
|
end
|
115
124
|
|
116
125
|
# Alias to +url+
|
117
|
-
def to_s
|
118
|
-
url(
|
119
|
-
end
|
120
|
-
|
121
|
-
# Returns true if there are no errors on this attachment.
|
122
|
-
def valid?
|
123
|
-
validate
|
124
|
-
errors.empty?
|
126
|
+
def to_s style_name = nil
|
127
|
+
url(style_name)
|
125
128
|
end
|
126
129
|
|
127
130
|
# Returns an array containing the errors on this attachment.
|
@@ -137,15 +140,10 @@ module Paperclip
|
|
137
140
|
# Saves the file, if there are no errors. If there are, it flushes them to
|
138
141
|
# the instance's errors and returns false, cancelling the save.
|
139
142
|
def save
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
true
|
145
|
-
else
|
146
|
-
flush_errors
|
147
|
-
false
|
148
|
-
end
|
143
|
+
flush_deletes
|
144
|
+
flush_writes
|
145
|
+
@dirty = false
|
146
|
+
true
|
149
147
|
end
|
150
148
|
|
151
149
|
# Clears out the attachment. Has the same effect as previously assigning
|
@@ -154,7 +152,6 @@ module Paperclip
|
|
154
152
|
def clear
|
155
153
|
queue_existing_for_delete
|
156
154
|
@errors = {}
|
157
|
-
@validation_errors = nil
|
158
155
|
end
|
159
156
|
|
160
157
|
# Destroys the attachment. Has the same effect as previously assigning
|
@@ -182,8 +179,8 @@ module Paperclip
|
|
182
179
|
def content_type
|
183
180
|
instance_read(:content_type)
|
184
181
|
end
|
185
|
-
|
186
|
-
# Returns the last modified time of the file as originally assigned, and
|
182
|
+
|
183
|
+
# Returns the last modified time of the file as originally assigned, and
|
187
184
|
# lives in the <attachment>_updated_at attribute of the model.
|
188
185
|
def updated_at
|
189
186
|
time = instance_read(:updated_at)
|
@@ -223,7 +220,7 @@ module Paperclip
|
|
223
220
|
true
|
224
221
|
end
|
225
222
|
end
|
226
|
-
|
223
|
+
|
227
224
|
# Returns true if a file has been assigned.
|
228
225
|
def file?
|
229
226
|
!original_filename.blank?
|
@@ -267,82 +264,6 @@ module Paperclip
|
|
267
264
|
file.nil? || (file.respond_to?(:original_filename) && file.respond_to?(:content_type))
|
268
265
|
end
|
269
266
|
|
270
|
-
def validate #:nodoc:
|
271
|
-
unless @validation_errors
|
272
|
-
@validation_errors = @validations.inject({}) do |errors, validation|
|
273
|
-
name, options = validation
|
274
|
-
errors[name] = send(:"validate_#{name}", options) if allow_validation?(options)
|
275
|
-
errors
|
276
|
-
end
|
277
|
-
@validation_errors.reject!{|k,v| v == nil }
|
278
|
-
@errors.merge!(@validation_errors)
|
279
|
-
end
|
280
|
-
@validation_errors
|
281
|
-
end
|
282
|
-
|
283
|
-
def allow_validation? options #:nodoc:
|
284
|
-
(options[:if].nil? || check_guard(options[:if])) && (options[:unless].nil? || !check_guard(options[:unless]))
|
285
|
-
end
|
286
|
-
|
287
|
-
def check_guard guard #:nodoc:
|
288
|
-
if guard.respond_to? :call
|
289
|
-
guard.call(instance)
|
290
|
-
elsif ! guard.blank?
|
291
|
-
instance.send(guard.to_s)
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
def validate_size options #:nodoc:
|
296
|
-
if file? && !options[:range].include?(size.to_i)
|
297
|
-
options[:message].gsub(/:min/, options[:min].to_s).gsub(/:max/, options[:max].to_s)
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
def validate_presence options #:nodoc:
|
302
|
-
options[:message] unless file?
|
303
|
-
end
|
304
|
-
|
305
|
-
def validate_content_type options #:nodoc:
|
306
|
-
valid_types = [options[:content_type]].flatten
|
307
|
-
unless original_filename.blank?
|
308
|
-
unless valid_types.blank?
|
309
|
-
content_type = instance_read(:content_type)
|
310
|
-
unless valid_types.any?{|t| content_type.nil? || t === content_type }
|
311
|
-
options[:message] || "is not one of the allowed file types."
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
def normalize_style_definition #:nodoc:
|
318
|
-
@styles.each do |name, args|
|
319
|
-
unless args.is_a? Hash
|
320
|
-
dimensions, format = [args, nil].flatten[0..1]
|
321
|
-
format = nil if format.blank?
|
322
|
-
@styles[name] = {
|
323
|
-
:processors => @processors,
|
324
|
-
:geometry => dimensions,
|
325
|
-
:format => format,
|
326
|
-
:whiny => @whiny,
|
327
|
-
:convert_options => extra_options_for(name)
|
328
|
-
}
|
329
|
-
else
|
330
|
-
@styles[name] = {
|
331
|
-
:processors => @processors,
|
332
|
-
:whiny => @whiny,
|
333
|
-
:convert_options => extra_options_for(name)
|
334
|
-
}.merge(@styles[name])
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
def solidify_style_definitions #:nodoc:
|
340
|
-
@styles.each do |name, args|
|
341
|
-
@styles[name][:geometry] = @styles[name][:geometry].call(instance) if @styles[name][:geometry].respond_to?(:call)
|
342
|
-
@styles[name][:processors] = @styles[name][:processors].call(instance) if @styles[name][:processors].respond_to?(:call)
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
267
|
def initialize_storage #:nodoc:
|
347
268
|
@storage_module = Paperclip::Storage.const_get(@storage.to_s.capitalize)
|
348
269
|
self.extend(@storage_module)
|
@@ -359,27 +280,19 @@ module Paperclip
|
|
359
280
|
|
360
281
|
def post_process #:nodoc:
|
361
282
|
return if @queued_for_write[:original].nil?
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
def fire_events(which) #:nodoc:
|
369
|
-
return true if callback(:"#{which}_post_process") == false
|
370
|
-
return true if callback(:"#{which}_#{name}_post_process") == false
|
371
|
-
end
|
372
|
-
|
373
|
-
def callback which #:nodoc:
|
374
|
-
instance.run_callbacks(which, @queued_for_write){|result, obj| result == false }
|
283
|
+
instance.run_paperclip_callbacks(:post_process) do
|
284
|
+
instance.run_paperclip_callbacks(:"#{name}_post_process") do
|
285
|
+
post_process_styles
|
286
|
+
end
|
287
|
+
end
|
375
288
|
end
|
376
289
|
|
377
290
|
def post_process_styles #:nodoc:
|
378
|
-
|
291
|
+
styles.each do |name, style|
|
379
292
|
begin
|
380
|
-
raise RuntimeError.new("Style #{name} has no processors defined.") if
|
381
|
-
@queued_for_write[name] =
|
382
|
-
Paperclip.processor(processor).make(file,
|
293
|
+
raise RuntimeError.new("Style #{name} has no processors defined.") if style.processors.blank?
|
294
|
+
@queued_for_write[name] = style.processors.inject(@queued_for_write[:original]) do |file, processor|
|
295
|
+
Paperclip.processor(processor).make(file, style.processor_options, self)
|
383
296
|
end
|
384
297
|
rescue PaperclipError => e
|
385
298
|
log("An error was received while processing: #{e.inspect}")
|
@@ -388,13 +301,13 @@ module Paperclip
|
|
388
301
|
end
|
389
302
|
end
|
390
303
|
|
391
|
-
def interpolate pattern,
|
392
|
-
Paperclip::Interpolations.interpolate(pattern, self,
|
304
|
+
def interpolate pattern, style_name = default_style #:nodoc:
|
305
|
+
Paperclip::Interpolations.interpolate(pattern, self, style_name)
|
393
306
|
end
|
394
307
|
|
395
308
|
def queue_existing_for_delete #:nodoc:
|
396
309
|
return unless file?
|
397
|
-
@queued_for_delete += [:original,
|
310
|
+
@queued_for_delete += [:original, *styles.keys].uniq.map do |style|
|
398
311
|
path(style) if exists?(style)
|
399
312
|
end.compact
|
400
313
|
instance_write(:file_name, nil)
|
@@ -411,4 +324,3 @@ module Paperclip
|
|
411
324
|
|
412
325
|
end
|
413
326
|
end
|
414
|
-
|
@@ -1,33 +1,61 @@
|
|
1
1
|
module Paperclip
|
2
|
-
# This module is intended as a compatability shim for the differences in
|
3
|
-
# callbacks between Rails 2.0 and Rails 2.1.
|
4
2
|
module CallbackCompatability
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module Rails21
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(Defining)
|
6
|
+
base.send(:include, Running)
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
9
|
+
module Defining
|
10
|
+
def define_paperclip_callbacks(*args)
|
11
|
+
args.each do |callback|
|
12
|
+
define_callbacks("before_#{callback}")
|
13
|
+
define_callbacks("after_#{callback}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Running
|
19
|
+
def run_paperclip_callbacks(callback, opts = nil, &blk)
|
20
|
+
# The overall structure of this isn't ideal since after callbacks run even if
|
21
|
+
# befores return false. But this is how rails 3's callbacks work, unfortunately.
|
22
|
+
if run_callbacks(:"before_#{callback}"){ |result, object| result == false } != false
|
23
|
+
blk.call
|
24
|
+
end
|
25
|
+
run_callbacks(:"after_#{callback}"){ |result, object| result == false }
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
|
-
module
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
callback(meth)
|
30
|
+
module Rails3
|
31
|
+
def self.included(base)
|
32
|
+
base.extend(Defining)
|
33
|
+
base.send(:include, Running)
|
30
34
|
end
|
35
|
+
|
36
|
+
module Defining
|
37
|
+
def define_paperclip_callbacks(*callbacks)
|
38
|
+
define_callbacks *[callbacks, {:terminator => "result == false"}].flatten
|
39
|
+
callbacks.each do |callback|
|
40
|
+
eval <<-end_callbacks
|
41
|
+
def before_#{callback}(*args, &blk)
|
42
|
+
set_callback(:#{callback}, :before, *args, &blk)
|
43
|
+
end
|
44
|
+
def after_#{callback}(*args, &blk)
|
45
|
+
set_callback(:#{callback}, :after, *args, &blk)
|
46
|
+
end
|
47
|
+
end_callbacks
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module Running
|
53
|
+
def run_paperclip_callbacks(callback, opts = nil, &block)
|
54
|
+
run_callbacks(callback, opts, &block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
31
58
|
end
|
59
|
+
|
32
60
|
end
|
33
61
|
end
|
data/lib/paperclip/geometry.rb
CHANGED
@@ -16,7 +16,7 @@ module Paperclip
|
|
16
16
|
def self.from_file file
|
17
17
|
file = file.path if file.respond_to? "path"
|
18
18
|
geometry = begin
|
19
|
-
Paperclip.run("identify",
|
19
|
+
Paperclip.run("identify", "-format", "%wx%h", "#{file}[0]")
|
20
20
|
rescue PaperclipCommandLineError
|
21
21
|
""
|
22
22
|
end
|
@@ -75,12 +75,12 @@ module Paperclip
|
|
75
75
|
to_s
|
76
76
|
end
|
77
77
|
|
78
|
-
# Returns the scaling and cropping geometries (in string-based ImageMagick format)
|
79
|
-
# neccessary to transform this Geometry into the Geometry given. If crop is true,
|
80
|
-
# then it is assumed the destination Geometry will be the exact final resolution.
|
81
|
-
# In this case, the source Geometry is scaled so that an image containing the
|
82
|
-
# destination Geometry would be completely filled by the source image, and any
|
83
|
-
# overhanging image would be cropped. Useful for square thumbnail images. The cropping
|
78
|
+
# Returns the scaling and cropping geometries (in string-based ImageMagick format)
|
79
|
+
# neccessary to transform this Geometry into the Geometry given. If crop is true,
|
80
|
+
# then it is assumed the destination Geometry will be the exact final resolution.
|
81
|
+
# In this case, the source Geometry is scaled so that an image containing the
|
82
|
+
# destination Geometry would be completely filled by the source image, and any
|
83
|
+
# overhanging image would be cropped. Useful for square thumbnail images. The cropping
|
84
84
|
# is weighted at the center of the Geometry.
|
85
85
|
def transformation_to dst, crop = false
|
86
86
|
if crop
|
@@ -34,75 +34,75 @@ 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_name
|
38
|
+
"#{basename(attachment, style_name)}.#{extension(attachment, style_name)}"
|
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_name
|
45
45
|
raise InfiniteInterpolationError if attachment.options[:url].include?(":url")
|
46
|
-
attachment.url(
|
46
|
+
attachment.url(style_name, 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_name
|
51
51
|
attachment.instance_read(:updated_at).to_s
|
52
52
|
end
|
53
53
|
|
54
|
-
# Returns the
|
55
|
-
def rails_root attachment,
|
56
|
-
|
54
|
+
# Returns the Rails.root constant.
|
55
|
+
def rails_root attachment, style_name
|
56
|
+
Rails.root
|
57
57
|
end
|
58
58
|
|
59
|
-
# Returns the
|
60
|
-
def rails_env attachment,
|
61
|
-
|
59
|
+
# Returns the Rails.env constant.
|
60
|
+
def rails_env attachment, style_name
|
61
|
+
Rails.env
|
62
62
|
end
|
63
63
|
|
64
64
|
# Returns the underscored, pluralized version of the class name.
|
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_name = nil
|
69
|
+
return super() if attachment.nil? && style_name.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_name
|
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_name
|
82
|
+
((style = attachment.styles[style_name]) && 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_name
|
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_name
|
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_name
|
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_name
|
105
|
+
style_name || attachment.default_style
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|