carrierwave 0.11.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of carrierwave might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/README.md +255 -125
- data/lib/carrierwave/compatibility/paperclip.rb +0 -2
- data/lib/carrierwave/error.rb +1 -0
- data/lib/carrierwave/locale/en.yml +7 -4
- data/lib/carrierwave/mount.rb +219 -176
- data/lib/carrierwave/mounter.rb +165 -0
- data/lib/carrierwave/orm/activerecord.rb +50 -21
- data/lib/carrierwave/processing/mini_magick.rb +86 -15
- data/lib/carrierwave/processing/rmagick.rb +63 -8
- data/lib/carrierwave/processing.rb +0 -1
- data/lib/carrierwave/sanitized_file.rb +51 -46
- data/lib/carrierwave/storage/abstract.rb +15 -2
- data/lib/carrierwave/storage/file.rb +69 -2
- data/lib/carrierwave/storage/fog.rb +152 -33
- data/lib/carrierwave/storage.rb +0 -9
- data/lib/carrierwave/test/matchers.rb +77 -12
- data/lib/carrierwave/uploader/cache.rb +41 -27
- data/lib/carrierwave/uploader/callbacks.rb +0 -2
- data/lib/carrierwave/uploader/configuration.rb +54 -9
- data/lib/carrierwave/uploader/content_type_whitelist.rb +1 -1
- data/lib/carrierwave/uploader/default_url.rb +3 -5
- data/lib/carrierwave/uploader/download.rb +66 -15
- data/lib/carrierwave/uploader/extension_blacklist.rb +14 -10
- data/lib/carrierwave/uploader/extension_whitelist.rb +13 -10
- data/lib/carrierwave/uploader/file_size.rb +43 -0
- data/lib/carrierwave/uploader/mountable.rb +7 -8
- data/lib/carrierwave/uploader/processing.rb +10 -10
- data/lib/carrierwave/uploader/proxy.rb +5 -7
- data/lib/carrierwave/uploader/remove.rb +0 -2
- data/lib/carrierwave/uploader/serialization.rb +1 -3
- data/lib/carrierwave/uploader/store.rb +14 -23
- data/lib/carrierwave/uploader/url.rb +3 -5
- data/lib/carrierwave/uploader/versions.rb +82 -82
- data/lib/carrierwave/uploader.rb +11 -2
- data/lib/carrierwave/utilities/uri.rb +5 -6
- data/lib/carrierwave/utilities.rb +0 -3
- data/lib/carrierwave/validations/active_model.rb +3 -5
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +32 -10
- data/lib/generators/templates/uploader.rb +4 -8
- metadata +74 -83
- data/lib/carrierwave/locale/cs.yml +0 -11
- data/lib/carrierwave/locale/de.yml +0 -11
- data/lib/carrierwave/locale/el.yml +0 -11
- data/lib/carrierwave/locale/es.yml +0 -11
- data/lib/carrierwave/locale/fr.yml +0 -11
- data/lib/carrierwave/locale/ja.yml +0 -11
- data/lib/carrierwave/locale/nb.yml +0 -11
- data/lib/carrierwave/locale/nl.yml +0 -11
- data/lib/carrierwave/locale/pl.yml +0 -11
- data/lib/carrierwave/locale/pt-BR.yml +0 -11
- data/lib/carrierwave/locale/pt-PT.yml +0 -11
- data/lib/carrierwave/locale/ru.yml +0 -11
- data/lib/carrierwave/locale/sk.yml +0 -11
- data/lib/carrierwave/locale/tr.yml +0 -11
- data/lib/carrierwave/processing/mime_types.rb +0 -74
- data/lib/carrierwave/utilities/deprecation.rb +0 -18
data/lib/carrierwave/error.rb
CHANGED
@@ -4,8 +4,11 @@ en:
|
|
4
4
|
carrierwave_processing_error: failed to be processed
|
5
5
|
carrierwave_integrity_error: is not of an allowed file type
|
6
6
|
carrierwave_download_error: could not be downloaded
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
|
8
|
+
extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
9
|
+
content_type_whitelist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
10
|
+
content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
|
11
|
+
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
|
11
12
|
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
13
|
+
min_size_error: "File size should be greater than %{min_size}"
|
14
|
+
max_size_error: "File size should be less than %{max_size}"
|
data/lib/carrierwave/mount.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module CarrierWave
|
4
2
|
|
5
3
|
##
|
@@ -62,7 +60,7 @@ module CarrierWave
|
|
62
60
|
# will create an anonymous uploader class.
|
63
61
|
#
|
64
62
|
# Passing a block makes it possible to customize the uploader. This can be
|
65
|
-
# convenient for brevity, but if there is any
|
63
|
+
# convenient for brevity, but if there is any significant logic in the
|
66
64
|
# uploader, you should do the right thing and have it in its own file.
|
67
65
|
#
|
68
66
|
# === Added instance methods
|
@@ -92,7 +90,6 @@ module CarrierWave
|
|
92
90
|
# [image_processing_error] Returns an error object if the last file to be assigned caused a processing error
|
93
91
|
# [image_download_error] Returns an error object if the last file to be remotely assigned caused a download error
|
94
92
|
#
|
95
|
-
# [write_image_identifier] Uses the write_uploader method to set the identifier.
|
96
93
|
# [image_identifier] Reads out the identifier of the file
|
97
94
|
#
|
98
95
|
# === Parameters
|
@@ -135,56 +132,247 @@ module CarrierWave
|
|
135
132
|
# end
|
136
133
|
#
|
137
134
|
def mount_uploader(column, uploader=nil, options={}, &block)
|
138
|
-
|
139
|
-
|
140
|
-
uploader = build_uploader(uploader, &block)
|
141
|
-
uploaders[column.to_sym] = uploader
|
142
|
-
uploader_options[column.to_sym] = options
|
143
|
-
|
144
|
-
# Make sure to write over accessors directly defined on the class.
|
145
|
-
# Simply super to the included module below.
|
146
|
-
class_eval <<-RUBY, __FILE__, __LINE__+1
|
147
|
-
def #{column}; super; end
|
148
|
-
def #{column}=(new_file); super; end
|
149
|
-
RUBY
|
135
|
+
mount_base(column, uploader, options, &block)
|
150
136
|
|
151
|
-
# Mixing this in as a Module instead of class_evaling directly, so we
|
152
|
-
# can maintain the ability to super to any of these methods from within
|
153
|
-
# the class.
|
154
137
|
mod = Module.new
|
155
138
|
include mod
|
156
139
|
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
157
140
|
|
158
141
|
def #{column}
|
159
|
-
_mounter(:#{column}).
|
142
|
+
_mounter(:#{column}).uploaders[0] ||= _mounter(:#{column}).blank_uploader
|
160
143
|
end
|
161
144
|
|
162
145
|
def #{column}=(new_file)
|
163
|
-
_mounter(:#{column}).cache(new_file)
|
164
|
-
end
|
165
|
-
|
166
|
-
def #{column}?
|
167
|
-
_mounter(:#{column}).present?
|
146
|
+
_mounter(:#{column}).cache([new_file])
|
168
147
|
end
|
169
148
|
|
170
149
|
def #{column}_url(*args)
|
171
|
-
|
150
|
+
#{column}.url(*args)
|
172
151
|
end
|
173
152
|
|
174
153
|
def #{column}_cache
|
175
|
-
_mounter(:#{column}).
|
154
|
+
_mounter(:#{column}).cache_names[0]
|
176
155
|
end
|
177
156
|
|
178
157
|
def #{column}_cache=(cache_name)
|
179
|
-
_mounter(:#{column}).
|
158
|
+
_mounter(:#{column}).cache_names = [cache_name]
|
180
159
|
end
|
181
160
|
|
182
161
|
def remote_#{column}_url
|
183
|
-
_mounter(:#{column}).
|
162
|
+
[_mounter(:#{column}).remote_urls].flatten[0]
|
184
163
|
end
|
185
164
|
|
186
165
|
def remote_#{column}_url=(url)
|
187
|
-
_mounter(:#{column}).
|
166
|
+
_mounter(:#{column}).remote_urls = [url]
|
167
|
+
end
|
168
|
+
|
169
|
+
def remote_#{column}_request_header=(header)
|
170
|
+
_mounter(:#{column}).remote_request_headers = [header]
|
171
|
+
end
|
172
|
+
|
173
|
+
def write_#{column}_identifier
|
174
|
+
return if frozen?
|
175
|
+
mounter = _mounter(:#{column})
|
176
|
+
|
177
|
+
if mounter.remove?
|
178
|
+
write_uploader(mounter.serialization_column, nil)
|
179
|
+
elsif mounter.identifiers.first
|
180
|
+
write_uploader(mounter.serialization_column, mounter.identifiers.first)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def #{column}_identifier
|
185
|
+
_mounter(:#{column}).read_identifiers[0]
|
186
|
+
end
|
187
|
+
|
188
|
+
def store_previous_changes_for_#{column}
|
189
|
+
attribute_changes = ::ActiveRecord.version.to_s.to_f >= 5.1 ? saved_changes : changes
|
190
|
+
@_previous_changes_for_#{column} = attribute_changes[_mounter(:#{column}).serialization_column]
|
191
|
+
end
|
192
|
+
|
193
|
+
def remove_previously_stored_#{column}
|
194
|
+
before, after = @_previous_changes_for_#{column}
|
195
|
+
_mounter(:#{column}).remove_previous([before], [after])
|
196
|
+
end
|
197
|
+
RUBY
|
198
|
+
end
|
199
|
+
|
200
|
+
##
|
201
|
+
# Mounts the given uploader on the given array column. This means that
|
202
|
+
# assigning and reading from the array column will upload and retrieve
|
203
|
+
# multiple files. Supposing that a User class has an uploader mounted on
|
204
|
+
# images, and that images can store an array, for example it could be a
|
205
|
+
# PostgreSQL JSON column. You can assign and retrieve files like this:
|
206
|
+
#
|
207
|
+
# @user.images # => []
|
208
|
+
# @user.images = [some_file_object]
|
209
|
+
# @user.images # => [<Uploader>]
|
210
|
+
#
|
211
|
+
# @user.images[0].url # => '/some_url.png'
|
212
|
+
#
|
213
|
+
# It is also possible (but not recommended) to omit the uploader, which
|
214
|
+
# will create an anonymous uploader class.
|
215
|
+
#
|
216
|
+
# Passing a block makes it possible to customize the uploader. This can be
|
217
|
+
# convenient for brevity, but if there is any significant logic in the
|
218
|
+
# uploader, you should do the right thing and have it in its own file.
|
219
|
+
#
|
220
|
+
# === Added instance methods
|
221
|
+
#
|
222
|
+
# Supposing a class has used +mount_uploaders+ to mount an uploader on a column
|
223
|
+
# named +images+, in that case the following methods will be added to the class:
|
224
|
+
#
|
225
|
+
# [images] Returns an array of uploaders for each uploaded file
|
226
|
+
# [images=] Caches the given files
|
227
|
+
#
|
228
|
+
# [images_urls] Returns the urls to the uploaded files
|
229
|
+
#
|
230
|
+
# [images_cache] Returns a string that identifies the cache location of the files
|
231
|
+
# [images_cache=] Retrieves the files from the cache based on the given cache name
|
232
|
+
#
|
233
|
+
# [remote_image_urls] Returns previously cached remote urls
|
234
|
+
# [remote_image_urls=] Retrieve files from the given remote urls
|
235
|
+
#
|
236
|
+
# [remove_images] An attribute reader that can be used with a checkbox to mark the files for removal
|
237
|
+
# [remove_images=] An attribute writer that can be used with a checkbox to mark the files for removal
|
238
|
+
# [remove_images?] Whether the files should be removed when store_image! is called.
|
239
|
+
#
|
240
|
+
# [store_images!] Stores all files that have been assigned with +images=+
|
241
|
+
# [remove_images!] Removes the uploaded file from the filesystem.
|
242
|
+
#
|
243
|
+
# [images_integrity_error] Returns an error object if the last files to be assigned caused an integrity error
|
244
|
+
# [images_processing_error] Returns an error object if the last files to be assigned caused a processing error
|
245
|
+
# [images_download_error] Returns an error object if the last files to be remotely assigned caused a download error
|
246
|
+
#
|
247
|
+
# [image_identifiers] Reads out the identifiers of the files
|
248
|
+
#
|
249
|
+
# === Parameters
|
250
|
+
#
|
251
|
+
# [column (Symbol)] the attribute to mount this uploader on
|
252
|
+
# [uploader (CarrierWave::Uploader)] the uploader class to mount
|
253
|
+
# [options (Hash{Symbol => Object})] a set of options
|
254
|
+
# [&block (Proc)] customize anonymous uploaders
|
255
|
+
#
|
256
|
+
# === Options
|
257
|
+
#
|
258
|
+
# [:mount_on => Symbol] if the name of the column to be serialized to differs you can override it using this option
|
259
|
+
# [:ignore_integrity_errors => Boolean] if set to true, integrity errors will result in caching failing silently
|
260
|
+
# [:ignore_processing_errors => Boolean] if set to true, processing errors will result in caching failing silently
|
261
|
+
#
|
262
|
+
# === Examples
|
263
|
+
#
|
264
|
+
# Mounting uploaders on different columns.
|
265
|
+
#
|
266
|
+
# class Song
|
267
|
+
# mount_uploaders :lyrics, LyricsUploader
|
268
|
+
# mount_uploaders :alternative_lyrics, LyricsUploader
|
269
|
+
# mount_uploaders :files, SongUploader
|
270
|
+
# end
|
271
|
+
#
|
272
|
+
# This will add an anonymous uploader with only the default settings:
|
273
|
+
#
|
274
|
+
# class Data
|
275
|
+
# mount_uploaders :csv_files
|
276
|
+
# end
|
277
|
+
#
|
278
|
+
# this will add an anonymous uploader overriding the store_dir:
|
279
|
+
#
|
280
|
+
# class Product
|
281
|
+
# mount_uploaders :blueprints do
|
282
|
+
# def store_dir
|
283
|
+
# 'blueprints'
|
284
|
+
# end
|
285
|
+
# end
|
286
|
+
# end
|
287
|
+
#
|
288
|
+
def mount_uploaders(column, uploader=nil, options={}, &block)
|
289
|
+
mount_base(column, uploader, options, &block)
|
290
|
+
|
291
|
+
mod = Module.new
|
292
|
+
include mod
|
293
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
294
|
+
|
295
|
+
def #{column}
|
296
|
+
_mounter(:#{column}).uploaders
|
297
|
+
end
|
298
|
+
|
299
|
+
def #{column}=(new_files)
|
300
|
+
_mounter(:#{column}).cache(new_files)
|
301
|
+
end
|
302
|
+
|
303
|
+
def #{column}_urls(*args)
|
304
|
+
_mounter(:#{column}).urls(*args)
|
305
|
+
end
|
306
|
+
|
307
|
+
def #{column}_cache
|
308
|
+
names = _mounter(:#{column}).cache_names
|
309
|
+
names.to_json if names.present?
|
310
|
+
end
|
311
|
+
|
312
|
+
def #{column}_cache=(cache_name)
|
313
|
+
_mounter(:#{column}).cache_names = JSON.parse(cache_name) if cache_name.present?
|
314
|
+
end
|
315
|
+
|
316
|
+
def remote_#{column}_urls
|
317
|
+
_mounter(:#{column}).remote_urls
|
318
|
+
end
|
319
|
+
|
320
|
+
def remote_#{column}_urls=(urls)
|
321
|
+
_mounter(:#{column}).remote_urls = urls
|
322
|
+
end
|
323
|
+
|
324
|
+
def remote_#{column}_request_headers=(headers)
|
325
|
+
_mounter(:#{column}).remote_request_headers = headers
|
326
|
+
end
|
327
|
+
|
328
|
+
def write_#{column}_identifier
|
329
|
+
return if frozen?
|
330
|
+
mounter = _mounter(:#{column})
|
331
|
+
|
332
|
+
if mounter.remove?
|
333
|
+
write_uploader(mounter.serialization_column, nil)
|
334
|
+
elsif mounter.identifiers.any?
|
335
|
+
write_uploader(mounter.serialization_column, mounter.identifiers)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def #{column}_identifiers
|
340
|
+
_mounter(:#{column}).read_identifiers
|
341
|
+
end
|
342
|
+
|
343
|
+
def store_previous_changes_for_#{column}
|
344
|
+
attribute_changes = ::ActiveRecord.version.to_s.to_f >= 5.1 ? saved_changes : changes
|
345
|
+
@_previous_changes_for_#{column} = attribute_changes[_mounter(:#{column}).serialization_column]
|
346
|
+
end
|
347
|
+
|
348
|
+
def remove_previously_stored_#{column}
|
349
|
+
_mounter(:#{column}).remove_previous(*@_previous_changes_for_#{column})
|
350
|
+
end
|
351
|
+
RUBY
|
352
|
+
end
|
353
|
+
|
354
|
+
private
|
355
|
+
|
356
|
+
def mount_base(column, uploader=nil, options={}, &block)
|
357
|
+
include CarrierWave::Mount::Extension
|
358
|
+
|
359
|
+
uploader = build_uploader(uploader, &block)
|
360
|
+
uploaders[column.to_sym] = uploader
|
361
|
+
uploader_options[column.to_sym] = options
|
362
|
+
|
363
|
+
# Make sure to write over accessors directly defined on the class.
|
364
|
+
# Simply super to the included module below.
|
365
|
+
class_eval <<-RUBY, __FILE__, __LINE__+1
|
366
|
+
def #{column}; super; end
|
367
|
+
def #{column}=(new_file); super; end
|
368
|
+
RUBY
|
369
|
+
|
370
|
+
mod = Module.new
|
371
|
+
include mod
|
372
|
+
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
373
|
+
|
374
|
+
def #{column}?
|
375
|
+
_mounter(:#{column}).present?
|
188
376
|
end
|
189
377
|
|
190
378
|
def remove_#{column}
|
@@ -219,47 +407,17 @@ module CarrierWave
|
|
219
407
|
_mounter(:#{column}).download_error
|
220
408
|
end
|
221
409
|
|
222
|
-
def write_#{column}_identifier
|
223
|
-
_mounter(:#{column}).write_identifier
|
224
|
-
end
|
225
|
-
|
226
|
-
def #{column}_identifier
|
227
|
-
_mounter(:#{column}).identifier
|
228
|
-
end
|
229
|
-
|
230
|
-
def store_previous_model_for_#{column}
|
231
|
-
serialization_column = _mounter(:#{column}).serialization_column
|
232
|
-
|
233
|
-
if #{column}.remove_previously_stored_files_after_update && send(:"\#{serialization_column}_changed?")
|
234
|
-
@previous_model_for_#{column} ||= self.find_previous_model_for_#{column}
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
def find_previous_model_for_#{column}
|
239
|
-
self.class.find(to_key.first)
|
240
|
-
end
|
241
|
-
|
242
|
-
def remove_previously_stored_#{column}
|
243
|
-
if @previous_model_for_#{column} && @previous_model_for_#{column}.#{column}.path != #{column}.path
|
244
|
-
@previous_model_for_#{column}.#{column}.remove!
|
245
|
-
@previous_model_for_#{column} = nil
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
410
|
def mark_remove_#{column}_false
|
250
411
|
_mounter(:#{column}).remove = false
|
251
412
|
end
|
252
|
-
|
253
413
|
RUBY
|
254
414
|
end
|
255
415
|
|
256
|
-
private
|
257
|
-
|
258
416
|
def build_uploader(uploader, &block)
|
259
417
|
return uploader if uploader && !block_given?
|
260
418
|
|
261
419
|
uploader = Class.new(uploader || CarrierWave::Uploader::Base)
|
262
|
-
const_set("Uploader#{uploader.object_id}".
|
420
|
+
const_set("Uploader#{uploader.object_id}".tr('-', '_'), uploader)
|
263
421
|
|
264
422
|
if block_given?
|
265
423
|
uploader.class_eval(&block)
|
@@ -292,120 +450,5 @@ module CarrierWave
|
|
292
450
|
|
293
451
|
end # Extension
|
294
452
|
|
295
|
-
# this is an internal class, used by CarrierWave::Mount so that
|
296
|
-
# we don't pollute the model with a lot of methods.
|
297
|
-
class Mounter #:nodoc:
|
298
|
-
attr_reader :column, :record, :remote_url, :integrity_error, :processing_error, :download_error
|
299
|
-
attr_accessor :remove
|
300
|
-
|
301
|
-
def initialize(record, column, options={})
|
302
|
-
@record = record
|
303
|
-
@column = column
|
304
|
-
@options = record.class.uploader_options[column]
|
305
|
-
end
|
306
|
-
|
307
|
-
def write_identifier
|
308
|
-
return if record.frozen?
|
309
|
-
|
310
|
-
if remove?
|
311
|
-
record.write_uploader(serialization_column, nil)
|
312
|
-
elsif uploader.identifier.present?
|
313
|
-
record.write_uploader(serialization_column, uploader.identifier)
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
def identifier
|
318
|
-
record.read_uploader(serialization_column)
|
319
|
-
end
|
320
|
-
|
321
|
-
def uploader
|
322
|
-
@uploader ||= record.class.uploaders[column].new(record, column)
|
323
|
-
@uploader.retrieve_from_store!(identifier) if @uploader.blank? && identifier.present?
|
324
|
-
|
325
|
-
@uploader
|
326
|
-
end
|
327
|
-
|
328
|
-
def cache(new_file)
|
329
|
-
uploader.cache!(new_file)
|
330
|
-
@integrity_error = nil
|
331
|
-
@processing_error = nil
|
332
|
-
rescue CarrierWave::IntegrityError => e
|
333
|
-
@integrity_error = e
|
334
|
-
raise e unless option(:ignore_integrity_errors)
|
335
|
-
rescue CarrierWave::ProcessingError => e
|
336
|
-
@processing_error = e
|
337
|
-
raise e unless option(:ignore_processing_errors)
|
338
|
-
end
|
339
|
-
|
340
|
-
def cache_name
|
341
|
-
uploader.cache_name
|
342
|
-
end
|
343
|
-
|
344
|
-
def cache_name=(cache_name)
|
345
|
-
uploader.retrieve_from_cache!(cache_name) unless uploader.cached?
|
346
|
-
rescue CarrierWave::InvalidParameter
|
347
|
-
end
|
348
|
-
|
349
|
-
def remote_url=(url)
|
350
|
-
return if url.blank?
|
351
|
-
|
352
|
-
@remote_url = url
|
353
|
-
@download_error = nil
|
354
|
-
@integrity_error = nil
|
355
|
-
|
356
|
-
uploader.download!(url)
|
357
|
-
|
358
|
-
rescue CarrierWave::DownloadError => e
|
359
|
-
@download_error = e
|
360
|
-
raise e unless option(:ignore_download_errors)
|
361
|
-
rescue CarrierWave::ProcessingError => e
|
362
|
-
@processing_error = e
|
363
|
-
raise e unless option(:ignore_processing_errors)
|
364
|
-
rescue CarrierWave::IntegrityError => e
|
365
|
-
@integrity_error = e
|
366
|
-
raise e unless option(:ignore_integrity_errors)
|
367
|
-
end
|
368
|
-
|
369
|
-
def store!
|
370
|
-
return if uploader.blank?
|
371
|
-
|
372
|
-
if remove?
|
373
|
-
uploader.remove!
|
374
|
-
else
|
375
|
-
uploader.store!
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
|
-
def url(*args)
|
380
|
-
uploader.url(*args)
|
381
|
-
end
|
382
|
-
|
383
|
-
def blank?
|
384
|
-
uploader.blank?
|
385
|
-
end
|
386
|
-
|
387
|
-
def remove?
|
388
|
-
remove.present? && remove !~ /\A0|false$\z/
|
389
|
-
end
|
390
|
-
|
391
|
-
def remove!
|
392
|
-
uploader.remove!
|
393
|
-
end
|
394
|
-
|
395
|
-
def serialization_column
|
396
|
-
option(:mount_on) || column
|
397
|
-
end
|
398
|
-
|
399
|
-
attr_accessor :uploader_options
|
400
|
-
|
401
|
-
private
|
402
|
-
|
403
|
-
def option(name)
|
404
|
-
self.uploader_options ||= {}
|
405
|
-
self.uploader_options[name] ||= record.class.uploader_option(column, name)
|
406
|
-
end
|
407
|
-
|
408
|
-
end # Mounter
|
409
|
-
|
410
453
|
end # Mount
|
411
454
|
end # CarrierWave
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
|
3
|
+
# this is an internal class, used by CarrierWave::Mount so that
|
4
|
+
# we don't pollute the model with a lot of methods.
|
5
|
+
class Mounter #:nodoc:
|
6
|
+
attr_reader :column, :record, :remote_urls, :integrity_error,
|
7
|
+
:processing_error, :download_error
|
8
|
+
attr_accessor :remove, :remote_request_headers
|
9
|
+
|
10
|
+
def initialize(record, column, options={})
|
11
|
+
@record = record
|
12
|
+
@column = column
|
13
|
+
@options = record.class.uploader_options[column]
|
14
|
+
end
|
15
|
+
|
16
|
+
def uploader_class
|
17
|
+
record.class.uploaders[column]
|
18
|
+
end
|
19
|
+
|
20
|
+
def blank_uploader
|
21
|
+
uploader_class.new(record, column)
|
22
|
+
end
|
23
|
+
|
24
|
+
def identifiers
|
25
|
+
uploaders.map(&:identifier)
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_identifiers
|
29
|
+
[record.read_uploader(serialization_column)].flatten.reject(&:blank?)
|
30
|
+
end
|
31
|
+
|
32
|
+
def uploaders
|
33
|
+
@uploaders ||= read_identifiers.map do |identifier|
|
34
|
+
uploader = blank_uploader
|
35
|
+
uploader.retrieve_from_store!(identifier) if identifier.present?
|
36
|
+
uploader
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def cache(new_files)
|
41
|
+
return if not new_files or new_files == ""
|
42
|
+
@uploaders = new_files.map do |new_file|
|
43
|
+
uploader = blank_uploader
|
44
|
+
uploader.cache!(new_file)
|
45
|
+
uploader
|
46
|
+
end
|
47
|
+
|
48
|
+
@integrity_error = nil
|
49
|
+
@processing_error = nil
|
50
|
+
rescue CarrierWave::IntegrityError => e
|
51
|
+
@integrity_error = e
|
52
|
+
raise e unless option(:ignore_integrity_errors)
|
53
|
+
rescue CarrierWave::ProcessingError => e
|
54
|
+
@processing_error = e
|
55
|
+
raise e unless option(:ignore_processing_errors)
|
56
|
+
end
|
57
|
+
|
58
|
+
def cache_names
|
59
|
+
uploaders.map(&:cache_name).compact
|
60
|
+
end
|
61
|
+
|
62
|
+
def cache_names=(cache_names)
|
63
|
+
return if not cache_names or cache_names == "" or uploaders.any?(&:cached?)
|
64
|
+
@uploaders = cache_names.map do |cache_name|
|
65
|
+
uploader = blank_uploader
|
66
|
+
uploader.retrieve_from_cache!(cache_name)
|
67
|
+
uploader
|
68
|
+
end
|
69
|
+
rescue CarrierWave::InvalidParameter
|
70
|
+
end
|
71
|
+
|
72
|
+
def remote_urls=(urls)
|
73
|
+
return if not urls or urls == "" or urls.all?(&:blank?)
|
74
|
+
|
75
|
+
@remote_urls = urls
|
76
|
+
@download_error = nil
|
77
|
+
@integrity_error = nil
|
78
|
+
|
79
|
+
@uploaders = urls.zip(remote_request_headers || []).map do |url, header|
|
80
|
+
uploader = blank_uploader
|
81
|
+
uploader.download!(url, header || {})
|
82
|
+
uploader
|
83
|
+
end
|
84
|
+
|
85
|
+
rescue CarrierWave::DownloadError => e
|
86
|
+
@download_error = e
|
87
|
+
raise e unless option(:ignore_download_errors)
|
88
|
+
rescue CarrierWave::ProcessingError => e
|
89
|
+
@processing_error = e
|
90
|
+
raise e unless option(:ignore_processing_errors)
|
91
|
+
rescue CarrierWave::IntegrityError => e
|
92
|
+
@integrity_error = e
|
93
|
+
raise e unless option(:ignore_integrity_errors)
|
94
|
+
end
|
95
|
+
|
96
|
+
def store!
|
97
|
+
if remove?
|
98
|
+
remove!
|
99
|
+
else
|
100
|
+
uploaders.reject(&:blank?).each(&:store!)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def urls(*args)
|
105
|
+
uploaders.map { |u| u.url(*args) }
|
106
|
+
end
|
107
|
+
|
108
|
+
def blank?
|
109
|
+
uploaders.none?(&:present?)
|
110
|
+
end
|
111
|
+
|
112
|
+
def remove?
|
113
|
+
remove.present? && (remove == true || remove !~ /\A0|false$\z/)
|
114
|
+
end
|
115
|
+
|
116
|
+
def remove!
|
117
|
+
uploaders.reject(&:blank?).each(&:remove!)
|
118
|
+
@uploaders = []
|
119
|
+
end
|
120
|
+
|
121
|
+
def serialization_column
|
122
|
+
option(:mount_on) || column
|
123
|
+
end
|
124
|
+
|
125
|
+
def remove_previous(before=nil, after=nil)
|
126
|
+
after ||= []
|
127
|
+
return unless before
|
128
|
+
|
129
|
+
# both 'before' and 'after' can be string when 'mount_on' option is set
|
130
|
+
before = before.reject(&:blank?).map do |value|
|
131
|
+
if value.is_a?(String)
|
132
|
+
uploader = blank_uploader
|
133
|
+
uploader.retrieve_from_store!(value)
|
134
|
+
uploader
|
135
|
+
else
|
136
|
+
value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
after_paths = after.reject(&:blank?).map do |value|
|
140
|
+
if value.is_a?(String)
|
141
|
+
uploader = blank_uploader
|
142
|
+
uploader.retrieve_from_store!(value)
|
143
|
+
uploader
|
144
|
+
else
|
145
|
+
value
|
146
|
+
end.path
|
147
|
+
end
|
148
|
+
before.each do |uploader|
|
149
|
+
if uploader.remove_previously_stored_files_after_update and not after_paths.include?(uploader.path)
|
150
|
+
uploader.remove!
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
attr_accessor :uploader_options
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
def option(name)
|
160
|
+
self.uploader_options ||= {}
|
161
|
+
self.uploader_options[name] ||= record.class.uploader_option(column, name)
|
162
|
+
end
|
163
|
+
|
164
|
+
end # Mounter
|
165
|
+
end # CarrierWave
|