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.

Files changed (94) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +9 -7
  3. data/Appraisals +6 -12
  4. data/Gemfile +2 -0
  5. data/NEWS +24 -0
  6. data/README.md +53 -21
  7. data/Rakefile +7 -2
  8. data/UPGRADING +14 -0
  9. data/features/basic_integration.feature +8 -8
  10. data/features/rake_tasks.feature +1 -1
  11. data/features/step_definitions/attachment_steps.rb +11 -2
  12. data/features/step_definitions/rails_steps.rb +17 -79
  13. data/features/support/env.rb +3 -0
  14. data/features/support/file_helpers.rb +24 -0
  15. data/features/support/rails.rb +3 -3
  16. data/gemfiles/{rails3_1.gemfile → 3.0.gemfile} +3 -1
  17. data/gemfiles/{rails2.gemfile → 3.1.gemfile} +3 -1
  18. data/gemfiles/{rails3.gemfile → 3.2.gemfile} +3 -1
  19. data/images.rake +21 -0
  20. data/lib/generators/paperclip/paperclip_generator.rb +1 -2
  21. data/lib/paperclip.rb +48 -319
  22. data/lib/paperclip/attachment.rb +33 -81
  23. data/lib/paperclip/attachment_options.rb +0 -1
  24. data/lib/paperclip/callbacks.rb +30 -0
  25. data/lib/paperclip/errors.rb +27 -0
  26. data/lib/paperclip/geometry.rb +6 -4
  27. data/lib/paperclip/glue.rb +15 -0
  28. data/lib/paperclip/helpers.rb +71 -0
  29. data/lib/paperclip/instance_methods.rb +35 -0
  30. data/lib/paperclip/interpolations.rb +2 -2
  31. data/lib/paperclip/io_adapters/attachment_adapter.rb +62 -0
  32. data/lib/paperclip/io_adapters/file_adapter.rb +81 -0
  33. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  34. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  35. data/lib/paperclip/io_adapters/registry.rb +32 -0
  36. data/lib/paperclip/io_adapters/stringio_adapter.rb +64 -0
  37. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +63 -0
  38. data/lib/paperclip/locales/en.yml +17 -0
  39. data/lib/paperclip/logger.rb +21 -0
  40. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +1 -1
  41. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -2
  42. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +7 -7
  43. data/lib/paperclip/processor.rb +32 -17
  44. data/lib/paperclip/railtie.rb +10 -15
  45. data/lib/paperclip/storage/filesystem.rb +5 -14
  46. data/lib/paperclip/storage/fog.rb +2 -21
  47. data/lib/paperclip/storage/s3.rb +12 -29
  48. data/lib/paperclip/tempfile.rb +41 -0
  49. data/lib/paperclip/thumbnail.rb +2 -3
  50. data/lib/paperclip/validators.rb +45 -0
  51. data/lib/paperclip/validators/attachment_content_type_validator.rb +47 -0
  52. data/lib/paperclip/validators/attachment_presence_validator.rb +26 -0
  53. data/lib/paperclip/validators/attachment_size_validator.rb +102 -0
  54. data/lib/paperclip/version.rb +1 -1
  55. data/lib/tasks/paperclip.rake +3 -11
  56. data/paperclip.gemspec +15 -5
  57. data/test/adapter_registry_test.rb +32 -0
  58. data/test/attachment_adapter_test.rb +48 -0
  59. data/test/attachment_options_test.rb +0 -13
  60. data/test/attachment_test.rb +27 -55
  61. data/test/file_adapter_test.rb +43 -0
  62. data/test/generator_test.rb +78 -0
  63. data/test/geometry_test.rb +5 -5
  64. data/test/helper.rb +9 -11
  65. data/test/identity_adapter_test.rb +8 -0
  66. data/test/integration_test.rb +39 -94
  67. data/test/interpolations_test.rb +8 -1
  68. data/test/matchers/validate_attachment_size_matcher_test.rb +16 -2
  69. data/test/nil_adapter_test.rb +25 -0
  70. data/test/paperclip_test.rb +30 -189
  71. data/test/storage/filesystem_test.rb +0 -14
  72. data/test/storage/fog_test.rb +0 -14
  73. data/test/storage/s3_live_test.rb +22 -9
  74. data/test/storage/s3_test.rb +70 -34
  75. data/test/stringio_adapter_test.rb +42 -0
  76. data/test/style_test.rb +10 -16
  77. data/test/thumbnail_test.rb +16 -10
  78. data/test/uploaded_file_adapter_test.rb +98 -0
  79. data/test/validators/attachment_content_type_validator_test.rb +140 -0
  80. data/test/validators/attachment_presence_validator_test.rb +85 -0
  81. data/test/validators/attachment_size_validator_test.rb +207 -0
  82. data/test/validators_test.rb +25 -0
  83. metadata +152 -30
  84. data/gemfiles/rails3_2.gemfile +0 -9
  85. data/generators/paperclip/USAGE +0 -5
  86. data/generators/paperclip/paperclip_generator.rb +0 -27
  87. data/generators/paperclip/templates/paperclip_migration.rb.erb +0 -19
  88. data/init.rb +0 -4
  89. data/lib/paperclip/callback_compatibility.rb +0 -61
  90. data/lib/paperclip/iostream.rb +0 -45
  91. data/lib/paperclip/upfile.rb +0 -64
  92. data/rails/init.rb +0 -2
  93. data/test/iostream_test.rb +0 -71
  94. data/test/upfile_test.rb +0 -53
