carrierwave 2.2.6 → 3.1.0
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.
- checksums.yaml +4 -4
- data/README.md +180 -62
- data/lib/carrierwave/compatibility/paperclip.rb +4 -2
- data/lib/carrierwave/downloader/base.rb +20 -12
- data/lib/carrierwave/downloader/remote_file.rb +13 -10
- data/lib/carrierwave/locale/en.yml +5 -3
- data/lib/carrierwave/mount.rb +36 -50
- data/lib/carrierwave/mounter.rb +118 -50
- data/lib/carrierwave/orm/activerecord.rb +21 -62
- data/lib/carrierwave/processing/mini_magick.rb +45 -14
- data/lib/carrierwave/processing/rmagick.rb +47 -20
- data/lib/carrierwave/processing/vips.rb +43 -12
- data/lib/carrierwave/sanitized_file.rb +58 -77
- data/lib/carrierwave/storage/abstract.rb +5 -5
- data/lib/carrierwave/storage/file.rb +6 -5
- data/lib/carrierwave/storage/fog.rb +86 -65
- data/lib/carrierwave/test/matchers.rb +11 -7
- data/lib/carrierwave/uploader/cache.rb +19 -11
- data/lib/carrierwave/uploader/callbacks.rb +1 -1
- data/lib/carrierwave/uploader/configuration.rb +18 -8
- data/lib/carrierwave/uploader/{content_type_whitelist.rb → content_type_allowlist.rb} +17 -15
- data/lib/carrierwave/uploader/{content_type_blacklist.rb → content_type_denylist.rb} +20 -15
- data/lib/carrierwave/uploader/dimension.rb +66 -0
- data/lib/carrierwave/uploader/{extension_whitelist.rb → extension_allowlist.rb} +17 -15
- data/lib/carrierwave/uploader/{extension_blacklist.rb → extension_denylist.rb} +19 -14
- data/lib/carrierwave/uploader/file_size.rb +2 -2
- data/lib/carrierwave/uploader/processing.rb +34 -6
- data/lib/carrierwave/uploader/proxy.rb +16 -3
- data/lib/carrierwave/uploader/store.rb +70 -6
- data/lib/carrierwave/uploader/url.rb +1 -1
- data/lib/carrierwave/uploader/versions.rb +158 -138
- data/lib/carrierwave/uploader.rb +10 -8
- data/lib/carrierwave/utilities/file_name.rb +47 -0
- data/lib/carrierwave/utilities/uri.rb +14 -11
- data/lib/carrierwave/utilities.rb +1 -0
- data/lib/carrierwave/validations/active_model.rb +4 -6
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +18 -17
- data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +1 -1
- data/lib/generators/uploader_generator.rb +3 -3
- metadata +33 -59
@@ -22,7 +22,7 @@ module CarrierWave
|
|
22
22
|
# end
|
23
23
|
#
|
24
24
|
# Or create your own helpers with the powerful manipulate! method. Check
|
25
|
-
# out the RMagick docs at
|
25
|
+
# out the RMagick docs at https://rmagick.github.io/ for more
|
26
26
|
# info
|
27
27
|
#
|
28
28
|
# class MyUploader < CarrierWave::Uploader::Base
|
@@ -62,10 +62,12 @@ module CarrierWave
|
|
62
62
|
begin
|
63
63
|
require "rmagick"
|
64
64
|
rescue LoadError
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
begin
|
66
|
+
require "RMagick"
|
67
|
+
rescue LoadError => e
|
68
|
+
e.message << " (You may need to install the rmagick gem)"
|
69
|
+
raise e
|
70
|
+
end
|
69
71
|
end
|
70
72
|
|
71
73
|
prepend Module.new {
|
@@ -100,16 +102,20 @@ module CarrierWave
|
|
100
102
|
def resize_to_geometry_string(geometry_string)
|
101
103
|
process :resize_to_geometry_string => [geometry_string]
|
102
104
|
end
|
105
|
+
|
106
|
+
def crop(left, top, width, height)
|
107
|
+
process :crop => [left, top, width, height]
|
108
|
+
end
|
103
109
|
end
|
104
110
|
|
105
111
|
##
|
106
112
|
# Changes the image encoding format to the given format
|
107
113
|
#
|
108
|
-
# See even
|
114
|
+
# See even https://rmagick.github.io/magick.html#formats
|
109
115
|
#
|
110
116
|
# === Parameters
|
111
117
|
#
|
112
|
-
# [format (#to_s)] an
|
118
|
+
# [format (#to_s)] an abbreviation of the format
|
113
119
|
#
|
114
120
|
# === Yields
|
115
121
|
#
|
@@ -159,7 +165,7 @@ module CarrierWave
|
|
159
165
|
# image may be shorter or narrower than specified in the smaller dimension
|
160
166
|
# but will not be larger than the specified values."
|
161
167
|
#
|
162
|
-
# See even
|
168
|
+
# See even https://rmagick.github.io/image3.html#resize_to_fit
|
163
169
|
#
|
164
170
|
# === Parameters
|
165
171
|
#
|
@@ -185,7 +191,7 @@ module CarrierWave
|
|
185
191
|
# specified dimensions while retaining the aspect ratio of the original
|
186
192
|
# image. If necessary, crop the image in the larger dimension."
|
187
193
|
#
|
188
|
-
# See even
|
194
|
+
# See even https://rmagick.github.io/image3.html#resize_to_fill
|
189
195
|
#
|
190
196
|
# === Parameters
|
191
197
|
#
|
@@ -228,13 +234,7 @@ module CarrierWave
|
|
228
234
|
height = dimension_from height
|
229
235
|
manipulate! do |img|
|
230
236
|
img.resize_to_fit!(width, height)
|
231
|
-
|
232
|
-
if background == :transparent
|
233
|
-
filled = new_img.matte_floodfill(1, 1)
|
234
|
-
else
|
235
|
-
filled = new_img.color_floodfill(1, 1, ::Magick::Pixel.from_color(background))
|
236
|
-
end
|
237
|
-
destroy_image(new_img)
|
237
|
+
filled = ::Magick::Image.new(width, height) { |image| image.background_color = background == :transparent ? 'rgba(255,255,255,0)' : background.to_s }
|
238
238
|
filled.composite!(img, gravity, ::Magick::OverCompositeOp)
|
239
239
|
destroy_image(img)
|
240
240
|
filled = yield(filled) if block_given?
|
@@ -264,6 +264,33 @@ module CarrierWave
|
|
264
264
|
end
|
265
265
|
end
|
266
266
|
|
267
|
+
##
|
268
|
+
# Crop the image to the contents of a box positioned at [left] and [top], with the dimensions given
|
269
|
+
# by [width] and [height]. The original image bottom/right edge is preserved if the cropping box falls
|
270
|
+
# outside the image bounds.
|
271
|
+
#
|
272
|
+
# === Parameters
|
273
|
+
#
|
274
|
+
# [left (integer)] left edge of area to extract
|
275
|
+
# [top (integer)] top edge of area to extract
|
276
|
+
# [width (Integer)] width of area to extract
|
277
|
+
# [height (Integer)] height of area to extract
|
278
|
+
#
|
279
|
+
# === Yields
|
280
|
+
#
|
281
|
+
# [Magick::Image] additional manipulations to perform
|
282
|
+
#
|
283
|
+
def crop(left, top, width, height, combine_options: {})
|
284
|
+
width = dimension_from width
|
285
|
+
height = dimension_from height
|
286
|
+
|
287
|
+
manipulate! do |img|
|
288
|
+
img.crop!(left, top, width, height)
|
289
|
+
img = yield(img) if block_given?
|
290
|
+
img
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
267
294
|
##
|
268
295
|
# Returns the width of the image.
|
269
296
|
#
|
@@ -363,15 +390,15 @@ module CarrierWave
|
|
363
390
|
if options[:format] || @format
|
364
391
|
frames.write("#{options[:format] || @format}:#{current_path}", &write_block)
|
365
392
|
move_to = current_path.chomp(File.extname(current_path)) + ".#{options[:format] || @format}"
|
366
|
-
file.content_type = ::
|
393
|
+
file.content_type = Marcel::Magic.by_path(move_to).try(:type)
|
367
394
|
file.move_to(move_to, permissions, directory_permissions)
|
368
395
|
else
|
369
396
|
frames.write(current_path, &write_block)
|
370
397
|
end
|
371
398
|
|
372
399
|
destroy_image(frames)
|
373
|
-
rescue ::Magick::ImageMagickError
|
374
|
-
raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.
|
400
|
+
rescue ::Magick::ImageMagickError
|
401
|
+
raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.processing_error")
|
375
402
|
end
|
376
403
|
|
377
404
|
private
|
@@ -381,7 +408,7 @@ module CarrierWave
|
|
381
408
|
proc do |img|
|
382
409
|
options.each do |k, v|
|
383
410
|
if v.is_a?(String) && (matches = v.match(/^["'](.+)["']/))
|
384
|
-
|
411
|
+
CarrierWave.deprecator.warn "Passing quoted strings like #{v} to #manipulate! is deprecated, pass them without quoting."
|
385
412
|
v = matches[1]
|
386
413
|
end
|
387
414
|
img.public_send(:"#{k}=", v)
|
@@ -78,6 +78,10 @@ module CarrierWave
|
|
78
78
|
def resize_and_pad(width, height, background=nil, gravity='centre', alpha=nil)
|
79
79
|
process :resize_and_pad => [width, height, background, gravity, alpha]
|
80
80
|
end
|
81
|
+
|
82
|
+
def crop(left, top, width, height)
|
83
|
+
process :crop => [left, top, width, height]
|
84
|
+
end
|
81
85
|
end
|
82
86
|
|
83
87
|
##
|
@@ -208,6 +212,33 @@ module CarrierWave
|
|
208
212
|
end
|
209
213
|
end
|
210
214
|
|
215
|
+
##
|
216
|
+
# Crop the image to the contents of a box positioned at [left] and [top], with the dimensions given
|
217
|
+
# by [width] and [height]. The original image bottom/right edge is preserved if the cropping box falls
|
218
|
+
# outside the image bounds.
|
219
|
+
#
|
220
|
+
# === Parameters
|
221
|
+
#
|
222
|
+
# [left (integer)] left edge of area to extract
|
223
|
+
# [top (integer)] top edge of area to extract
|
224
|
+
# [width (Integer)] width of area to extract
|
225
|
+
# [height (Integer)] height of area to extract
|
226
|
+
#
|
227
|
+
# === Yields
|
228
|
+
#
|
229
|
+
# [Vips::Image] additional manipulations to perform
|
230
|
+
#
|
231
|
+
def crop(left, top, width, height, combine_options: {})
|
232
|
+
width, height = resolve_dimensions(width, height)
|
233
|
+
width = vips_image.width - left if width + left > vips_image.width
|
234
|
+
height = vips_image.height - top if height + top > vips_image.height
|
235
|
+
|
236
|
+
vips! do |builder|
|
237
|
+
builder.crop(left, top, width, height)
|
238
|
+
.apply(combine_options)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
211
242
|
##
|
212
243
|
# Returns the width of the image in pixels.
|
213
244
|
#
|
@@ -259,26 +290,26 @@ module CarrierWave
|
|
259
290
|
|
260
291
|
if File.extname(result.path) != File.extname(current_path)
|
261
292
|
move_to = current_path.chomp(File.extname(current_path)) + File.extname(result.path)
|
262
|
-
file.content_type = ::
|
293
|
+
file.content_type = Marcel::Magic.by_path(move_to).try(:type)
|
263
294
|
file.move_to(move_to, permissions, directory_permissions)
|
264
295
|
end
|
265
|
-
rescue ::Vips::Error
|
266
|
-
message = I18n.translate(:"errors.messages.
|
296
|
+
rescue ::Vips::Error
|
297
|
+
message = I18n.translate(:"errors.messages.processing_error")
|
267
298
|
raise CarrierWave::ProcessingError, message
|
268
299
|
end
|
269
300
|
|
270
|
-
|
301
|
+
private
|
271
302
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
end
|
303
|
+
def resolve_dimensions(*dimensions)
|
304
|
+
dimensions.map do |value|
|
305
|
+
next value unless value.instance_of?(Proc)
|
306
|
+
value.arity >= 1 ? value.call(self) : value.call
|
277
307
|
end
|
308
|
+
end
|
278
309
|
|
279
|
-
|
280
|
-
|
281
|
-
|
310
|
+
def vips_image
|
311
|
+
::Vips::Image.new_from_buffer(read, "")
|
312
|
+
end
|
282
313
|
|
283
314
|
end # Vips
|
284
315
|
end # CarrierWave
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'active_support/core_ext/string/multibyte'
|
3
|
-
require 'mini_mime'
|
4
3
|
require 'marcel'
|
5
4
|
|
6
5
|
module CarrierWave
|
@@ -14,6 +13,7 @@ module CarrierWave
|
|
14
13
|
# It's probably needlessly comprehensive and complex. Help is appreciated.
|
15
14
|
#
|
16
15
|
class SanitizedFile
|
16
|
+
include CarrierWave::Utilities::FileName
|
17
17
|
|
18
18
|
attr_reader :file
|
19
19
|
|
@@ -27,7 +27,7 @@ module CarrierWave
|
|
27
27
|
|
28
28
|
def initialize(file)
|
29
29
|
self.file = file
|
30
|
-
@content = nil
|
30
|
+
@content = @content_type = nil
|
31
31
|
end
|
32
32
|
|
33
33
|
##
|
@@ -39,7 +39,7 @@ module CarrierWave
|
|
39
39
|
#
|
40
40
|
def original_filename
|
41
41
|
return @original_filename if @original_filename
|
42
|
-
if @file
|
42
|
+
if @file && @file.respond_to?(:original_filename)
|
43
43
|
@file.original_filename
|
44
44
|
elsif path
|
45
45
|
File.basename(path)
|
@@ -59,29 +59,6 @@ module CarrierWave
|
|
59
59
|
|
60
60
|
alias_method :identifier, :filename
|
61
61
|
|
62
|
-
##
|
63
|
-
# Returns the part of the filename before the extension. So if a file is called 'test.jpeg'
|
64
|
-
# this would return 'test'
|
65
|
-
#
|
66
|
-
# === Returns
|
67
|
-
#
|
68
|
-
# [String] the first part of the filename
|
69
|
-
#
|
70
|
-
def basename
|
71
|
-
split_extension(filename)[0] if filename
|
72
|
-
end
|
73
|
-
|
74
|
-
##
|
75
|
-
# Returns the file extension
|
76
|
-
#
|
77
|
-
# === Returns
|
78
|
-
#
|
79
|
-
# [String] the extension
|
80
|
-
#
|
81
|
-
def extension
|
82
|
-
split_extension(filename)[1] if filename
|
83
|
-
end
|
84
|
-
|
85
62
|
##
|
86
63
|
# Returns the file's size.
|
87
64
|
#
|
@@ -132,7 +109,7 @@ module CarrierWave
|
|
132
109
|
# [Boolean] whether the file is valid and has a non-zero size
|
133
110
|
#
|
134
111
|
def empty?
|
135
|
-
@file.nil? || self.size.nil? || (self.size.zero? && !
|
112
|
+
@file.nil? || self.size.nil? || (self.size.zero? && !self.exists?)
|
136
113
|
end
|
137
114
|
|
138
115
|
##
|
@@ -151,15 +128,21 @@ module CarrierWave
|
|
151
128
|
#
|
152
129
|
# [String] contents of the file
|
153
130
|
#
|
154
|
-
def read
|
131
|
+
def read(*args)
|
155
132
|
if @content
|
156
|
-
|
133
|
+
if args.empty?
|
134
|
+
@content
|
135
|
+
else
|
136
|
+
length, outbuf = args
|
137
|
+
raise ArgumentError, "outbuf argument not supported since the content is already loaded" if outbuf
|
138
|
+
@content[0, length]
|
139
|
+
end
|
157
140
|
elsif is_path?
|
158
|
-
File.open(@file, "rb") {|file| file.read}
|
141
|
+
File.open(@file, "rb") {|file| file.read(*args)}
|
159
142
|
else
|
160
143
|
@file.try(:rewind)
|
161
|
-
@content = @file.read
|
162
|
-
@file.try(:close) unless @file.try(:closed?)
|
144
|
+
@content = @file.read(*args)
|
145
|
+
@file.try(:close) unless @file.class.ancestors.include?(::StringIO) || @file.try(:closed?)
|
163
146
|
@content
|
164
147
|
end
|
165
148
|
end
|
@@ -180,13 +163,10 @@ module CarrierWave
|
|
180
163
|
mkdir!(new_path, directory_permissions)
|
181
164
|
move!(new_path)
|
182
165
|
chmod!(new_path, permissions)
|
183
|
-
|
184
|
-
self.file = {:tempfile => new_path, :filename => original_filename, :content_type => @content_type}
|
185
|
-
else
|
186
|
-
self.file = {:tempfile => new_path, :content_type => @content_type}
|
187
|
-
end
|
166
|
+
self.file = {tempfile: new_path, filename: keep_filename ? original_filename : nil, content_type: declared_content_type}
|
188
167
|
self
|
189
168
|
end
|
169
|
+
|
190
170
|
##
|
191
171
|
# Helper to move file to new path.
|
192
172
|
#
|
@@ -218,7 +198,7 @@ module CarrierWave
|
|
218
198
|
mkdir!(new_path, directory_permissions)
|
219
199
|
copy!(new_path)
|
220
200
|
chmod!(new_path, permissions)
|
221
|
-
self.class.new({:
|
201
|
+
self.class.new({tempfile: new_path, content_type: declared_content_type})
|
222
202
|
end
|
223
203
|
|
224
204
|
##
|
@@ -260,9 +240,10 @@ module CarrierWave
|
|
260
240
|
#
|
261
241
|
def content_type
|
262
242
|
@content_type ||=
|
263
|
-
|
264
|
-
|
265
|
-
|
243
|
+
identified_content_type ||
|
244
|
+
declared_content_type ||
|
245
|
+
guessed_safe_content_type ||
|
246
|
+
Marcel::MimeType::BINARY
|
266
247
|
end
|
267
248
|
|
268
249
|
##
|
@@ -293,11 +274,11 @@ module CarrierWave
|
|
293
274
|
if file.is_a?(Hash)
|
294
275
|
@file = file["tempfile"] || file[:tempfile]
|
295
276
|
@original_filename = file["filename"] || file[:filename]
|
296
|
-
@
|
277
|
+
@declared_content_type = file["content_type"] || file[:content_type] || file["type"] || file[:type]
|
297
278
|
else
|
298
279
|
@file = file
|
299
280
|
@original_filename = nil
|
300
|
-
@
|
281
|
+
@declared_content_type = nil
|
301
282
|
end
|
302
283
|
end
|
303
284
|
|
@@ -314,57 +295,57 @@ module CarrierWave
|
|
314
295
|
|
315
296
|
# Sanitize the filename, to prevent hacking
|
316
297
|
def sanitize(name)
|
298
|
+
name = name.scrub
|
317
299
|
name = name.tr("\\", "/") # work-around for IE
|
318
300
|
name = File.basename(name)
|
319
|
-
name = name.gsub(sanitize_regexp,"_")
|
301
|
+
name = name.gsub(sanitize_regexp, "_")
|
320
302
|
name = "_#{name}" if name =~ /\A\.+\z/
|
321
303
|
name = "unnamed" if name.size.zero?
|
322
|
-
|
304
|
+
name.mb_chars.to_s
|
323
305
|
end
|
324
306
|
|
325
|
-
def
|
326
|
-
|
327
|
-
|
328
|
-
|
307
|
+
def declared_content_type
|
308
|
+
@declared_content_type ||
|
309
|
+
if @file.respond_to?(:content_type) && @file.content_type
|
310
|
+
Marcel::MimeType.for(declared_type: @file.content_type.to_s.chomp)
|
311
|
+
end
|
329
312
|
end
|
330
313
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
Marcel::Magic.by_magic(file).try(:type)
|
335
|
-
end
|
314
|
+
# Guess content type from its file extension. Limit what to be returned to prevent spoofing.
|
315
|
+
def guessed_safe_content_type
|
316
|
+
return unless path
|
336
317
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
318
|
+
type = Marcel::Magic.by_path(original_filename).to_s
|
319
|
+
type if type.start_with?('text/') || type.start_with?('application/json')
|
320
|
+
end
|
321
|
+
|
322
|
+
def identified_content_type
|
323
|
+
with_io do |io|
|
324
|
+
mimetype_by_magic = Marcel::Magic.by_magic(io)
|
325
|
+
mimetype_by_path = Marcel::Magic.by_path(path)
|
341
326
|
|
342
|
-
|
327
|
+
return nil if mimetype_by_magic.nil?
|
328
|
+
|
329
|
+
if mimetype_by_path&.child_of?(mimetype_by_magic.type)
|
330
|
+
mimetype_by_path.type
|
331
|
+
else
|
332
|
+
mimetype_by_magic.type
|
333
|
+
end
|
343
334
|
end
|
344
335
|
rescue Errno::ENOENT
|
345
336
|
nil
|
346
337
|
end
|
347
338
|
|
348
|
-
def
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
def split_extension(filename)
|
355
|
-
# regular expressions to try for identifying extensions
|
356
|
-
extension_matchers = [
|
357
|
-
/\A(.+)\.(tar\.([glx]?z|bz2))\z/, # matches "something.tar.gz"
|
358
|
-
/\A(.+)\.([^\.]+)\z/ # matches "something.jpg"
|
359
|
-
]
|
360
|
-
|
361
|
-
extension_matchers.each do |regexp|
|
362
|
-
if filename =~ regexp
|
363
|
-
return $1, $2
|
339
|
+
def with_io(&block)
|
340
|
+
if file.is_a?(IO)
|
341
|
+
begin
|
342
|
+
yield file
|
343
|
+
ensure
|
344
|
+
file.try(:rewind)
|
364
345
|
end
|
346
|
+
elsif path
|
347
|
+
File.open(path, &block)
|
365
348
|
end
|
366
|
-
return filename, "" # In case we weren't able to split the extension
|
367
349
|
end
|
368
|
-
|
369
350
|
end # SanitizedFile
|
370
351
|
end # CarrierWave
|
@@ -14,7 +14,7 @@ module CarrierWave
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def identifier
|
17
|
-
uploader.
|
17
|
+
uploader.deduplicated_filename
|
18
18
|
end
|
19
19
|
|
20
20
|
def store!(file)
|
@@ -24,19 +24,19 @@ module CarrierWave
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def cache!(new_file)
|
27
|
-
raise NotImplementedError
|
27
|
+
raise NotImplementedError, "Need to implement #cache! if you want to use #{self.class.name} as a cache storage."
|
28
28
|
end
|
29
29
|
|
30
30
|
def retrieve_from_cache!(identifier)
|
31
|
-
raise NotImplementedError
|
31
|
+
raise NotImplementedError, "Need to implement #retrieve_from_cache! if you want to use #{self.class.name} as a cache storage."
|
32
32
|
end
|
33
33
|
|
34
34
|
def delete_dir!(path)
|
35
|
-
raise NotImplementedError
|
35
|
+
raise NotImplementedError, "Need to implement #delete_dir! if you want to use #{self.class.name} as a cache storage."
|
36
36
|
end
|
37
37
|
|
38
38
|
def clean_cache!(seconds)
|
39
|
-
raise NotImplementedError
|
39
|
+
raise NotImplementedError, "Need to implement #clean_cache! if you want to use #{self.class.name} as a cache storage."
|
40
40
|
end
|
41
41
|
end # Abstract
|
42
42
|
end # Storage
|
@@ -17,7 +17,7 @@ module CarrierWave
|
|
17
17
|
#
|
18
18
|
# By default, store!() uses copy_to(), which operates by copying the file
|
19
19
|
# from the cache to the store, then deleting the file from the cache.
|
20
|
-
# If move_to_store() is
|
20
|
+
# If move_to_store() is overridden to return true, then store!() uses move_to(),
|
21
21
|
# which simply moves the file from cache to store. Useful for large files.
|
22
22
|
#
|
23
23
|
# === Parameters
|
@@ -109,10 +109,11 @@ module CarrierWave
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def clean_cache!(seconds)
|
112
|
-
Dir.glob(::File.expand_path(::File.join(uploader.cache_dir, '*'),
|
113
|
-
# generate_cache_id returns key
|
114
|
-
|
115
|
-
|
112
|
+
Dir.glob(::File.expand_path(::File.join(uploader.cache_dir, '*'), uploader.root)).each do |dir|
|
113
|
+
# generate_cache_id returns key formatted TIMEINT-PID(-COUNTER)-RND
|
114
|
+
matched = dir.scan(/(\d+)-\d+-\d+(?:-\d+)?/).first
|
115
|
+
next unless matched
|
116
|
+
time = Time.at(matched[0].to_i)
|
116
117
|
if time < (Time.now.utc - seconds)
|
117
118
|
FileUtils.rm_rf(dir)
|
118
119
|
end
|