carrierwave-rails3 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +527 -0
- data/lib/carrierwave.rb +103 -0
- data/lib/carrierwave/compatibility/paperclip.rb +95 -0
- data/lib/carrierwave/core_ext/file.rb +11 -0
- data/lib/carrierwave/mount.rb +359 -0
- data/lib/carrierwave/orm/activerecord.rb +75 -0
- data/lib/carrierwave/orm/datamapper.rb +27 -0
- data/lib/carrierwave/orm/mongoid.rb +23 -0
- data/lib/carrierwave/orm/mongomapper.rb +27 -0
- data/lib/carrierwave/orm/sequel.rb +45 -0
- data/lib/carrierwave/processing/image_science.rb +116 -0
- data/lib/carrierwave/processing/mini_magick.rb +261 -0
- data/lib/carrierwave/processing/rmagick.rb +278 -0
- data/lib/carrierwave/sanitized_file.rb +273 -0
- data/lib/carrierwave/storage/abstract.rb +30 -0
- data/lib/carrierwave/storage/cloud_files.rb +169 -0
- data/lib/carrierwave/storage/file.rb +48 -0
- data/lib/carrierwave/storage/grid_fs.rb +104 -0
- data/lib/carrierwave/storage/right_s3.rb +3 -0
- data/lib/carrierwave/storage/s3.rb +206 -0
- data/lib/carrierwave/test/matchers.rb +164 -0
- data/lib/carrierwave/uploader.rb +44 -0
- data/lib/carrierwave/uploader/cache.rb +146 -0
- data/lib/carrierwave/uploader/callbacks.rb +41 -0
- data/lib/carrierwave/uploader/configuration.rb +134 -0
- data/lib/carrierwave/uploader/default_url.rb +19 -0
- data/lib/carrierwave/uploader/download.rb +60 -0
- data/lib/carrierwave/uploader/extension_whitelist.rb +38 -0
- data/lib/carrierwave/uploader/mountable.rb +39 -0
- data/lib/carrierwave/uploader/processing.rb +84 -0
- data/lib/carrierwave/uploader/proxy.rb +62 -0
- data/lib/carrierwave/uploader/remove.rb +23 -0
- data/lib/carrierwave/uploader/store.rb +90 -0
- data/lib/carrierwave/uploader/url.rb +33 -0
- data/lib/carrierwave/uploader/versions.rb +147 -0
- data/lib/generators/templates/uploader.rb +47 -0
- data/lib/generators/uploader_generator.rb +13 -0
- data/spec/compatibility/paperclip_spec.rb +52 -0
- data/spec/mount_spec.rb +538 -0
- data/spec/orm/activerecord_spec.rb +271 -0
- data/spec/orm/datamapper_spec.rb +168 -0
- data/spec/orm/mongoid_spec.rb +202 -0
- data/spec/orm/mongomapper_spec.rb +202 -0
- data/spec/orm/sequel_spec.rb +183 -0
- data/spec/processing/image_science_spec.rb +56 -0
- data/spec/processing/mini_magick_spec.rb +76 -0
- data/spec/processing/rmagick_spec.rb +75 -0
- data/spec/sanitized_file_spec.rb +623 -0
- data/spec/spec_helper.rb +92 -0
- data/spec/storage/cloudfiles_spec.rb +78 -0
- data/spec/storage/grid_fs_spec.rb +86 -0
- data/spec/storage/s3_spec.rb +118 -0
- data/spec/uploader/cache_spec.rb +209 -0
- data/spec/uploader/callback_spec.rb +24 -0
- data/spec/uploader/configuration_spec.rb +105 -0
- data/spec/uploader/default_url_spec.rb +85 -0
- data/spec/uploader/download_spec.rb +75 -0
- data/spec/uploader/extension_whitelist_spec.rb +44 -0
- data/spec/uploader/mountable_spec.rb +33 -0
- data/spec/uploader/paths_spec.rb +22 -0
- data/spec/uploader/processing_spec.rb +73 -0
- data/spec/uploader/proxy_spec.rb +54 -0
- data/spec/uploader/remove_spec.rb +70 -0
- data/spec/uploader/store_spec.rb +264 -0
- data/spec/uploader/url_spec.rb +102 -0
- data/spec/uploader/versions_spec.rb +298 -0
- metadata +128 -0
data/lib/carrierwave.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'carrierwave/core_ext/file'
|
5
|
+
require 'active_support/core_ext/object/blank'
|
6
|
+
require 'active_support/core_ext/class/inheritable_attributes'
|
7
|
+
require 'active_support/concern'
|
8
|
+
|
9
|
+
module CarrierWave
|
10
|
+
|
11
|
+
VERSION = "0.4.5"
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_accessor :root
|
15
|
+
|
16
|
+
def configure(&block)
|
17
|
+
CarrierWave::Uploader::Base.configure(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def clean_cached_files!
|
21
|
+
CarrierWave::Uploader::Base.clean_cached_files!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class UploadError < StandardError; end
|
26
|
+
class IntegrityError < UploadError; end
|
27
|
+
class InvalidParameter < UploadError; end
|
28
|
+
class ProcessingError < UploadError; end
|
29
|
+
class DownloadError < UploadError; end
|
30
|
+
|
31
|
+
autoload :SanitizedFile, 'carrierwave/sanitized_file'
|
32
|
+
autoload :Mount, 'carrierwave/mount'
|
33
|
+
autoload :RMagick, 'carrierwave/processing/rmagick'
|
34
|
+
autoload :ImageScience, 'carrierwave/processing/image_science'
|
35
|
+
autoload :MiniMagick, 'carrierwave/processing/mini_magick'
|
36
|
+
|
37
|
+
module Storage
|
38
|
+
autoload :Abstract, 'carrierwave/storage/abstract'
|
39
|
+
autoload :File, 'carrierwave/storage/file'
|
40
|
+
autoload :S3, 'carrierwave/storage/s3'
|
41
|
+
autoload :GridFS, 'carrierwave/storage/grid_fs'
|
42
|
+
autoload :RightS3, 'carrierwave/storage/right_s3'
|
43
|
+
autoload :CloudFiles, 'carrierwave/storage/cloud_files'
|
44
|
+
end
|
45
|
+
|
46
|
+
module Uploader
|
47
|
+
autoload :Base, 'carrierwave/uploader'
|
48
|
+
autoload :Cache, 'carrierwave/uploader/cache'
|
49
|
+
autoload :Store, 'carrierwave/uploader/store'
|
50
|
+
autoload :Download, 'carrierwave/uploader/download'
|
51
|
+
autoload :Callbacks, 'carrierwave/uploader/callbacks'
|
52
|
+
autoload :Processing, 'carrierwave/uploader/processing'
|
53
|
+
autoload :Versions, 'carrierwave/uploader/versions'
|
54
|
+
autoload :Remove, 'carrierwave/uploader/remove'
|
55
|
+
autoload :ExtensionWhitelist, 'carrierwave/uploader/extension_whitelist'
|
56
|
+
autoload :DefaultUrl, 'carrierwave/uploader/default_url'
|
57
|
+
autoload :Proxy, 'carrierwave/uploader/proxy'
|
58
|
+
autoload :Url, 'carrierwave/uploader/url'
|
59
|
+
autoload :Mountable, 'carrierwave/uploader/mountable'
|
60
|
+
autoload :Configuration, 'carrierwave/uploader/configuration'
|
61
|
+
end
|
62
|
+
|
63
|
+
module Compatibility
|
64
|
+
autoload :Paperclip, 'carrierwave/compatibility/paperclip'
|
65
|
+
end
|
66
|
+
|
67
|
+
module Test
|
68
|
+
autoload :Matchers, 'carrierwave/test/matchers'
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
if defined?(Merb)
|
74
|
+
|
75
|
+
CarrierWave.root = Merb.dir_for(:public)
|
76
|
+
Merb::BootLoader.before_app_loads do
|
77
|
+
# Setup path for uploaders and load all of them before classes are loaded
|
78
|
+
Merb.push_path(:uploaders, Merb.root / 'app' / 'uploaders', '*.rb')
|
79
|
+
Dir.glob(File.join(Merb.load_paths[:uploaders])).each {|f| require f }
|
80
|
+
end
|
81
|
+
|
82
|
+
elsif defined?(Rails)
|
83
|
+
|
84
|
+
module CarrierWave
|
85
|
+
class Railtie < Rails::Railtie
|
86
|
+
initializer "carrierwave.setup_paths" do
|
87
|
+
CarrierWave.root = Rails.root.join(Rails.public_path).to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
elsif defined?(Sinatra)
|
93
|
+
|
94
|
+
CarrierWave.root = Sinatra::Application.public
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
require File.join(File.dirname(__FILE__), "carrierwave", "orm", 'activerecord') if defined?(ActiveRecord)
|
100
|
+
require File.join(File.dirname(__FILE__), "carrierwave", "orm", 'datamapper') if defined?(DataMapper)
|
101
|
+
require File.join(File.dirname(__FILE__), "carrierwave", "orm", 'sequel') if defined?(Sequel)
|
102
|
+
require File.join(File.dirname(__FILE__), "carrierwave", "orm", "mongomapper") if defined?(MongoMapper)
|
103
|
+
require File.join(File.dirname(__FILE__), "carrierwave", "orm", "mongoid") if defined?(Mongoid)
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
module Compatibility
|
5
|
+
|
6
|
+
##
|
7
|
+
# Mix this module into an Uploader to make it mimic Paperclip's storage paths
|
8
|
+
# This will make your Uploader use the same default storage path as paperclip
|
9
|
+
# does. If you need to override it, you can override the +paperclip_path+ method
|
10
|
+
# and provide a Paperclip style path:
|
11
|
+
#
|
12
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
13
|
+
# include CarrierWave::Compatibility::Paperclip
|
14
|
+
#
|
15
|
+
# def paperclip_path
|
16
|
+
# ":rails_root/public/uploads/:id/:attachment/:style_:basename.:extension"
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# ---
|
21
|
+
#
|
22
|
+
# This file contains code taken from Paperclip
|
23
|
+
#
|
24
|
+
# LICENSE
|
25
|
+
#
|
26
|
+
# The MIT License
|
27
|
+
#
|
28
|
+
# Copyright (c) 2008 Jon Yurek and thoughtbot, inc.
|
29
|
+
#
|
30
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
31
|
+
# of this software and associated documentation files (the "Software"), to deal
|
32
|
+
# in the Software without restriction, including without limitation the rights
|
33
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
34
|
+
# copies of the Software, and to permit persons to whom the Software is
|
35
|
+
# furnished to do so, subject to the following conditions:
|
36
|
+
#
|
37
|
+
# The above copyright notice and this permission notice shall be included in
|
38
|
+
# all copies or substantial portions of the Software.
|
39
|
+
#
|
40
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
41
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
42
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
43
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
44
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
45
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
46
|
+
# THE SOFTWARE.
|
47
|
+
#
|
48
|
+
module Paperclip
|
49
|
+
|
50
|
+
def store_path(for_file=filename)
|
51
|
+
path = paperclip_path
|
52
|
+
path ||= File.join(*[store_dir, paperclip_style.to_s, for_file].compact)
|
53
|
+
interpolate_paperclip_path(path, for_file)
|
54
|
+
end
|
55
|
+
|
56
|
+
def store_dir
|
57
|
+
":rails_root/public/system/:attachment/:id"
|
58
|
+
end
|
59
|
+
|
60
|
+
def paperclip_default_style
|
61
|
+
:original
|
62
|
+
end
|
63
|
+
|
64
|
+
def paperclip_path
|
65
|
+
end
|
66
|
+
|
67
|
+
def paperclip_style
|
68
|
+
version_name || paperclip_default_style
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def interpolate_paperclip_path(path, filename)
|
74
|
+
mappings.inject(path) do |agg, pair|
|
75
|
+
agg.gsub(":#{pair[0]}") { pair[1].call(self, filename).to_s }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def mappings
|
80
|
+
{
|
81
|
+
:rails_root => lambda{|u, f| Rails.root },
|
82
|
+
:rails_env => lambda{|u, f| Rails.env },
|
83
|
+
:class => lambda{|u, f| u.model.class.name.underscore.pluralize},
|
84
|
+
:id => lambda{|u, f| u.model.id },
|
85
|
+
:id_partition => lambda{|u, f| ("%09d" % u.model.id).scan(/\d{3}/).join("/")},
|
86
|
+
:attachment => lambda{|u, f| u.mounted_as.to_s.downcase.pluralize },
|
87
|
+
:style => lambda{|u, f| u.paperclip_style },
|
88
|
+
:basename => lambda{|u, f| f.gsub(/#{File.extname(f)}$/, "") },
|
89
|
+
:extension => lambda{|u, f| File.extname(f).gsub(/^\.+/, "")}
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
end # Paperclip
|
94
|
+
end # Compatibility
|
95
|
+
end # CarrierWave
|
@@ -0,0 +1,359 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
|
5
|
+
##
|
6
|
+
# If a Class is extended with this module, it gains the mount_uploader
|
7
|
+
# method, which is used for mapping attributes to uploaders and allowing
|
8
|
+
# easy assignment.
|
9
|
+
#
|
10
|
+
# You can use mount_uploader with pretty much any class, however it is
|
11
|
+
# intended to be used with some kind of persistent storage, like an ORM.
|
12
|
+
# If you want to persist the uploaded files in a particular Class, it
|
13
|
+
# needs to implement a `read_uploader` and a `write_uploader` method.
|
14
|
+
#
|
15
|
+
module Mount
|
16
|
+
|
17
|
+
##
|
18
|
+
# === Returns
|
19
|
+
#
|
20
|
+
# [Hash{Symbol => CarrierWave}] what uploaders are mounted on which columns
|
21
|
+
#
|
22
|
+
def uploaders
|
23
|
+
@uploaders ||= {}
|
24
|
+
@uploaders = superclass.uploaders.merge(@uploaders)
|
25
|
+
rescue NoMethodError
|
26
|
+
@uploaders
|
27
|
+
end
|
28
|
+
|
29
|
+
def uploader_options
|
30
|
+
@uploader_options ||= {}
|
31
|
+
@uploader_options = superclass.uploader_options.merge(@uploader_options)
|
32
|
+
rescue NoMethodError
|
33
|
+
@uploader_options
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Return a particular option for a particular uploader
|
38
|
+
#
|
39
|
+
# === Parameters
|
40
|
+
#
|
41
|
+
# [column (Symbol)] The column the uploader is mounted at
|
42
|
+
# [option (Symbol)] The option, e.g. validate_integrity
|
43
|
+
#
|
44
|
+
# === Returns
|
45
|
+
#
|
46
|
+
# [Object] The option value
|
47
|
+
#
|
48
|
+
def uploader_option(column, option)
|
49
|
+
if uploader_options[column].has_key?(option)
|
50
|
+
uploader_options[column][option]
|
51
|
+
else
|
52
|
+
uploaders[column].send(option)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Mounts the given uploader on the given column. This means that assigning
|
58
|
+
# and reading from the column will upload and retrieve files. Supposing
|
59
|
+
# that a User class has an uploader mounted on image, you can assign and
|
60
|
+
# retrieve files like this:
|
61
|
+
#
|
62
|
+
# @user.image # => <Uploader>
|
63
|
+
# @user.image = some_file_object
|
64
|
+
#
|
65
|
+
# @user.store_image!
|
66
|
+
#
|
67
|
+
# @user.image.url # => '/some_url.png'
|
68
|
+
#
|
69
|
+
# It is also possible (but not recommended) to ommit the uploader, which
|
70
|
+
# will create an anonymous uploader class. Passing a block to this method
|
71
|
+
# makes it possible to customize it. This can be convenient for brevity,
|
72
|
+
# but if there is any significatnt logic in the uploader, you should do
|
73
|
+
# the right thing and have it in its own file.
|
74
|
+
#
|
75
|
+
# === Added instance methods
|
76
|
+
#
|
77
|
+
# Supposing a class has used +mount_uploader+ to mount an uploader on a column
|
78
|
+
# named +image+, in that case the following methods will be added to the class:
|
79
|
+
#
|
80
|
+
# [image] Returns an instance of the uploader only if anything has been uploaded
|
81
|
+
# [image=] Caches the given file
|
82
|
+
#
|
83
|
+
# [image_url] Returns the url to the uploaded file
|
84
|
+
#
|
85
|
+
# [image_cache] Returns a string that identifies the cache location of the file
|
86
|
+
# [image_cache=] Retrieves the file from the cache based on the given cache name
|
87
|
+
#
|
88
|
+
# [remote_image_url] Returns previously cached remote url
|
89
|
+
# [remote_image_url=] Retrieve the file from the remote url
|
90
|
+
#
|
91
|
+
# [remove_image] An attribute reader that can be used with a checkbox to mark a file for removal
|
92
|
+
# [remove_image=] An attribute writer that can be used with a checkbox to mark a file for removal
|
93
|
+
# [remove_image?] Whether the file should be removed when store_image! is called.
|
94
|
+
#
|
95
|
+
# [store_image!] Stores a file that has been assigned with +image=+
|
96
|
+
# [remove_image!] Removes the uploaded file from the filesystem.
|
97
|
+
#
|
98
|
+
# [image_integrity_error] Returns an error object if the last file to be assigned caused an integrity error
|
99
|
+
# [image_processing_error] Returns an error object if the last file to be assigned caused a processing error
|
100
|
+
#
|
101
|
+
# [write_image_identifier] Uses the write_uploader method to set the identifier.
|
102
|
+
#
|
103
|
+
# === Parameters
|
104
|
+
#
|
105
|
+
# [column (Symbol)] the attribute to mount this uploader on
|
106
|
+
# [uploader (CarrierWave::Uploader)] the uploader class to mount
|
107
|
+
# [options (Hash{Symbol => Object})] a set of options
|
108
|
+
# [&block (Proc)] customize anonymous uploaders
|
109
|
+
#
|
110
|
+
# === Options
|
111
|
+
#
|
112
|
+
# [:mount_on => Symbol] if the name of the column to be serialized to differs you can override it using this option
|
113
|
+
# [:ignore_integrity_errors => Boolean] if set to true, integrity errors will result in caching failing silently
|
114
|
+
# [:ignore_processing_errors => Boolean] if set to true, processing errors will result in caching failing silently
|
115
|
+
#
|
116
|
+
# === Examples
|
117
|
+
#
|
118
|
+
# Mounting uploaders on different columns.
|
119
|
+
#
|
120
|
+
# class Song
|
121
|
+
# mount_uploader :lyrics, LyricsUploader
|
122
|
+
# mount_uploader :alternative_lyrics, LyricsUploader
|
123
|
+
# mount_uploader :file, SongUploader
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# This will add an anonymous uploader with only the default settings:
|
127
|
+
#
|
128
|
+
# class Data
|
129
|
+
# mount_uploader :csv
|
130
|
+
# end
|
131
|
+
#
|
132
|
+
# this will add an anonymous uploader overriding the store_dir:
|
133
|
+
#
|
134
|
+
# class Product
|
135
|
+
# mount_uploader :blueprint do
|
136
|
+
# def store_dir
|
137
|
+
# 'blueprints'
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
def mount_uploader(column, uploader=nil, options={}, &block)
|
143
|
+
unless uploader
|
144
|
+
uploader = Class.new(CarrierWave::Uploader::Base)
|
145
|
+
uploader.class_eval(&block)
|
146
|
+
end
|
147
|
+
|
148
|
+
uploaders[column.to_sym] = uploader
|
149
|
+
uploader_options[column.to_sym] = options
|
150
|
+
|
151
|
+
include CarrierWave::Mount::Extension
|
152
|
+
|
153
|
+
# Make sure to write over accessors directly defined on the class.
|
154
|
+
# Simply super to the included module below.
|
155
|
+
class_eval <<-RUBY, __FILE__, __LINE__+1
|
156
|
+
def #{column}; super; end
|
157
|
+
def #{column}=(new_file); super; end
|
158
|
+
RUBY
|
159
|
+
|
160
|
+
# Mixing this in as a Module instead of class_evaling directly, so we
|
161
|
+
# can maintain the ability to super to any of these methods from within
|
162
|
+
# the class.
|
163
|
+
mod = Module.new
|
164
|
+
include mod
|
165
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
166
|
+
|
167
|
+
def #{column}
|
168
|
+
_mounter(:#{column}).uploader
|
169
|
+
end
|
170
|
+
|
171
|
+
def #{column}=(new_file)
|
172
|
+
_mounter(:#{column}).cache(new_file)
|
173
|
+
end
|
174
|
+
|
175
|
+
def #{column}?
|
176
|
+
!_mounter(:#{column}).blank?
|
177
|
+
end
|
178
|
+
|
179
|
+
def #{column}_url(*args)
|
180
|
+
_mounter(:#{column}).url(*args)
|
181
|
+
end
|
182
|
+
|
183
|
+
def #{column}_cache
|
184
|
+
_mounter(:#{column}).cache_name
|
185
|
+
end
|
186
|
+
|
187
|
+
def #{column}_cache=(cache_name)
|
188
|
+
_mounter(:#{column}).cache_name = cache_name
|
189
|
+
end
|
190
|
+
|
191
|
+
def remote_#{column}_url
|
192
|
+
_mounter(:#{column}).remote_url
|
193
|
+
end
|
194
|
+
|
195
|
+
def remote_#{column}_url=(url)
|
196
|
+
_mounter(:#{column}).remote_url = url
|
197
|
+
end
|
198
|
+
|
199
|
+
def remove_#{column}
|
200
|
+
_mounter(:#{column}).remove
|
201
|
+
end
|
202
|
+
|
203
|
+
def remove_#{column}!
|
204
|
+
_mounter(:#{column}).remove!
|
205
|
+
end
|
206
|
+
|
207
|
+
def remove_#{column}=(value)
|
208
|
+
_mounter(:#{column}).remove = value
|
209
|
+
end
|
210
|
+
|
211
|
+
def remove_#{column}?
|
212
|
+
_mounter(:#{column}).remove?
|
213
|
+
end
|
214
|
+
|
215
|
+
def store_#{column}!
|
216
|
+
_mounter(:#{column}).store!
|
217
|
+
end
|
218
|
+
|
219
|
+
def #{column}_integrity_error
|
220
|
+
_mounter(:#{column}).integrity_error
|
221
|
+
end
|
222
|
+
|
223
|
+
def #{column}_processing_error
|
224
|
+
_mounter(:#{column}).processing_error
|
225
|
+
end
|
226
|
+
|
227
|
+
def write_#{column}_identifier
|
228
|
+
_mounter(:#{column}).write_identifier
|
229
|
+
end
|
230
|
+
|
231
|
+
RUBY
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
module Extension
|
236
|
+
|
237
|
+
##
|
238
|
+
# overwrite this to read from a serialized attribute
|
239
|
+
#
|
240
|
+
def read_uploader(column); end
|
241
|
+
|
242
|
+
##
|
243
|
+
# overwrite this to write to a serialized attribute
|
244
|
+
#
|
245
|
+
def write_uploader(column, identifier); end
|
246
|
+
|
247
|
+
private
|
248
|
+
|
249
|
+
def _mounter(column)
|
250
|
+
# We cannot memoize in frozen objects :(
|
251
|
+
return Mounter.new(self, column) if frozen?
|
252
|
+
@_mounters ||= {}
|
253
|
+
@_mounters[column] ||= Mounter.new(self, column)
|
254
|
+
end
|
255
|
+
|
256
|
+
end # Extension
|
257
|
+
|
258
|
+
# this is an internal class, used by CarrierWave::Mount so that
|
259
|
+
# we don't pollute the model with a lot of methods.
|
260
|
+
class Mounter #:nodoc:
|
261
|
+
|
262
|
+
attr_reader :column, :record, :remote_url, :integrity_error, :processing_error
|
263
|
+
attr_accessor :remove
|
264
|
+
|
265
|
+
def initialize(record, column, options={})
|
266
|
+
@record = record
|
267
|
+
@column = column
|
268
|
+
@options = record.class.uploader_options[column]
|
269
|
+
end
|
270
|
+
|
271
|
+
def write_identifier
|
272
|
+
if remove?
|
273
|
+
record.write_uploader(serialization_column, '')
|
274
|
+
elsif not uploader.identifier.blank?
|
275
|
+
record.write_uploader(serialization_column, uploader.identifier)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def identifier
|
280
|
+
record.read_uploader(serialization_column)
|
281
|
+
end
|
282
|
+
|
283
|
+
def uploader
|
284
|
+
@uploader ||= record.class.uploaders[column].new(record, column)
|
285
|
+
|
286
|
+
if @uploader.blank? and not identifier.blank?
|
287
|
+
@uploader.retrieve_from_store!(identifier)
|
288
|
+
end
|
289
|
+
return @uploader
|
290
|
+
end
|
291
|
+
|
292
|
+
def cache(new_file)
|
293
|
+
uploader.cache!(new_file)
|
294
|
+
@integrity_error = nil
|
295
|
+
@processing_error = nil
|
296
|
+
rescue CarrierWave::IntegrityError => e
|
297
|
+
@integrity_error = e
|
298
|
+
raise e unless option(:ignore_integrity_errors)
|
299
|
+
rescue CarrierWave::ProcessingError => e
|
300
|
+
@processing_error = e
|
301
|
+
raise e unless option(:ignore_processing_errors)
|
302
|
+
end
|
303
|
+
|
304
|
+
def cache_name
|
305
|
+
uploader.cache_name
|
306
|
+
end
|
307
|
+
|
308
|
+
def cache_name=(cache_name)
|
309
|
+
uploader.retrieve_from_cache!(cache_name) unless uploader.cached?
|
310
|
+
rescue CarrierWave::InvalidParameter
|
311
|
+
end
|
312
|
+
|
313
|
+
def remote_url=(url)
|
314
|
+
unless uploader.cached?
|
315
|
+
@remote_url = url
|
316
|
+
uploader.download!(url)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def store!
|
321
|
+
unless uploader.blank?
|
322
|
+
if remove?
|
323
|
+
uploader.remove!
|
324
|
+
else
|
325
|
+
uploader.store!
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def url(*args)
|
331
|
+
uploader.url(*args)
|
332
|
+
end
|
333
|
+
|
334
|
+
def blank?
|
335
|
+
uploader.blank?
|
336
|
+
end
|
337
|
+
|
338
|
+
def remove?
|
339
|
+
!remove.blank? and remove !~ /\A0|false$\z/
|
340
|
+
end
|
341
|
+
|
342
|
+
def remove!
|
343
|
+
uploader.remove!
|
344
|
+
end
|
345
|
+
|
346
|
+
private
|
347
|
+
|
348
|
+
def option(name)
|
349
|
+
record.class.uploader_option(column, name)
|
350
|
+
end
|
351
|
+
|
352
|
+
def serialization_column
|
353
|
+
option(:mount_on) || column
|
354
|
+
end
|
355
|
+
|
356
|
+
end # Mounter
|
357
|
+
|
358
|
+
end # Mount
|
359
|
+
end # CarrierWave
|