paperclip 2.8.0 → 3.0.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/.gitignore +1 -0
- data/.travis.yml +9 -7
- data/Appraisals +6 -12
- data/Gemfile +2 -0
- data/NEWS +24 -0
- data/README.md +53 -21
- data/Rakefile +7 -2
- data/UPGRADING +14 -0
- data/features/basic_integration.feature +8 -8
- data/features/rake_tasks.feature +1 -1
- data/features/step_definitions/attachment_steps.rb +11 -2
- data/features/step_definitions/rails_steps.rb +17 -79
- data/features/support/env.rb +3 -0
- data/features/support/file_helpers.rb +24 -0
- data/features/support/rails.rb +3 -3
- data/gemfiles/{rails3_1.gemfile → 3.0.gemfile} +3 -1
- data/gemfiles/{rails2.gemfile → 3.1.gemfile} +3 -1
- data/gemfiles/{rails3.gemfile → 3.2.gemfile} +3 -1
- data/images.rake +21 -0
- data/lib/generators/paperclip/paperclip_generator.rb +1 -2
- data/lib/paperclip.rb +48 -319
- data/lib/paperclip/attachment.rb +33 -81
- data/lib/paperclip/attachment_options.rb +0 -1
- data/lib/paperclip/callbacks.rb +30 -0
- data/lib/paperclip/errors.rb +27 -0
- data/lib/paperclip/geometry.rb +6 -4
- data/lib/paperclip/glue.rb +15 -0
- data/lib/paperclip/helpers.rb +71 -0
- data/lib/paperclip/instance_methods.rb +35 -0
- data/lib/paperclip/interpolations.rb +2 -2
- data/lib/paperclip/io_adapters/attachment_adapter.rb +62 -0
- data/lib/paperclip/io_adapters/file_adapter.rb +81 -0
- data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
- data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
- data/lib/paperclip/io_adapters/registry.rb +32 -0
- data/lib/paperclip/io_adapters/stringio_adapter.rb +64 -0
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +63 -0
- data/lib/paperclip/locales/en.yml +17 -0
- data/lib/paperclip/logger.rb +21 -0
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +1 -1
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -2
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +7 -7
- data/lib/paperclip/processor.rb +32 -17
- data/lib/paperclip/railtie.rb +10 -15
- data/lib/paperclip/storage/filesystem.rb +5 -14
- data/lib/paperclip/storage/fog.rb +2 -21
- data/lib/paperclip/storage/s3.rb +12 -29
- data/lib/paperclip/tempfile.rb +41 -0
- data/lib/paperclip/thumbnail.rb +2 -3
- data/lib/paperclip/validators.rb +45 -0
- data/lib/paperclip/validators/attachment_content_type_validator.rb +47 -0
- data/lib/paperclip/validators/attachment_presence_validator.rb +26 -0
- data/lib/paperclip/validators/attachment_size_validator.rb +102 -0
- data/lib/paperclip/version.rb +1 -1
- data/lib/tasks/paperclip.rake +3 -11
- data/paperclip.gemspec +15 -5
- data/test/adapter_registry_test.rb +32 -0
- data/test/attachment_adapter_test.rb +48 -0
- data/test/attachment_options_test.rb +0 -13
- data/test/attachment_test.rb +27 -55
- data/test/file_adapter_test.rb +43 -0
- data/test/generator_test.rb +78 -0
- data/test/geometry_test.rb +5 -5
- data/test/helper.rb +9 -11
- data/test/identity_adapter_test.rb +8 -0
- data/test/integration_test.rb +39 -94
- data/test/interpolations_test.rb +8 -1
- data/test/matchers/validate_attachment_size_matcher_test.rb +16 -2
- data/test/nil_adapter_test.rb +25 -0
- data/test/paperclip_test.rb +30 -189
- data/test/storage/filesystem_test.rb +0 -14
- data/test/storage/fog_test.rb +0 -14
- data/test/storage/s3_live_test.rb +22 -9
- data/test/storage/s3_test.rb +70 -34
- data/test/stringio_adapter_test.rb +42 -0
- data/test/style_test.rb +10 -16
- data/test/thumbnail_test.rb +16 -10
- data/test/uploaded_file_adapter_test.rb +98 -0
- data/test/validators/attachment_content_type_validator_test.rb +140 -0
- data/test/validators/attachment_presence_validator_test.rb +85 -0
- data/test/validators/attachment_size_validator_test.rb +207 -0
- data/test/validators_test.rb +25 -0
- metadata +152 -30
- data/gemfiles/rails3_2.gemfile +0 -9
- data/generators/paperclip/USAGE +0 -5
- data/generators/paperclip/paperclip_generator.rb +0 -27
- data/generators/paperclip/templates/paperclip_migration.rb.erb +0 -19
- data/init.rb +0 -4
- data/lib/paperclip/callback_compatibility.rb +0 -61
- data/lib/paperclip/iostream.rb +0 -45
- data/lib/paperclip/upfile.rb +0 -64
- data/rails/init.rb +0 -2
- data/test/iostream_test.rb +0 -71
- data/test/upfile_test.rb +0 -53
data/features/support/env.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
module FileHelpers
|
2
|
+
def append_to(path, contents)
|
3
|
+
in_current_dir do
|
4
|
+
File.open(path, "a") do |file|
|
5
|
+
file.puts
|
6
|
+
file.puts contents
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def append_to_gemfile(contents)
|
12
|
+
append_to('Gemfile', contents)
|
13
|
+
end
|
14
|
+
|
15
|
+
def comment_out_gem_in_gemfile(gemname)
|
16
|
+
in_current_dir do
|
17
|
+
gemfile = File.read("Gemfile")
|
18
|
+
gemfile.sub!(/^(\s*)(gem\s*['"]#{gemname})/, "\\1# \\2")
|
19
|
+
File.open("Gemfile", 'w'){ |file| file.write(gemfile) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
World(FileHelpers)
|
data/features/support/rails.rb
CHANGED
@@ -32,15 +32,15 @@ module RailsCommandHelpers
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def new_application_command
|
35
|
-
|
35
|
+
"rails new"
|
36
36
|
end
|
37
37
|
|
38
38
|
def generator_command
|
39
|
-
|
39
|
+
"script/rails generate"
|
40
40
|
end
|
41
41
|
|
42
42
|
def runner_command
|
43
|
-
|
43
|
+
"script/rails runner"
|
44
44
|
end
|
45
45
|
end
|
46
46
|
World(RailsCommandHelpers)
|
@@ -3,7 +3,9 @@
|
|
3
3
|
source "http://rubygems.org"
|
4
4
|
|
5
5
|
gem "jruby-openssl", :platform=>:jruby
|
6
|
-
gem "
|
6
|
+
gem "activerecord-jdbcsqlite3-adapter", :platform=>:jruby
|
7
|
+
gem "sqlite3", :platform=>:ruby
|
8
|
+
gem "rails", "~> 3.0.12"
|
7
9
|
gem "paperclip", :path=>"../"
|
8
10
|
|
9
11
|
gemspec :path=>"../"
|
@@ -3,7 +3,9 @@
|
|
3
3
|
source "http://rubygems.org"
|
4
4
|
|
5
5
|
gem "jruby-openssl", :platform=>:jruby
|
6
|
-
gem "
|
6
|
+
gem "activerecord-jdbcsqlite3-adapter", :platform=>:jruby
|
7
|
+
gem "sqlite3", :platform=>:ruby
|
8
|
+
gem "rails", "~> 3.1.4"
|
7
9
|
gem "paperclip", :path=>"../"
|
8
10
|
|
9
11
|
gemspec :path=>"../"
|
@@ -3,7 +3,9 @@
|
|
3
3
|
source "http://rubygems.org"
|
4
4
|
|
5
5
|
gem "jruby-openssl", :platform=>:jruby
|
6
|
-
gem "
|
6
|
+
gem "activerecord-jdbcsqlite3-adapter", :platform=>:jruby
|
7
|
+
gem "sqlite3", :platform=>:ruby
|
8
|
+
gem "rails", "~> 3.2.2"
|
7
9
|
gem "paperclip", :path=>"../"
|
8
10
|
|
9
11
|
gemspec :path=>"../"
|
data/images.rake
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
namespace :images do
|
2
|
+
desc "Regenerate images"
|
3
|
+
task :regenerate => :environment do
|
4
|
+
require 'open-uri'
|
5
|
+
OpportunityPhoto.all.each do |photo|
|
6
|
+
begin
|
7
|
+
old_name = photo.image_file_name
|
8
|
+
new_image = open(photo.image.url(:original, escape: false))
|
9
|
+
class << new_image
|
10
|
+
def original_filename; @original_filename; end
|
11
|
+
def original_filename=(name); @original_filename = name; end
|
12
|
+
end
|
13
|
+
new_image.original_filename = old_name
|
14
|
+
photo.image = new_image
|
15
|
+
photo.save
|
16
|
+
rescue => e
|
17
|
+
puts "ERROR: #{e.message} while processing #{photo.id}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -19,7 +19,7 @@ class PaperclipGenerator < ActiveRecord::Generators::Base
|
|
19
19
|
protected
|
20
20
|
|
21
21
|
def migration_name
|
22
|
-
"add_attachment_#{attachment_names.join("_")}_to_#{name.underscore}"
|
22
|
+
"add_attachment_#{attachment_names.join("_")}_to_#{name.underscore.pluralize}"
|
23
23
|
end
|
24
24
|
|
25
25
|
def migration_file_name
|
@@ -29,5 +29,4 @@ class PaperclipGenerator < ActiveRecord::Generators::Base
|
|
29
29
|
def migration_class_name
|
30
30
|
migration_name.camelize
|
31
31
|
end
|
32
|
-
|
33
32
|
end
|
data/lib/paperclip.rb
CHANGED
@@ -29,207 +29,60 @@ require 'erb'
|
|
29
29
|
require 'digest'
|
30
30
|
require 'tempfile'
|
31
31
|
require 'paperclip/version'
|
32
|
-
require 'paperclip/upfile'
|
33
|
-
require 'paperclip/iostream'
|
34
32
|
require 'paperclip/geometry'
|
35
33
|
require 'paperclip/processor'
|
34
|
+
require 'paperclip/tempfile'
|
36
35
|
require 'paperclip/thumbnail'
|
37
36
|
require 'paperclip/interpolations'
|
38
37
|
require 'paperclip/style'
|
39
38
|
require 'paperclip/attachment'
|
40
39
|
require 'paperclip/attachment_options'
|
41
40
|
require 'paperclip/storage'
|
42
|
-
require 'paperclip/
|
41
|
+
require 'paperclip/callbacks'
|
42
|
+
require 'paperclip/glue'
|
43
|
+
require 'paperclip/errors'
|
43
44
|
require 'paperclip/missing_attachment_styles'
|
45
|
+
require 'paperclip/validators'
|
46
|
+
require 'paperclip/instance_methods'
|
47
|
+
require 'paperclip/logger'
|
48
|
+
require 'paperclip/helpers'
|
44
49
|
require 'paperclip/railtie'
|
50
|
+
require 'mime/types'
|
45
51
|
require 'logger'
|
46
52
|
require 'cocaine'
|
47
53
|
|
48
54
|
# The base module that gets included in ActiveRecord::Base. See the
|
49
55
|
# documentation for Paperclip::ClassMethods for more useful information.
|
50
56
|
module Paperclip
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
def configure
|
74
|
-
yield(self) if block_given?
|
75
|
-
end
|
76
|
-
|
77
|
-
def interpolates key, &block
|
78
|
-
Paperclip::Interpolations[key] = block
|
79
|
-
end
|
80
|
-
|
81
|
-
# The run method takes the name of a binary to run, the arguments to that binary
|
82
|
-
# and some options:
|
83
|
-
#
|
84
|
-
# :command_path -> A $PATH-like variable that defines where to look for the binary
|
85
|
-
# on the filesystem. Colon-separated, just like $PATH.
|
86
|
-
#
|
87
|
-
# :expected_outcodes -> An array of integers that defines the expected exit codes
|
88
|
-
# of the binary. Defaults to [0].
|
89
|
-
#
|
90
|
-
# :log_command -> Log the command being run when set to true (defaults to false).
|
91
|
-
# This will only log if logging in general is set to true as well.
|
92
|
-
#
|
93
|
-
# :swallow_stderr -> Set to true if you don't care what happens on STDERR.
|
94
|
-
#
|
95
|
-
def run(cmd, arguments = "", interpolation_values = {}, local_options = {})
|
96
|
-
if options[:image_magick_path]
|
97
|
-
Paperclip.log("[DEPRECATION] :image_magick_path is deprecated and will be removed. Use :command_path instead")
|
98
|
-
end
|
99
|
-
command_path = options[:command_path] || options[:image_magick_path]
|
100
|
-
Cocaine::CommandLine.path = [Cocaine::CommandLine.path, command_path].flatten.compact.uniq
|
101
|
-
local_options = local_options.merge(:logger => logger) if logging? && (options[:log_command] || local_options[:log_command])
|
102
|
-
Cocaine::CommandLine.new(cmd, arguments, local_options).run(interpolation_values)
|
103
|
-
end
|
104
|
-
|
105
|
-
def processor(name) #:nodoc:
|
106
|
-
@known_processors ||= {}
|
107
|
-
if @known_processors[name.to_s]
|
108
|
-
@known_processors[name.to_s]
|
109
|
-
else
|
110
|
-
name = name.to_s.camelize
|
111
|
-
load_processor(name) unless Paperclip.const_defined?(name)
|
112
|
-
processor = Paperclip.const_get(name)
|
113
|
-
@known_processors[name.to_s] = processor
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def load_processor(name)
|
118
|
-
if defined?(Rails.root) && Rails.root
|
119
|
-
require File.expand_path(Rails.root.join("lib", "paperclip_processors", "#{name.underscore}.rb"))
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def clear_processors!
|
124
|
-
@known_processors.try(:clear)
|
125
|
-
end
|
126
|
-
|
127
|
-
# You can add your own processor via the Paperclip configuration. Normally
|
128
|
-
# Paperclip will load all processors from the
|
129
|
-
# Rails.root/lib/paperclip_processors directory, but here you can add any
|
130
|
-
# existing class using this mechanism.
|
131
|
-
#
|
132
|
-
# Paperclip.configure do |c|
|
133
|
-
# c.register_processor :watermarker, WatermarkingProcessor.new
|
134
|
-
# end
|
135
|
-
def register_processor(name, processor)
|
136
|
-
@known_processors ||= {}
|
137
|
-
@known_processors[name.to_s] = processor
|
138
|
-
end
|
139
|
-
|
140
|
-
# Find all instances of the given Active Record model +klass+ with attachment +name+.
|
141
|
-
# This method is used by the refresh rake tasks.
|
142
|
-
def each_instance_with_attachment(klass, name)
|
143
|
-
unscope_method = class_for(klass).respond_to?(:unscoped) ? :unscoped : :with_exclusive_scope
|
144
|
-
class_for(klass).send(unscope_method) do
|
145
|
-
class_for(klass).find(:all, :order => 'id').each do |instance|
|
146
|
-
yield(instance) if instance.send(:"#{name}?")
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# Log a paperclip-specific line. This will logs to STDOUT
|
152
|
-
# by default. Set Paperclip.options[:log] to false to turn off.
|
153
|
-
def log message
|
154
|
-
logger.info("[paperclip] #{message}") if logging?
|
155
|
-
end
|
156
|
-
|
157
|
-
def logger #:nodoc:
|
158
|
-
@logger ||= options[:logger] || Logger.new(STDOUT)
|
159
|
-
end
|
160
|
-
|
161
|
-
def logger=(logger)
|
162
|
-
@logger = logger
|
163
|
-
end
|
164
|
-
|
165
|
-
def logging? #:nodoc:
|
166
|
-
options[:log]
|
167
|
-
end
|
168
|
-
|
169
|
-
def class_for(class_name)
|
170
|
-
# Ruby 1.9 introduces an inherit argument for Module#const_get and
|
171
|
-
# #const_defined? and changes their default behavior.
|
172
|
-
# https://github.com/rails/rails/blob/v3.0.9/activesupport/lib/active_support/inflector/methods.rb#L89
|
173
|
-
if Module.method(:const_get).arity == 1
|
174
|
-
class_name.split('::').inject(Object) do |klass, partial_class_name|
|
175
|
-
klass.const_defined?(partial_class_name) ? klass.const_get(partial_class_name) : klass.const_missing(partial_class_name)
|
176
|
-
end
|
177
|
-
else
|
178
|
-
class_name.split('::').inject(Object) do |klass, partial_class_name|
|
179
|
-
klass.const_defined?(partial_class_name) ? klass.const_get(partial_class_name, false) : klass.const_missing(partial_class_name)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
rescue ArgumentError => e
|
183
|
-
# Sadly, we need to capture ArgumentError here because Rails 2.3.x
|
184
|
-
# ActiveSupport dependency management will try to the constant inherited
|
185
|
-
# from Object, and fail miserably with "Object is not missing constant X" error
|
186
|
-
# https://github.com/rails/rails/blob/v2.3.12/activesupport/lib/active_support/dependencies.rb#L124
|
187
|
-
if e.message =~ /is not missing constant/
|
188
|
-
raise NameError, "uninitialized constant #{class_name}"
|
189
|
-
else
|
190
|
-
raise e
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
def check_for_url_clash(name,url,klass)
|
195
|
-
@names_url ||= {}
|
196
|
-
default_url = url || Attachment.default_options[:url]
|
197
|
-
if @names_url[name] && @names_url[name][:url] == default_url && @names_url[name][:class] != klass && @names_url[name][:url] !~ /:class/
|
198
|
-
log("Duplicate URL for #{name} with #{default_url}. This will clash with attachment defined in #{@names_url[name][:class]} class")
|
199
|
-
end
|
200
|
-
@names_url[name] = {:url => default_url, :class => klass}
|
201
|
-
end
|
202
|
-
|
203
|
-
def reset_duplicate_clash_check!
|
204
|
-
@names_url = nil
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
class PaperclipError < StandardError #:nodoc:
|
209
|
-
end
|
210
|
-
|
211
|
-
class StorageMethodNotFound < PaperclipError
|
212
|
-
end
|
213
|
-
|
214
|
-
class CommandNotFoundError < PaperclipError
|
57
|
+
extend Helpers
|
58
|
+
extend Logger
|
59
|
+
extend ProcessorHelpers
|
60
|
+
|
61
|
+
# Provides configurability to Paperclip. The options available are:
|
62
|
+
# * whiny: Will raise an error if Paperclip cannot process thumbnails of
|
63
|
+
# an uploaded image. Defaults to true.
|
64
|
+
# * log: Logs progress to the Rails log. Uses ActiveRecord's logger, so honors
|
65
|
+
# log levels, etc. Defaults to true.
|
66
|
+
# * command_path: Defines the path at which to find the command line
|
67
|
+
# programs if they are not visible to Rails the system's search path. Defaults to
|
68
|
+
# nil, which uses the first executable found in the user's search path.
|
69
|
+
def self.options
|
70
|
+
@options ||= {
|
71
|
+
:whiny => true,
|
72
|
+
:image_magick_path => nil,
|
73
|
+
:command_path => nil,
|
74
|
+
:log => true,
|
75
|
+
:log_command => true,
|
76
|
+
:swallow_stderr => true
|
77
|
+
}
|
215
78
|
end
|
216
79
|
|
217
|
-
|
80
|
+
def self.io_adapters=(new_registry)
|
81
|
+
@io_adapters = new_registry
|
218
82
|
end
|
219
83
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
module Glue
|
224
|
-
def self.included base #:nodoc:
|
225
|
-
base.extend ClassMethods
|
226
|
-
base.class_attribute :attachment_definitions if base.respond_to?(:class_attribute)
|
227
|
-
if base.respond_to?(:set_callback)
|
228
|
-
base.send :include, Paperclip::CallbackCompatability::Rails3
|
229
|
-
else
|
230
|
-
base.send :include, Paperclip::CallbackCompatability::Rails21
|
231
|
-
end
|
232
|
-
end
|
84
|
+
def self.io_adapters
|
85
|
+
@io_adapters ||= Paperclip::AdapterRegistry.new
|
233
86
|
end
|
234
87
|
|
235
88
|
module ClassMethods
|
@@ -272,8 +125,7 @@ module Paperclip
|
|
272
125
|
# Defaults to +false+.#
|
273
126
|
# * +whiny+: Will raise an error if Paperclip cannot post_process an uploaded file due
|
274
127
|
# to a command line error. This will override the global setting for this attachment.
|
275
|
-
# Defaults to true.
|
276
|
-
# deprecated.
|
128
|
+
# Defaults to true.
|
277
129
|
# * +convert_options+: When creating thumbnails, use this free-form options
|
278
130
|
# array to pass in various convert command options. Typical options are "-strip" to
|
279
131
|
# remove all Exif data from the image (save space for thumbnails and avatars) or
|
@@ -313,21 +165,13 @@ module Paperclip
|
|
313
165
|
# "/assets/avatars/default_#{gender}.png"
|
314
166
|
# end
|
315
167
|
# end
|
316
|
-
def has_attached_file
|
168
|
+
def has_attached_file(name, options = {})
|
317
169
|
include InstanceMethods
|
318
170
|
|
319
171
|
if attachment_definitions.nil?
|
320
|
-
|
321
|
-
self.attachment_definitions = {}
|
322
|
-
else
|
323
|
-
write_inheritable_attribute(:attachment_definitions, {})
|
324
|
-
end
|
172
|
+
self.attachment_definitions = {}
|
325
173
|
else
|
326
|
-
|
327
|
-
self.attachment_definitions = self.attachment_definitions.dup
|
328
|
-
else
|
329
|
-
write_inheritable_attribute(:attachment_definitions, self.attachment_definitions.dup)
|
330
|
-
end
|
174
|
+
self.attachment_definitions = self.attachment_definitions.dup
|
331
175
|
end
|
332
176
|
|
333
177
|
attachment_definitions[name] = Paperclip::AttachmentOptions.new(options)
|
@@ -359,134 +203,19 @@ module Paperclip
|
|
359
203
|
end
|
360
204
|
end
|
361
205
|
|
362
|
-
# Places ActiveRecord-style validations on the size of the file assigned. The
|
363
|
-
# possible options are:
|
364
|
-
# * +in+: a Range of bytes (i.e. +1..1.megabyte+),
|
365
|
-
# * +less_than+: equivalent to :in => 0..options[:less_than]
|
366
|
-
# * +greater_than+: equivalent to :in => options[:greater_than]..Infinity
|
367
|
-
# * +message+: error message to display, use :min and :max as replacements
|
368
|
-
# * +if+: A lambda or name of an instance method. Validation will only
|
369
|
-
# be run if this lambda or method returns true.
|
370
|
-
# * +unless+: Same as +if+ but validates if lambda or method returns false.
|
371
|
-
def validates_attachment_size name, options = {}
|
372
|
-
min = options[:greater_than] || (options[:in] && options[:in].first) || 0
|
373
|
-
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
|
374
|
-
range = (min..max)
|
375
|
-
message = options[:message] || "must be between :min and :max bytes"
|
376
|
-
message = message.call if message.respond_to?(:call)
|
377
|
-
message = message.gsub(/:min/, min.to_s).gsub(/:max/, max.to_s)
|
378
|
-
|
379
|
-
validates_inclusion_of :"#{name}_file_size",
|
380
|
-
:in => range,
|
381
|
-
:message => message,
|
382
|
-
:if => options[:if],
|
383
|
-
:unless => options[:unless],
|
384
|
-
:allow_nil => true
|
385
|
-
end
|
386
|
-
|
387
|
-
# Adds errors if thumbnail creation fails. The same as specifying :whiny_thumbnails => true.
|
388
|
-
def validates_attachment_thumbnails name, options = {}
|
389
|
-
warn('[DEPRECATION] validates_attachment_thumbnail is deprecated. ' +
|
390
|
-
'This validation is on by default and will be removed from future versions. ' +
|
391
|
-
'If you wish to turn it off, supply :whiny => false in your definition.')
|
392
|
-
attachment_definitions[name][:whiny_thumbnails] = true
|
393
|
-
end
|
394
|
-
|
395
|
-
# Places ActiveRecord-style validations on the presence of a file.
|
396
|
-
# Options:
|
397
|
-
# * +if+: A lambda or name of an instance method. Validation will only
|
398
|
-
# be run if this lambda or method returns true.
|
399
|
-
# * +unless+: Same as +if+ but validates if lambda or method returns false.
|
400
|
-
def validates_attachment_presence name, options = {}
|
401
|
-
message = options[:message] || :empty
|
402
|
-
validates_each :"#{name}_file_name" do |record, attr, value|
|
403
|
-
if_clause_passed = options[:if].nil? || (options[:if].respond_to?(:call) ? options[:if].call(record) != false : record.send(options[:if]))
|
404
|
-
unless_clause_passed = options[:unless].nil? || (options[:unless].respond_to?(:call) ? !!options[:unless].call(record) == false : !record.send(options[:unless]))
|
405
|
-
if if_clause_passed && unless_clause_passed && value.blank?
|
406
|
-
record.errors.add(name, message)
|
407
|
-
record.errors.add("#{name}_file_name", message)
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
# Places ActiveRecord-style validations on the content type of the file
|
413
|
-
# assigned. The possible options are:
|
414
|
-
# * +content_type+: Allowed content types. Can be a single content type
|
415
|
-
# or an array. Each type can be a String or a Regexp. It should be
|
416
|
-
# noted that Internet Explorer uploads files with content_types that you
|
417
|
-
# may not expect. For example, JPEG images are given image/pjpeg and
|
418
|
-
# PNGs are image/x-png, so keep that in mind when determining how you
|
419
|
-
# match. Allows all by default.
|
420
|
-
# * +message+: The message to display when the uploaded file has an invalid
|
421
|
-
# content type.
|
422
|
-
# * +if+: A lambda or name of an instance method. Validation will only
|
423
|
-
# be run is this lambda or method returns true.
|
424
|
-
# * +unless+: Same as +if+ but validates if lambda or method returns false.
|
425
|
-
# NOTE: If you do not specify an [attachment]_content_type field on your
|
426
|
-
# model, content_type validation will work _ONLY upon assignment_ and
|
427
|
-
# re-validation after the instance has been reloaded will always succeed.
|
428
|
-
# You'll still need to have a virtual attribute (created by +attr_accessor+)
|
429
|
-
# name +[attachment]_content_type+ to be able to use this validator.
|
430
|
-
def validates_attachment_content_type name, options = {}
|
431
|
-
validation_options = options.dup
|
432
|
-
allowed_types = [validation_options[:content_type]].flatten
|
433
|
-
validates_each(:"#{name}_content_type", validation_options) do |record, attr, value|
|
434
|
-
if !allowed_types.any?{|t| t === value } && !(value.nil? || value.blank?)
|
435
|
-
if record.errors.method(:add).arity == -2
|
436
|
-
message = options[:message] || "is not one of #{allowed_types.join(", ")}"
|
437
|
-
message = message.call if message.respond_to?(:call)
|
438
|
-
record.errors.add(:"#{name}_content_type", message)
|
439
|
-
else
|
440
|
-
record.errors.add(:"#{name}_content_type", :inclusion, :default => options[:message], :value => value)
|
441
|
-
end
|
442
|
-
end
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
206
|
# Returns the attachment definitions defined by each call to
|
447
207
|
# has_attached_file.
|
448
208
|
def attachment_definitions
|
449
|
-
|
450
|
-
self.attachment_definitions
|
451
|
-
else
|
452
|
-
read_inheritable_attribute(:attachment_definitions)
|
453
|
-
end
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
module InstanceMethods #:nodoc:
|
458
|
-
def attachment_for name
|
459
|
-
@_paperclip_attachments ||= {}
|
460
|
-
@_paperclip_attachments[name] ||= Attachment.new(name, self, self.class.attachment_definitions[name])
|
461
|
-
end
|
462
|
-
|
463
|
-
def each_attachment
|
464
|
-
self.class.attachment_definitions.each do |name, definition|
|
465
|
-
yield(name, attachment_for(name))
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
def save_attached_files
|
470
|
-
Paperclip.log("Saving attachments.")
|
471
|
-
each_attachment do |name, attachment|
|
472
|
-
attachment.send(:save)
|
473
|
-
end
|
474
|
-
end
|
475
|
-
|
476
|
-
def destroy_attached_files
|
477
|
-
Paperclip.log("Deleting attachments.")
|
478
|
-
each_attachment do |name, attachment|
|
479
|
-
attachment.send(:flush_deletes)
|
480
|
-
end
|
209
|
+
self.attachment_definitions
|
481
210
|
end
|
482
|
-
|
483
|
-
def prepare_for_destroy
|
484
|
-
Paperclip.log("Scheduling attachments for deletion.")
|
485
|
-
each_attachment do |name, attachment|
|
486
|
-
attachment.send(:queue_existing_for_delete)
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
211
|
end
|
491
|
-
|
492
212
|
end
|
213
|
+
|
214
|
+
# This stuff needs to be run after Paperclip is defined.
|
215
|
+
require 'paperclip/io_adapters/registry'
|
216
|
+
require 'paperclip/io_adapters/identity_adapter'
|
217
|
+
require 'paperclip/io_adapters/file_adapter'
|
218
|
+
require 'paperclip/io_adapters/stringio_adapter'
|
219
|
+
require 'paperclip/io_adapters/nil_adapter'
|
220
|
+
require 'paperclip/io_adapters/attachment_adapter'
|
221
|
+
require 'paperclip/io_adapters/uploaded_file_adapter'
|