carrierwave-pressplane 0.5.8.3
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.md +748 -0
- data/lib/carrierwave.rb +116 -0
- data/lib/carrierwave/compatibility/paperclip.rb +95 -0
- data/lib/carrierwave/locale/en.yml +9 -0
- data/lib/carrierwave/mount.rb +382 -0
- data/lib/carrierwave/orm/activerecord.rb +46 -0
- data/lib/carrierwave/processing/mime_types.rb +58 -0
- data/lib/carrierwave/processing/mini_magick.rb +252 -0
- data/lib/carrierwave/processing/rmagick.rb +279 -0
- data/lib/carrierwave/sanitized_file.rb +315 -0
- data/lib/carrierwave/storage/abstract.rb +30 -0
- data/lib/carrierwave/storage/cloud_files.rb +188 -0
- data/lib/carrierwave/storage/file.rb +56 -0
- data/lib/carrierwave/storage/fog.rb +333 -0
- data/lib/carrierwave/storage/right_s3.rb +1 -0
- data/lib/carrierwave/storage/s3.rb +240 -0
- data/lib/carrierwave/test/matchers.rb +241 -0
- data/lib/carrierwave/uploader.rb +44 -0
- data/lib/carrierwave/uploader/cache.rb +178 -0
- data/lib/carrierwave/uploader/callbacks.rb +35 -0
- data/lib/carrierwave/uploader/configuration.rb +168 -0
- data/lib/carrierwave/uploader/default_url.rb +19 -0
- data/lib/carrierwave/uploader/download.rb +75 -0
- data/lib/carrierwave/uploader/extension_whitelist.rb +49 -0
- data/lib/carrierwave/uploader/mountable.rb +39 -0
- data/lib/carrierwave/uploader/processing.rb +90 -0
- data/lib/carrierwave/uploader/proxy.rb +77 -0
- data/lib/carrierwave/uploader/remove.rb +23 -0
- data/lib/carrierwave/uploader/store.rb +113 -0
- data/lib/carrierwave/uploader/url.rb +47 -0
- data/lib/carrierwave/uploader/versions.rb +237 -0
- data/lib/carrierwave/validations/active_model.rb +64 -0
- data/lib/carrierwave/version.rb +3 -0
- data/lib/generators/templates/uploader.rb +48 -0
- data/lib/generators/uploader_generator.rb +7 -0
- metadata +215 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module CarrierWave
|
|
4
|
+
module Uploader
|
|
5
|
+
module Callbacks
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
class_attribute :_before_callbacks, :_after_callbacks,
|
|
10
|
+
:instance_writer => false
|
|
11
|
+
self._before_callbacks = Hash.new []
|
|
12
|
+
self._after_callbacks = Hash.new []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def with_callbacks(kind, *args)
|
|
16
|
+
self.class._before_callbacks[kind].each { |c| send c, *args }
|
|
17
|
+
yield
|
|
18
|
+
self.class._after_callbacks[kind].each { |c| send c, *args }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module ClassMethods
|
|
22
|
+
def before(kind, callback)
|
|
23
|
+
self._before_callbacks = self._before_callbacks.
|
|
24
|
+
merge kind => _before_callbacks[kind] + [callback]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def after(kind, callback)
|
|
28
|
+
self._after_callbacks = self._after_callbacks.
|
|
29
|
+
merge kind => _after_callbacks[kind] + [callback]
|
|
30
|
+
end
|
|
31
|
+
end # ClassMethods
|
|
32
|
+
|
|
33
|
+
end # Callbacks
|
|
34
|
+
end # Uploader
|
|
35
|
+
end # CarrierWave
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
module CarrierWave
|
|
2
|
+
|
|
3
|
+
module Uploader
|
|
4
|
+
module Configuration
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
class_attribute :_storage, :instance_writer => false
|
|
9
|
+
|
|
10
|
+
add_config :root
|
|
11
|
+
add_config :base_path
|
|
12
|
+
add_config :permissions
|
|
13
|
+
add_config :storage_engines
|
|
14
|
+
add_config :s3_access_policy
|
|
15
|
+
add_config :s3_bucket
|
|
16
|
+
add_config :s3_access_key_id
|
|
17
|
+
add_config :s3_secret_access_key
|
|
18
|
+
add_config :s3_cnamed
|
|
19
|
+
add_config :s3_headers
|
|
20
|
+
add_config :s3_region
|
|
21
|
+
add_config :s3_use_ssl
|
|
22
|
+
add_config :s3_authentication_timeout
|
|
23
|
+
add_config :cloud_files_username
|
|
24
|
+
add_config :cloud_files_api_key
|
|
25
|
+
add_config :cloud_files_container
|
|
26
|
+
add_config :cloud_files_cdn_host
|
|
27
|
+
add_config :cloud_files_auth_url
|
|
28
|
+
add_config :cloud_files_snet
|
|
29
|
+
add_config :grid_fs_connection
|
|
30
|
+
add_config :grid_fs_database
|
|
31
|
+
add_config :grid_fs_host
|
|
32
|
+
add_config :grid_fs_port
|
|
33
|
+
add_config :grid_fs_username
|
|
34
|
+
add_config :grid_fs_password
|
|
35
|
+
add_config :grid_fs_access_url
|
|
36
|
+
add_config :store_dir
|
|
37
|
+
add_config :cache_dir
|
|
38
|
+
add_config :enable_processing
|
|
39
|
+
add_config :ensure_multipart_form
|
|
40
|
+
add_config :delete_tmp_file_after_storage
|
|
41
|
+
add_config :move_to_cache
|
|
42
|
+
add_config :move_to_store
|
|
43
|
+
add_config :remove_previously_stored_files_after_update
|
|
44
|
+
|
|
45
|
+
# fog
|
|
46
|
+
add_config :fog_attributes
|
|
47
|
+
add_config :fog_credentials
|
|
48
|
+
add_config :fog_directory
|
|
49
|
+
add_config :fog_host
|
|
50
|
+
add_config :fog_public
|
|
51
|
+
add_config :fog_authenticated_url_expiration
|
|
52
|
+
|
|
53
|
+
# Mounting
|
|
54
|
+
add_config :ignore_integrity_errors
|
|
55
|
+
add_config :ignore_processing_errors
|
|
56
|
+
add_config :validate_integrity
|
|
57
|
+
add_config :validate_processing
|
|
58
|
+
add_config :mount_on
|
|
59
|
+
|
|
60
|
+
# set default values
|
|
61
|
+
reset_config
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module ClassMethods
|
|
65
|
+
|
|
66
|
+
##
|
|
67
|
+
# Sets the storage engine to be used when storing files with this uploader.
|
|
68
|
+
# Can be any class that implements a #store!(CarrierWave::SanitizedFile) and a #retrieve!
|
|
69
|
+
# method. See lib/carrierwave/storage/file.rb for an example. Storage engines should
|
|
70
|
+
# be added to CarrierWave::Uploader::Base.storage_engines so they can be referred
|
|
71
|
+
# to by a symbol, which should be more convenient
|
|
72
|
+
#
|
|
73
|
+
# If no argument is given, it will simply return the currently used storage engine.
|
|
74
|
+
#
|
|
75
|
+
# === Parameters
|
|
76
|
+
#
|
|
77
|
+
# [storage (Symbol, Class)] The storage engine to use for this uploader
|
|
78
|
+
#
|
|
79
|
+
# === Returns
|
|
80
|
+
#
|
|
81
|
+
# [Class] the storage engine to be used with this uploader
|
|
82
|
+
#
|
|
83
|
+
# === Examples
|
|
84
|
+
#
|
|
85
|
+
# storage :file
|
|
86
|
+
# storage CarrierWave::Storage::File
|
|
87
|
+
# storage MyCustomStorageEngine
|
|
88
|
+
#
|
|
89
|
+
def storage(storage = nil)
|
|
90
|
+
if storage
|
|
91
|
+
self._storage = storage.is_a?(Symbol) ? eval(storage_engines[storage]) : storage
|
|
92
|
+
end
|
|
93
|
+
_storage
|
|
94
|
+
end
|
|
95
|
+
alias_method :storage=, :storage
|
|
96
|
+
|
|
97
|
+
def add_config(name)
|
|
98
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
99
|
+
def self.#{name}(value=nil)
|
|
100
|
+
@#{name} = value if value
|
|
101
|
+
return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
|
|
102
|
+
name = superclass.#{name}
|
|
103
|
+
return nil if name.nil? && !instance_variable_defined?("@#{name}")
|
|
104
|
+
@#{name} = name && !name.is_a?(Module) && !name.is_a?(Symbol) && !name.is_a?(Numeric) && !name.is_a?(TrueClass) && !name.is_a?(FalseClass) ? name.dup : name
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def self.#{name}=(value)
|
|
108
|
+
@#{name} = value
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def #{name}
|
|
112
|
+
self.class.#{name}
|
|
113
|
+
end
|
|
114
|
+
RUBY
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def configure
|
|
118
|
+
yield self
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# sets configuration back to default
|
|
123
|
+
#
|
|
124
|
+
def reset_config
|
|
125
|
+
configure do |config|
|
|
126
|
+
config.permissions = 0644
|
|
127
|
+
config.storage_engines = {
|
|
128
|
+
:file => "CarrierWave::Storage::File",
|
|
129
|
+
:fog => "CarrierWave::Storage::Fog",
|
|
130
|
+
:s3 => "CarrierWave::Storage::S3",
|
|
131
|
+
:grid_fs => "CarrierWave::Storage::GridFS",
|
|
132
|
+
:right_s3 => "CarrierWave::Storage::RightS3",
|
|
133
|
+
:cloud_files => "CarrierWave::Storage::CloudFiles"
|
|
134
|
+
}
|
|
135
|
+
config.storage = :file
|
|
136
|
+
config.s3_headers = {}
|
|
137
|
+
config.s3_access_policy = :public_read
|
|
138
|
+
config.s3_region = 'us-east-1'
|
|
139
|
+
config.s3_authentication_timeout = 600
|
|
140
|
+
config.grid_fs_database = 'carrierwave'
|
|
141
|
+
config.grid_fs_host = 'localhost'
|
|
142
|
+
config.grid_fs_port = 27017
|
|
143
|
+
config.fog_attributes = {}
|
|
144
|
+
config.fog_credentials = {}
|
|
145
|
+
config.fog_public = true
|
|
146
|
+
config.fog_authenticated_url_expiration = 600
|
|
147
|
+
config.store_dir = 'uploads'
|
|
148
|
+
config.cache_dir = 'uploads/tmp'
|
|
149
|
+
config.delete_tmp_file_after_storage = true
|
|
150
|
+
config.move_to_cache = false
|
|
151
|
+
config.move_to_store = false
|
|
152
|
+
config.remove_previously_stored_files_after_update = true
|
|
153
|
+
config.ignore_integrity_errors = true
|
|
154
|
+
config.ignore_processing_errors = true
|
|
155
|
+
config.validate_integrity = true
|
|
156
|
+
config.validate_processing = true
|
|
157
|
+
config.root = CarrierWave.root
|
|
158
|
+
config.base_path = CarrierWave.base_path
|
|
159
|
+
config.enable_processing = true
|
|
160
|
+
config.ensure_multipart_form = true
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module CarrierWave
|
|
4
|
+
module Uploader
|
|
5
|
+
module DefaultUrl
|
|
6
|
+
|
|
7
|
+
def url(*args)
|
|
8
|
+
super || default_url
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Override this method in your uploader to provide a default url
|
|
13
|
+
# in case no file has been cached/stored yet.
|
|
14
|
+
#
|
|
15
|
+
def default_url; end
|
|
16
|
+
|
|
17
|
+
end # DefaultPath
|
|
18
|
+
end # Uploader
|
|
19
|
+
end # CarrierWave
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'open-uri'
|
|
4
|
+
|
|
5
|
+
module CarrierWave
|
|
6
|
+
module Uploader
|
|
7
|
+
module Download
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
include CarrierWave::Uploader::Callbacks
|
|
11
|
+
include CarrierWave::Uploader::Configuration
|
|
12
|
+
include CarrierWave::Uploader::Cache
|
|
13
|
+
|
|
14
|
+
class RemoteFile
|
|
15
|
+
def initialize(uri)
|
|
16
|
+
@uri = uri
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def original_filename
|
|
20
|
+
File.basename(file.base_uri.path)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def respond_to?(*args)
|
|
24
|
+
super or file.respond_to?(*args)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def http?
|
|
28
|
+
@uri.scheme =~ /^https?$/
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def file
|
|
34
|
+
if @file.blank?
|
|
35
|
+
@file = Kernel.open(@uri.to_s)
|
|
36
|
+
@file = @file.is_a?(String) ? StringIO.new(@file) : @file
|
|
37
|
+
end
|
|
38
|
+
@file
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def method_missing(*args, &block)
|
|
42
|
+
file.send(*args, &block)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# Caches the file by downloading it from the given URL.
|
|
48
|
+
#
|
|
49
|
+
# === Parameters
|
|
50
|
+
#
|
|
51
|
+
# [url (String)] The URL where the remote file is stored
|
|
52
|
+
#
|
|
53
|
+
def download!(uri)
|
|
54
|
+
unless uri.blank?
|
|
55
|
+
processed_uri = process_uri(uri)
|
|
56
|
+
file = RemoteFile.new(processed_uri)
|
|
57
|
+
raise CarrierWave::DownloadError, "trying to download a file which is not served over HTTP" unless file.http?
|
|
58
|
+
cache!(file)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Processes the given URL by parsing and escaping it. Public to allow overriding.
|
|
64
|
+
#
|
|
65
|
+
# === Parameters
|
|
66
|
+
#
|
|
67
|
+
# [url (String)] The URL where the remote file is stored
|
|
68
|
+
#
|
|
69
|
+
def process_uri(uri)
|
|
70
|
+
URI.parse(URI.escape(URI.unescape(uri)))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end # Download
|
|
74
|
+
end # Uploader
|
|
75
|
+
end # CarrierWave
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module CarrierWave
|
|
4
|
+
module Uploader
|
|
5
|
+
module ExtensionWhitelist
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
before :cache, :check_whitelist!
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Override this method in your uploader to provide a white list of extensions which
|
|
14
|
+
# are allowed to be uploaded. Compares the file's extension case insensitive.
|
|
15
|
+
# Furthermore, not only strings but Regexp are allowed as well.
|
|
16
|
+
#
|
|
17
|
+
# When using a Regexp in the white list, `\A` and `\z` are automatically added to
|
|
18
|
+
# the Regexp expression, also case insensitive.
|
|
19
|
+
#
|
|
20
|
+
# === Returns
|
|
21
|
+
#
|
|
22
|
+
# [NilClass, Array[String,Regexp]] a white list of extensions which are allowed to be uploaded
|
|
23
|
+
#
|
|
24
|
+
# === Examples
|
|
25
|
+
#
|
|
26
|
+
# def extension_white_list
|
|
27
|
+
# %w(jpg jpeg gif png)
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# Basically the same, but using a Regexp:
|
|
31
|
+
#
|
|
32
|
+
# def extension_white_list
|
|
33
|
+
# [/jpe?g/, 'gif', 'png']
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
def extension_white_list; end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def check_whitelist!(new_file)
|
|
41
|
+
extension = new_file.extension.to_s
|
|
42
|
+
if extension_white_list and not extension_white_list.detect { |item| extension =~ /\A#{item}\z/i }
|
|
43
|
+
raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_white_list_error", :extension => new_file.extension.inspect, :allowed_types => extension_white_list.inspect)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end # ExtensionWhitelist
|
|
48
|
+
end # Uploader
|
|
49
|
+
end # CarrierWave
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module CarrierWave
|
|
4
|
+
module Uploader
|
|
5
|
+
module Mountable
|
|
6
|
+
|
|
7
|
+
attr_reader :model, :mounted_as
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# If a model is given as the first parameter, it will stored in the uploader, and
|
|
11
|
+
# available throught +#model+. Likewise, mounted_as stores the name of the column
|
|
12
|
+
# where this instance of the uploader is mounted. These values can then be used inside
|
|
13
|
+
# your uploader.
|
|
14
|
+
#
|
|
15
|
+
# If you do not wish to mount your uploaders with the ORM extensions in -more then you
|
|
16
|
+
# can override this method inside your uploader. Just be sure to call +super+
|
|
17
|
+
#
|
|
18
|
+
# === Parameters
|
|
19
|
+
#
|
|
20
|
+
# [model (Object)] Any kind of model object
|
|
21
|
+
# [mounted_as (Symbol)] The name of the column where this uploader is mounted
|
|
22
|
+
#
|
|
23
|
+
# === Examples
|
|
24
|
+
#
|
|
25
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
|
26
|
+
#
|
|
27
|
+
# def store_dir
|
|
28
|
+
# File.join('public', 'files', mounted_as, model.permalink)
|
|
29
|
+
# end
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
def initialize(model=nil, mounted_as=nil)
|
|
33
|
+
@model = model
|
|
34
|
+
@mounted_as = mounted_as
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end # Mountable
|
|
38
|
+
end # Uploader
|
|
39
|
+
end # CarrierWave
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module CarrierWave
|
|
4
|
+
module Uploader
|
|
5
|
+
module Processing
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
include CarrierWave::Uploader::Callbacks
|
|
9
|
+
|
|
10
|
+
included do
|
|
11
|
+
class_attribute :processors, :instance_writer => false
|
|
12
|
+
self.processors = []
|
|
13
|
+
|
|
14
|
+
after :cache, :process!
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module ClassMethods
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Adds a processor callback which applies operations as a file is uploaded.
|
|
21
|
+
# The argument may be the name of any method of the uploader, expressed as a symbol,
|
|
22
|
+
# or a list of such methods, or a hash where the key is a method and the value is
|
|
23
|
+
# an array of arguments to call the method with
|
|
24
|
+
#
|
|
25
|
+
# === Parameters
|
|
26
|
+
#
|
|
27
|
+
# args (*Symbol, Hash{Symbol => Array[]})
|
|
28
|
+
#
|
|
29
|
+
# === Examples
|
|
30
|
+
#
|
|
31
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
|
32
|
+
#
|
|
33
|
+
# process :sepiatone, :vignette
|
|
34
|
+
# process :scale => [200, 200]
|
|
35
|
+
# process :scale => [200, 200], :if => :image?
|
|
36
|
+
# process :sepiatone, :if => :image?
|
|
37
|
+
#
|
|
38
|
+
# def sepiatone
|
|
39
|
+
# ...
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# def vignette
|
|
43
|
+
# ...
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# def scale(height, width)
|
|
47
|
+
# ...
|
|
48
|
+
# end
|
|
49
|
+
#
|
|
50
|
+
# def image?
|
|
51
|
+
# ...
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
# end
|
|
55
|
+
#
|
|
56
|
+
def process(*args)
|
|
57
|
+
if !args.first.is_a?(Hash) && args.last.is_a?(Hash)
|
|
58
|
+
conditions = args.pop
|
|
59
|
+
args.map!{ |arg| {arg => []}.merge(conditions) }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
args.each do |arg|
|
|
63
|
+
if arg.is_a?(Hash)
|
|
64
|
+
condition = arg.delete(:if)
|
|
65
|
+
arg.each do |method, args|
|
|
66
|
+
self.processors += [[method, args, condition]]
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
self.processors += [[arg, [], nil]]
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end # ClassMethods
|
|
75
|
+
|
|
76
|
+
##
|
|
77
|
+
# Apply all process callbacks added through CarrierWave.process
|
|
78
|
+
#
|
|
79
|
+
def process!(new_file=nil)
|
|
80
|
+
if enable_processing
|
|
81
|
+
self.class.processors.each do |method, args, condition|
|
|
82
|
+
next if condition && !self.send(condition, new_file)
|
|
83
|
+
self.send(method, *args)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end # Processing
|
|
89
|
+
end # Uploader
|
|
90
|
+
end # CarrierWave
|