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/README.rdoc
CHANGED
@@ -138,7 +138,7 @@ For example, assuming we had this definition:
|
|
138
138
|
has_attached_file :scan, :styles => { :text => { :quality => :better } },
|
139
139
|
:processors => [:rotator, :ocr]
|
140
140
|
|
141
|
-
then both the :rotator processor and the :ocr processor would receive the
|
141
|
+
then both the :rotator processor and the :ocr processor would receive the
|
142
142
|
options "{ :quality => :better }". This parameter may not mean anything to one
|
143
143
|
or more or the processors, and they are expected to ignore it.
|
144
144
|
|
@@ -162,6 +162,11 @@ NOTE: Post processing will not even *start* if the attachment is not valid
|
|
162
162
|
according to the validations. Your callbacks and processors will *only* be
|
163
163
|
called with valid attachments.
|
164
164
|
|
165
|
+
==Testing
|
166
|
+
|
167
|
+
Paperclip provides rspec-compatible matchers for testing attachments. See the
|
168
|
+
documentation on Paperclip::Shoulda::Matchers for more information.
|
169
|
+
|
165
170
|
==Contributing
|
166
171
|
|
167
172
|
If you'd like to contribute a feature or bugfix: Thanks! To make sure your
|
data/Rakefile
CHANGED
@@ -8,6 +8,11 @@ require 'paperclip'
|
|
8
8
|
desc 'Default: run unit tests.'
|
9
9
|
task :default => [:clean, :test]
|
10
10
|
|
11
|
+
desc 'Test the paperclip plugin under all supported Rails versions.'
|
12
|
+
task :all do |t|
|
13
|
+
exec('rake RAILS_VERSION=2.1 && rake RAILS_VERSION=2.3 && rake RAILS_VERSION=3.0')
|
14
|
+
end
|
15
|
+
|
11
16
|
desc 'Test the paperclip plugin.'
|
12
17
|
Rake::TestTask.new(:test) do |t|
|
13
18
|
t.libs << 'lib' << 'profile'
|
@@ -40,47 +45,15 @@ task :clean do |t|
|
|
40
45
|
FileUtils.rm_rf "doc"
|
41
46
|
FileUtils.rm_rf "tmp"
|
42
47
|
FileUtils.rm_rf "pkg"
|
48
|
+
FileUtils.rm_rf "public"
|
43
49
|
FileUtils.rm "test/debug.log" rescue nil
|
44
50
|
FileUtils.rm "test/paperclip.db" rescue nil
|
45
51
|
Dir.glob("paperclip-*.gem").each{|f| FileUtils.rm f }
|
46
52
|
end
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
"init.rb",
|
52
|
-
"{generators,lib,tasks,test,shoulda_macros}/**/*"]
|
53
|
-
exclude_file_globs = ["test/s3.yml",
|
54
|
-
"test/debug.log",
|
55
|
-
"test/paperclip.db",
|
56
|
-
"test/doc",
|
57
|
-
"test/doc/*",
|
58
|
-
"test/pkg",
|
59
|
-
"test/pkg/*",
|
60
|
-
"test/tmp",
|
61
|
-
"test/tmp/*"]
|
62
|
-
spec = Gem::Specification.new do |s|
|
63
|
-
s.name = "paperclip"
|
64
|
-
s.version = Paperclip::VERSION
|
65
|
-
s.author = "Jon Yurek"
|
66
|
-
s.email = "jyurek@thoughtbot.com"
|
67
|
-
s.homepage = "http://www.thoughtbot.com/projects/paperclip"
|
68
|
-
s.platform = Gem::Platform::RUBY
|
69
|
-
s.summary = "File attachments as attributes for ActiveRecord"
|
70
|
-
s.files = FileList[include_file_globs].to_a - FileList[exclude_file_globs].to_a
|
71
|
-
s.require_path = "lib"
|
72
|
-
s.test_files = FileList["test/**/test_*.rb"].to_a
|
73
|
-
s.rubyforge_project = "paperclip"
|
74
|
-
s.has_rdoc = true
|
75
|
-
s.extra_rdoc_files = FileList["README*"].to_a
|
76
|
-
s.rdoc_options << '--line-numbers' << '--inline-source'
|
77
|
-
s.requirements << "ImageMagick"
|
78
|
-
s.add_development_dependency 'thoughtbot-shoulda'
|
79
|
-
s.add_development_dependency 'jferris-mocha', '= 0.9.5.0.1241126838'
|
80
|
-
s.add_development_dependency 'aws-s3'
|
81
|
-
s.add_development_dependency 'sqlite3-ruby'
|
82
|
-
s.add_development_dependency 'activerecord'
|
83
|
-
s.add_development_dependency 'activesupport'
|
54
|
+
desc 'Build the gemspec.'
|
55
|
+
task :gemspec do |t|
|
56
|
+
exec 'gem build paperclip.gemspec'
|
84
57
|
end
|
85
58
|
|
86
59
|
desc "Print a list of the files to be put into the gem"
|
@@ -89,13 +62,13 @@ task :manifest => :clean do
|
|
89
62
|
puts file
|
90
63
|
end
|
91
64
|
end
|
92
|
-
|
65
|
+
|
93
66
|
desc "Generate a gemspec file for GitHub"
|
94
67
|
task :gemspec => :clean do
|
95
68
|
File.open("#{spec.name}.gemspec", 'w') do |f|
|
96
69
|
f.write spec.to_ruby
|
97
70
|
end
|
98
|
-
end
|
71
|
+
end
|
99
72
|
|
100
73
|
desc "Build the gem into the current directory"
|
101
74
|
task :gem => :gemspec do
|
data/generators/paperclip/USAGE
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
class PaperclipGenerator < Rails::Generator::NamedBase
|
2
2
|
attr_accessor :attachments, :migration_name
|
3
|
-
|
3
|
+
|
4
4
|
def initialize(args, options = {})
|
5
5
|
super
|
6
6
|
@class_name, @attachments = args[0], args[1..-1]
|
7
7
|
end
|
8
|
-
|
9
|
-
def manifest
|
8
|
+
|
9
|
+
def manifest
|
10
10
|
file_name = generate_file_name
|
11
11
|
@migration_name = file_name.camelize
|
12
12
|
record do |m|
|
@@ -14,14 +14,14 @@ class PaperclipGenerator < Rails::Generator::NamedBase
|
|
14
14
|
File.join('db', 'migrate'),
|
15
15
|
:migration_file_name => file_name
|
16
16
|
end
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
21
|
def generate_file_name
|
22
22
|
names = attachments.map{|a| a.underscore }
|
23
23
|
names = names[0..-2] + ["and", names[-1]] if names.length > 1
|
24
24
|
"add_attachments_#{names.join("_")}_to_#{@class_name.underscore}"
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
class PaperclipGenerator < ActiveRecord::Generators::Base
|
4
|
+
desc "Create a migration to add paperclip-specific fields to your model."
|
5
|
+
|
6
|
+
argument :attachment_names, :required => true, :type => :array, :desc => "The names of the attachment(s) to add.",
|
7
|
+
:banner => "attachment_one attachment_two attachment_three ..."
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
@source_root ||= File.expand_path('../templates', __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_migration
|
14
|
+
migration_template "paperclip_migration.rb.erb", "db/migrate/#{migration_file_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def migration_name
|
20
|
+
"add_attachment_#{attachment_names.join("_")}_to_#{name.underscore}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def migration_file_name
|
24
|
+
"#{migration_name}.rb"
|
25
|
+
end
|
26
|
+
|
27
|
+
def migration_class_name
|
28
|
+
migration_name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
<% attachment_names.each do |attachment| -%>
|
4
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_file_name, :string
|
5
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_content_type, :string
|
6
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_file_size, :integer
|
7
|
+
add_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_updated_at, :datetime
|
8
|
+
<% end -%>
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
<% attachment_names.each do |attachment| -%>
|
13
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_file_name
|
14
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_content_type
|
15
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_file_size
|
16
|
+
remove_column :<%= name.underscore.camelize.tableize %>, :<%= attachment %>_updated_at
|
17
|
+
<% end -%>
|
18
|
+
end
|
19
|
+
end
|
data/lib/paperclip.rb
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
|
28
28
|
require 'erb'
|
29
29
|
require 'tempfile'
|
30
|
+
require 'paperclip/version'
|
30
31
|
require 'paperclip/upfile'
|
31
32
|
require 'paperclip/iostream'
|
32
33
|
require 'paperclip/geometry'
|
@@ -34,9 +35,12 @@ require 'paperclip/processor'
|
|
34
35
|
require 'paperclip/thumbnail'
|
35
36
|
require 'paperclip/storage'
|
36
37
|
require 'paperclip/interpolations'
|
38
|
+
require 'paperclip/style'
|
37
39
|
require 'paperclip/attachment'
|
38
|
-
|
39
|
-
|
40
|
+
require 'paperclip/callback_compatability'
|
41
|
+
require 'paperclip/railtie'
|
42
|
+
if defined?(Rails.root) && Rails.root
|
43
|
+
Dir.glob(File.join(File.expand_path(Rails.root), "lib", "paperclip_processors", "*.rb")).each do |processor|
|
40
44
|
require processor
|
41
45
|
end
|
42
46
|
end
|
@@ -45,16 +49,14 @@ end
|
|
45
49
|
# documentation for Paperclip::ClassMethods for more useful information.
|
46
50
|
module Paperclip
|
47
51
|
|
48
|
-
VERSION = "2.3.1.1"
|
49
|
-
|
50
52
|
class << self
|
51
53
|
# Provides configurability to Paperclip. There are a number of options available, such as:
|
52
|
-
# * whiny: Will raise an error if Paperclip cannot process thumbnails of
|
54
|
+
# * whiny: Will raise an error if Paperclip cannot process thumbnails of
|
53
55
|
# an uploaded image. Defaults to true.
|
54
56
|
# * log: Logs progress to the Rails log. Uses ActiveRecord's logger, so honors
|
55
57
|
# log levels, etc. Defaults to true.
|
56
58
|
# * command_path: Defines the path at which to find the command line
|
57
|
-
# programs if they are not visible to Rails the system's search path. Defaults to
|
59
|
+
# programs if they are not visible to Rails the system's search path. Defaults to
|
58
60
|
# nil, which uses the first executable found in the user's search path.
|
59
61
|
# * image_magick_path: Deprecated alias of command_path.
|
60
62
|
def options
|
@@ -63,11 +65,15 @@ module Paperclip
|
|
63
65
|
:image_magick_path => nil,
|
64
66
|
:command_path => nil,
|
65
67
|
:log => true,
|
66
|
-
:log_command =>
|
68
|
+
:log_command => true,
|
67
69
|
:swallow_stderr => true
|
68
70
|
}
|
69
71
|
end
|
70
72
|
|
73
|
+
def configure
|
74
|
+
yield(self) if block_given?
|
75
|
+
end
|
76
|
+
|
71
77
|
def path_for_command command #:nodoc:
|
72
78
|
if options[:image_magick_path]
|
73
79
|
warn("[DEPRECATION] :image_magick_path is deprecated and will be removed. Use :command_path instead")
|
@@ -80,7 +86,7 @@ module Paperclip
|
|
80
86
|
Paperclip::Interpolations[key] = block
|
81
87
|
end
|
82
88
|
|
83
|
-
# The run method takes a command to execute and
|
89
|
+
# The run method takes a command to execute and an array of parameters
|
84
90
|
# that get passed to it. The command is prefixed with the :command_path
|
85
91
|
# option from Paperclip.options. If you have many commands to run and
|
86
92
|
# they are in different paths, the suggested course of action is to
|
@@ -89,29 +95,55 @@ module Paperclip
|
|
89
95
|
# If the command returns with a result code that is not one of the
|
90
96
|
# expected_outcodes, a PaperclipCommandLineError will be raised. Generally
|
91
97
|
# a code of 0 is expected, but a list of codes may be passed if necessary.
|
98
|
+
# These codes should be passed as a hash as the last argument, like so:
|
92
99
|
#
|
93
|
-
#
|
100
|
+
# Paperclip.run("echo", "something", :expected_outcodes => [0,1,2,3])
|
101
|
+
#
|
102
|
+
# This method can log the command being run when
|
94
103
|
# Paperclip.options[:log_command] is set to true (defaults to false). This
|
95
104
|
# will only log if logging in general is set to true as well.
|
96
|
-
def run cmd, params
|
97
|
-
|
105
|
+
def run cmd, *params
|
106
|
+
options = params.last.is_a?(Hash) ? params.pop : {}
|
107
|
+
expected_outcodes = options[:expected_outcodes] || [0]
|
108
|
+
params = quote_command_options(*params).join(" ")
|
109
|
+
|
110
|
+
command = %Q[#{path_for_command(cmd)} #{params}]
|
98
111
|
command = "#{command} 2>#{bit_bucket}" if Paperclip.options[:swallow_stderr]
|
99
112
|
Paperclip.log(command) if Paperclip.options[:log_command]
|
100
|
-
|
101
|
-
|
102
|
-
|
113
|
+
|
114
|
+
begin
|
115
|
+
output = `#{command}`
|
116
|
+
|
117
|
+
raise CommandNotFoundError if $?.exitstatus == 127
|
118
|
+
|
119
|
+
unless expected_outcodes.include?($?.exitstatus)
|
120
|
+
raise PaperclipCommandLineError,
|
121
|
+
"Error while running #{cmd}. Expected return code to be #{expected_outcodes.join(", ")} but was #{$?.exitstatus}",
|
122
|
+
output
|
123
|
+
end
|
124
|
+
rescue Errno::ENOENT => e
|
125
|
+
raise CommandNotFoundError
|
103
126
|
end
|
127
|
+
|
104
128
|
output
|
105
129
|
end
|
106
130
|
|
131
|
+
def quote_command_options(*options)
|
132
|
+
options.map do |option|
|
133
|
+
option.split("'").map{|m| "'#{m}'" }.join("\\'")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
107
137
|
def bit_bucket #:nodoc:
|
108
138
|
File.exists?("/dev/null") ? "/dev/null" : "NUL"
|
109
139
|
end
|
110
140
|
|
111
141
|
def included base #:nodoc:
|
112
142
|
base.extend ClassMethods
|
113
|
-
|
114
|
-
base.send
|
143
|
+
if base.respond_to?("set_callback")
|
144
|
+
base.send :include, Paperclip::CallbackCompatability::Rails3
|
145
|
+
else
|
146
|
+
base.send :include, Paperclip::CallbackCompatability::Rails21
|
115
147
|
end
|
116
148
|
end
|
117
149
|
|
@@ -119,7 +151,7 @@ module Paperclip
|
|
119
151
|
name = name.to_s.camelize
|
120
152
|
processor = Paperclip.const_get(name)
|
121
153
|
unless processor.ancestors.include?(Paperclip::Processor)
|
122
|
-
raise PaperclipError.new("Processor #{name} was not found")
|
154
|
+
raise PaperclipError.new("Processor #{name} was not found")
|
123
155
|
end
|
124
156
|
processor
|
125
157
|
end
|
@@ -142,56 +174,64 @@ module Paperclip
|
|
142
174
|
class PaperclipError < StandardError #:nodoc:
|
143
175
|
end
|
144
176
|
|
145
|
-
class PaperclipCommandLineError <
|
177
|
+
class PaperclipCommandLineError < PaperclipError #:nodoc:
|
178
|
+
attr_accessor :output
|
179
|
+
def initialize(msg = nil, output = nil)
|
180
|
+
super(msg)
|
181
|
+
@output = output
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class CommandNotFoundError < PaperclipError
|
146
186
|
end
|
147
187
|
|
148
188
|
class NotIdentifiedByImageMagickError < PaperclipError #:nodoc:
|
149
189
|
end
|
150
|
-
|
190
|
+
|
151
191
|
class InfiniteInterpolationError < PaperclipError #:nodoc:
|
152
192
|
end
|
153
193
|
|
154
194
|
module ClassMethods
|
155
195
|
# +has_attached_file+ gives the class it is called on an attribute that maps to a file. This
|
156
|
-
# is typically a file stored somewhere on the filesystem and has been uploaded by a user.
|
196
|
+
# is typically a file stored somewhere on the filesystem and has been uploaded by a user.
|
157
197
|
# The attribute returns a Paperclip::Attachment object which handles the management of
|
158
|
-
# that file. The intent is to make the attachment as much like a normal attribute. The
|
159
|
-
# thumbnails will be created when the new file is assigned, but they will *not* be saved
|
160
|
-
# until +save+ is called on the record. Likewise, if the attribute is set to +nil+ is
|
161
|
-
# called on it, the attachment will *not* be deleted until +save+ is called. See the
|
162
|
-
# Paperclip::Attachment documentation for more specifics. There are a number of options
|
198
|
+
# that file. The intent is to make the attachment as much like a normal attribute. The
|
199
|
+
# thumbnails will be created when the new file is assigned, but they will *not* be saved
|
200
|
+
# until +save+ is called on the record. Likewise, if the attribute is set to +nil+ is
|
201
|
+
# called on it, the attachment will *not* be deleted until +save+ is called. See the
|
202
|
+
# Paperclip::Attachment documentation for more specifics. There are a number of options
|
163
203
|
# you can set to change the behavior of a Paperclip attachment:
|
164
204
|
# * +url+: The full URL of where the attachment is publically accessible. This can just
|
165
205
|
# as easily point to a directory served directly through Apache as it can to an action
|
166
206
|
# that can control permissions. You can specify the full domain and path, but usually
|
167
|
-
# just an absolute path is sufficient. The leading slash *must* be included manually for
|
168
|
-
# absolute paths. The default value is
|
207
|
+
# just an absolute path is sufficient. The leading slash *must* be included manually for
|
208
|
+
# absolute paths. The default value is
|
169
209
|
# "/system/:attachment/:id/:style/:filename". See
|
170
210
|
# Paperclip::Attachment#interpolate for more information on variable interpolaton.
|
171
211
|
# :url => "/:class/:attachment/:id/:style_:filename"
|
172
212
|
# :url => "http://some.other.host/stuff/:class/:id_:extension"
|
173
|
-
# * +default_url+: The URL that will be returned if there is no attachment assigned.
|
174
|
-
# This field is interpolated just as the url is. The default value is
|
213
|
+
# * +default_url+: The URL that will be returned if there is no attachment assigned.
|
214
|
+
# This field is interpolated just as the url is. The default value is
|
175
215
|
# "/:attachment/:style/missing.png"
|
176
216
|
# has_attached_file :avatar, :default_url => "/images/default_:style_avatar.png"
|
177
217
|
# User.new.avatar_url(:small) # => "/images/default_small_avatar.png"
|
178
|
-
# * +styles+: A hash of thumbnail styles and their geometries. You can find more about
|
179
|
-
# geometry strings at the ImageMagick website
|
218
|
+
# * +styles+: A hash of thumbnail styles and their geometries. You can find more about
|
219
|
+
# geometry strings at the ImageMagick website
|
180
220
|
# (http://www.imagemagick.org/script/command-line-options.php#resize). Paperclip
|
181
|
-
# also adds the "#" option (e.g. "50x50#"), which will resize the image to fit maximally
|
182
|
-
# inside the dimensions and then crop the rest off (weighted at the center). The
|
221
|
+
# also adds the "#" option (e.g. "50x50#"), which will resize the image to fit maximally
|
222
|
+
# inside the dimensions and then crop the rest off (weighted at the center). The
|
183
223
|
# default value is to generate no thumbnails.
|
184
|
-
# * +default_style+: The thumbnail style that will be used by default URLs.
|
224
|
+
# * +default_style+: The thumbnail style that will be used by default URLs.
|
185
225
|
# Defaults to +original+.
|
186
226
|
# has_attached_file :avatar, :styles => { :normal => "100x100#" },
|
187
227
|
# :default_style => :normal
|
188
228
|
# user.avatar.url # => "/avatars/23/normal_me.png"
|
189
229
|
# * +whiny+: Will raise an error if Paperclip cannot post_process an uploaded file due
|
190
|
-
# to a command line error. This will override the global setting for this attachment.
|
230
|
+
# to a command line error. This will override the global setting for this attachment.
|
191
231
|
# Defaults to true. This option used to be called :whiny_thumbanils, but this is
|
192
232
|
# deprecated.
|
193
233
|
# * +convert_options+: When creating thumbnails, use this free-form options
|
194
|
-
#
|
234
|
+
# array to pass in various convert command options. Typical options are "-strip" to
|
195
235
|
# remove all Exif data from the image (save space for thumbnails and avatars) or
|
196
236
|
# "-depth 8" to specify the bit depth of the resulting conversion. See ImageMagick
|
197
237
|
# convert documentation for more options: (http://www.imagemagick.org/script/convert.php)
|
@@ -208,6 +248,9 @@ module Paperclip
|
|
208
248
|
# NOTE: While not deprecated yet, it is not recommended to specify options this way.
|
209
249
|
# It is recommended that :convert_options option be included in the hash passed to each
|
210
250
|
# :styles for compatability with future versions.
|
251
|
+
# NOTE: Strings supplied to :convert_options are split on space in order to undergo
|
252
|
+
# shell quoting for safety. If your options require a space, please pre-split them
|
253
|
+
# and pass an array to :convert_options instead.
|
211
254
|
# * +storage+: Chooses the storage backend where the files will be stored. The current
|
212
255
|
# choices are :filesystem and :s3. The default is :filesystem. Make sure you read the
|
213
256
|
# documentation for Paperclip::Storage::Filesystem and Paperclip::Storage::S3
|
@@ -221,9 +264,8 @@ module Paperclip
|
|
221
264
|
after_save :save_attached_files
|
222
265
|
before_destroy :destroy_attached_files
|
223
266
|
|
224
|
-
|
225
|
-
|
226
|
-
|
267
|
+
define_paperclip_callbacks :post_process, :"#{name}_post_process"
|
268
|
+
|
227
269
|
define_method name do |*args|
|
228
270
|
a = attachment_for(name)
|
229
271
|
(args.length > 0) ? a.to_s(args.first) : a
|
@@ -239,7 +281,7 @@ module Paperclip
|
|
239
281
|
|
240
282
|
validates_each(name) do |record, attr, value|
|
241
283
|
attachment = record.attachment_for(name)
|
242
|
-
attachment.send(:flush_errors)
|
284
|
+
attachment.send(:flush_errors)
|
243
285
|
end
|
244
286
|
end
|
245
287
|
|
@@ -257,13 +299,13 @@ module Paperclip
|
|
257
299
|
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
|
258
300
|
range = (min..max)
|
259
301
|
message = options[:message] || "file size must be between :min and :max bytes."
|
302
|
+
message = message.gsub(/:min/, min.to_s).gsub(/:max/, max.to_s)
|
260
303
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
:unless => options[:unless]}]
|
304
|
+
validates_inclusion_of :"#{name}_file_size",
|
305
|
+
:in => range,
|
306
|
+
:message => message,
|
307
|
+
:if => options[:if],
|
308
|
+
:unless => options[:unless]
|
267
309
|
end
|
268
310
|
|
269
311
|
# Adds errors if thumbnail creation fails. The same as specifying :whiny_thumbnails => true.
|
@@ -281,18 +323,19 @@ module Paperclip
|
|
281
323
|
# * +unless+: Same as +if+ but validates if lambda or method returns false.
|
282
324
|
def validates_attachment_presence name, options = {}
|
283
325
|
message = options[:message] || "must be set."
|
284
|
-
|
285
|
-
|
286
|
-
|
326
|
+
validates_presence_of :"#{name}_file_name",
|
327
|
+
:message => message,
|
328
|
+
:if => options[:if],
|
329
|
+
:unless => options[:unless]
|
287
330
|
end
|
288
|
-
|
331
|
+
|
289
332
|
# Places ActiveRecord-style validations on the content type of the file
|
290
|
-
# assigned. The possible options are:
|
291
|
-
# * +content_type+: Allowed content types. Can be a single content type
|
292
|
-
# or an array. Each type can be a String or a Regexp. It should be
|
293
|
-
# noted that Internet Explorer upload files with content_types that you
|
294
|
-
# may not expect. For example, JPEG images are given image/pjpeg and
|
295
|
-
# PNGs are image/x-png, so keep that in mind when determining how you
|
333
|
+
# assigned. The possible options are:
|
334
|
+
# * +content_type+: Allowed content types. Can be a single content type
|
335
|
+
# or an array. Each type can be a String or a Regexp. It should be
|
336
|
+
# noted that Internet Explorer upload files with content_types that you
|
337
|
+
# may not expect. For example, JPEG images are given image/pjpeg and
|
338
|
+
# PNGs are image/x-png, so keep that in mind when determining how you
|
296
339
|
# match. Allows all by default.
|
297
340
|
# * +message+: The message to display when the uploaded file has an invalid
|
298
341
|
# content type.
|
@@ -303,10 +346,17 @@ module Paperclip
|
|
303
346
|
# model, content_type validation will work _ONLY upon assignment_ and
|
304
347
|
# re-validation after the instance has been reloaded will always succeed.
|
305
348
|
def validates_attachment_content_type name, options = {}
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
349
|
+
types = [options.delete(:content_type)].flatten
|
350
|
+
validates_each(:"#{name}_content_type", options) do |record, attr, value|
|
351
|
+
unless types.any?{|t| t === value }
|
352
|
+
if record.errors.method(:add).arity == -2
|
353
|
+
message = options[:message] || "is not one of #{types.join(", ")}"
|
354
|
+
record.errors.add(:"#{name}_content_type", message)
|
355
|
+
else
|
356
|
+
record.errors.add(:"#{name}_content_type", :inclusion, :default => options[:message], :value => value)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
310
360
|
end
|
311
361
|
|
312
362
|
# Returns the attachment definitions defined by each call to
|
@@ -321,7 +371,7 @@ module Paperclip
|
|
321
371
|
@_paperclip_attachments ||= {}
|
322
372
|
@_paperclip_attachments[name] ||= Attachment.new(name, self, self.class.attachment_definitions[name])
|
323
373
|
end
|
324
|
-
|
374
|
+
|
325
375
|
def each_attachment
|
326
376
|
self.class.attachment_definitions.each do |name, definition|
|
327
377
|
yield(name, attachment_for(name))
|
@@ -329,14 +379,14 @@ module Paperclip
|
|
329
379
|
end
|
330
380
|
|
331
381
|
def save_attached_files
|
332
|
-
|
382
|
+
Paperclip.log("Saving attachments.")
|
333
383
|
each_attachment do |name, attachment|
|
334
384
|
attachment.send(:save)
|
335
385
|
end
|
336
386
|
end
|
337
387
|
|
338
388
|
def destroy_attached_files
|
339
|
-
|
389
|
+
Paperclip.log("Deleting attachments.")
|
340
390
|
each_attachment do |name, attachment|
|
341
391
|
attachment.send(:queue_existing_for_delete)
|
342
392
|
attachment.send(:flush_deletes)
|
@@ -345,9 +395,3 @@ module Paperclip
|
|
345
395
|
end
|
346
396
|
|
347
397
|
end
|
348
|
-
|
349
|
-
# Set it all up.
|
350
|
-
if Object.const_defined?("ActiveRecord")
|
351
|
-
ActiveRecord::Base.send(:include, Paperclip)
|
352
|
-
File.send(:include, Paperclip::Upfile)
|
353
|
-
end
|