@@ -1,6 +1,9 @@
1
1
  require 'aruba/cucumber'
2
2
  require 'capybara/cucumber'
3
3
  require 'test/unit/assertions'
4
+
5
+ $CUCUMBER=1
6
+
4
7
  World(Test::Unit::Assertions)
5
8
 
6
9
  Before do
@@ -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)
@@ -32,15 +32,15 @@ module RailsCommandHelpers
32
32
  end
33
33
 
34
34
  def new_application_command
35
- framework_version?("3") ? "rails new" : "rails"
35
+ "rails new"
36
36
  end
37
37
 
38
38
  def generator_command
39
- framework_version?("3") ? "script/rails generate" : "script/generate"
39
+ "script/rails generate"
40
40
  end
41
41
 
42
42
  def runner_command
43
- framework_version?("3") ? "script/rails runner" : "script/runner"
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 "rails", "~> 3.1.0"
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 "rails", "~> 2.3.14"
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 "rails", "~> 3.0.10"
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=>"../"
@@ -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
@@ -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/callback_compatibility'
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
- class << self
53
- # Provides configurability to Paperclip. The options available are:
54
- # * whiny: Will raise an error if Paperclip cannot process thumbnails of
55
- # an uploaded image. Defaults to true.
56
- # * log: Logs progress to the Rails log. Uses ActiveRecord's logger, so honors
57
- # log levels, etc. Defaults to true.
58
- # * command_path: Defines the path at which to find the command line
59
- # programs if they are not visible to Rails the system's search path. Defaults to
60
- # nil, which uses the first executable found in the user's search path.
61
- # * image_magick_path: Deprecated alias of command_path.
62
- def options
63
- @options ||= {
64
- :whiny => true,
65
- :image_magick_path => nil,
66
- :command_path => nil,
67
- :log => true,
68
- :log_command => true,
69
- :swallow_stderr => true
70
- }
71
- end
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
- class NotIdentifiedByImageMagickError < PaperclipError #:nodoc:
80
+ def self.io_adapters=(new_registry)
81
+ @io_adapters = new_registry
218
82
  end
219
83
 
220
- class InfiniteInterpolationError < PaperclipError #:nodoc:
221
- end
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. This option used to be called :whiny_thumbanils, but this is
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 name, options = {}
168
+ def has_attached_file(name, options = {})
317
169
  include InstanceMethods
318
170
 
319
171
  if attachment_definitions.nil?
320
- if respond_to?(:class_attribute)
321
- self.attachment_definitions = {}
322
- else
323
- write_inheritable_attribute(:attachment_definitions, {})
324
- end
172
+ self.attachment_definitions = {}
325
173
  else
326
- if respond_to?(:class_attribute)
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
- if respond_to?(:class_attribute)
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'