carrierwave 0.11.0 → 1.0.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.

Potentially problematic release.


This version of carrierwave might be problematic. Click here for more details.

Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +225 -110
  3. data/lib/carrierwave/compatibility/paperclip.rb +0 -2
  4. data/lib/carrierwave/error.rb +1 -0
  5. data/lib/carrierwave/locale/en.yml +7 -4
  6. data/lib/carrierwave/mount.rb +217 -176
  7. data/lib/carrierwave/mounter.rb +164 -0
  8. data/lib/carrierwave/orm/activerecord.rb +49 -20
  9. data/lib/carrierwave/processing/mini_magick.rb +64 -13
  10. data/lib/carrierwave/processing/rmagick.rb +31 -3
  11. data/lib/carrierwave/processing.rb +0 -1
  12. data/lib/carrierwave/sanitized_file.rb +37 -17
  13. data/lib/carrierwave/storage/abstract.rb +15 -2
  14. data/lib/carrierwave/storage/file.rb +65 -2
  15. data/lib/carrierwave/storage/fog.rb +101 -29
  16. data/lib/carrierwave/storage.rb +0 -7
  17. data/lib/carrierwave/test/matchers.rb +77 -12
  18. data/lib/carrierwave/uploader/cache.rb +40 -26
  19. data/lib/carrierwave/uploader/callbacks.rb +0 -2
  20. data/lib/carrierwave/uploader/configuration.rb +48 -6
  21. data/lib/carrierwave/uploader/content_type_blacklist.rb +48 -0
  22. data/lib/carrierwave/uploader/content_type_whitelist.rb +48 -0
  23. data/lib/carrierwave/uploader/default_url.rb +3 -5
  24. data/lib/carrierwave/uploader/download.rb +10 -7
  25. data/lib/carrierwave/uploader/extension_blacklist.rb +14 -10
  26. data/lib/carrierwave/uploader/extension_whitelist.rb +12 -10
  27. data/lib/carrierwave/uploader/file_size.rb +41 -0
  28. data/lib/carrierwave/uploader/magic_mime_blacklist.rb +94 -0
  29. data/lib/carrierwave/uploader/magic_mime_whitelist.rb +94 -0
  30. data/lib/carrierwave/uploader/mountable.rb +7 -8
  31. data/lib/carrierwave/uploader/processing.rb +1 -3
  32. data/lib/carrierwave/uploader/proxy.rb +5 -7
  33. data/lib/carrierwave/uploader/remove.rb +0 -2
  34. data/lib/carrierwave/uploader/serialization.rb +1 -3
  35. data/lib/carrierwave/uploader/store.rb +5 -23
  36. data/lib/carrierwave/uploader/url.rb +1 -3
  37. data/lib/carrierwave/uploader/versions.rb +75 -82
  38. data/lib/carrierwave/uploader.rb +6 -2
  39. data/lib/carrierwave/utilities/uri.rb +4 -7
  40. data/lib/carrierwave/utilities.rb +0 -3
  41. data/lib/carrierwave/validations/active_model.rb +0 -2
  42. data/lib/carrierwave/version.rb +1 -1
  43. data/lib/carrierwave.rb +8 -10
  44. data/lib/generators/templates/uploader.rb +3 -5
  45. metadata +43 -81
  46. data/lib/carrierwave/locale/cs.yml +0 -11
  47. data/lib/carrierwave/locale/de.yml +0 -11
  48. data/lib/carrierwave/locale/el.yml +0 -11
  49. data/lib/carrierwave/locale/es.yml +0 -11
  50. data/lib/carrierwave/locale/fr.yml +0 -11
  51. data/lib/carrierwave/locale/ja.yml +0 -11
  52. data/lib/carrierwave/locale/nb.yml +0 -11
  53. data/lib/carrierwave/locale/nl.yml +0 -11
  54. data/lib/carrierwave/locale/pl.yml +0 -11
  55. data/lib/carrierwave/locale/pt-BR.yml +0 -11
  56. data/lib/carrierwave/locale/pt-PT.yml +0 -11
  57. data/lib/carrierwave/locale/ru.yml +0 -11
  58. data/lib/carrierwave/locale/sk.yml +0 -11
  59. data/lib/carrierwave/locale/tr.yml +0 -11
  60. data/lib/carrierwave/processing/mime_types.rb +0 -74
  61. data/lib/carrierwave/utilities/deprecation.rb +0 -18
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'active_record'
4
2
  require 'carrierwave/validations/active_model'
5
3
 
@@ -14,6 +12,35 @@ module CarrierWave
14
12
  def mount_uploader(column, uploader=nil, options={}, &block)
15
13
  super
16
14
 
15
+ class_eval <<-RUBY, __FILE__, __LINE__+1
16
+ def remote_#{column}_url=(url)
17
+ column = _mounter(:#{column}).serialization_column
18
+ send(:"\#{column}_will_change!")
19
+ super
20
+ end
21
+ RUBY
22
+ end
23
+
24
+ ##
25
+ # See +CarrierWave::Mount#mount_uploaders+ for documentation
26
+ #
27
+ def mount_uploaders(column, uploader=nil, options={}, &block)
28
+ super
29
+
30
+ class_eval <<-RUBY, __FILE__, __LINE__+1
31
+ def remote_#{column}_urls=(url)
32
+ column = _mounter(:#{column}).serialization_column
33
+ send(:"\#{column}_will_change!")
34
+ super
35
+ end
36
+ RUBY
37
+ end
38
+
39
+ private
40
+
41
+ def mount_base(column, uploader=nil, options={}, &block)
42
+ super
43
+
17
44
  alias_method :read_uploader, :read_attribute
18
45
  alias_method :write_uploader, :write_attribute
19
46
  public :read_uploader
@@ -29,43 +56,45 @@ module CarrierWave
29
56
  before_save :"write_#{column}_identifier"
30
57
  after_commit :"remove_#{column}!", :on => :destroy
31
58
  after_commit :"mark_remove_#{column}_false", :on => :update
32
- before_update :"store_previous_model_for_#{column}"
33
- after_save :"remove_previously_stored_#{column}"
59
+
60
+ after_save :"store_previous_changes_for_#{column}"
61
+ after_commit :"remove_previously_stored_#{column}", :on => :update
34
62
 
35
63
  class_eval <<-RUBY, __FILE__, __LINE__+1
36
64
  def #{column}=(new_file)
37
65
  column = _mounter(:#{column}).serialization_column
38
- send(:"\#{column}_will_change!")
66
+ if !(new_file.blank? && send(:#{column}).blank?)
67
+ send(:"\#{column}_will_change!")
68
+ end
69
+
39
70
  super
40
71
  end
41
72
 
42
- def remote_#{column}_url=(url)
73
+ def remove_#{column}=(value)
43
74
  column = _mounter(:#{column}).serialization_column
44
75
  send(:"\#{column}_will_change!")
45
76
  super
46
77
  end
47
78
 
48
79
  def remove_#{column}!
80
+ self.remove_#{column} = true
81
+ write_#{column}_identifier
82
+ self.remove_#{column} = false
49
83
  super
50
- _mounter(:#{column}).remove = true
51
- _mounter(:#{column}).write_identifier
52
84
  end
53
85
 
54
- def serializable_hash(options=nil)
55
- hash = {}
56
-
57
- except = options && options[:except] && Array.wrap(options[:except]).map(&:to_s)
58
- only = options && options[:only] && Array.wrap(options[:only]).map(&:to_s)
86
+ # Reset cached mounter on record reload
87
+ def reload(*)
88
+ @_mounters = nil
89
+ super
90
+ end
59
91
 
60
- self.class.uploaders.each do |column, uploader|
61
- if (!only && !except) || (only && only.include?(column.to_s)) || (!only && except && !except.include?(column.to_s))
62
- hash[column.to_s] = _mounter(column).uploader.serializable_hash
63
- end
64
- end
65
- super(options).merge(hash)
92
+ # Reset cached mounter on record dup
93
+ def initialize_dup(other)
94
+ @_mounters = nil
95
+ super
66
96
  end
67
97
  RUBY
68
-
69
98
  end
70
99
 
71
100
  end # ActiveRecord
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
 
5
3
  ##
@@ -39,6 +37,7 @@ module CarrierWave
39
37
  # img
40
38
  # end
41
39
  # end
40
+ # end
42
41
  #
43
42
  # === Note
44
43
  #
@@ -49,7 +48,7 @@ module CarrierWave
49
48
  #
50
49
  # http://mini_magick.rubyforge.org/
51
50
  # and
52
- # https://github.com/minimagic/minimagick/
51
+ # https://github.com/minimagick/minimagick/
53
52
  #
54
53
  #
55
54
  module MiniMagick
@@ -81,7 +80,7 @@ module CarrierWave
81
80
  process :resize_to_fill => [width, height, gravity]
82
81
  end
83
82
 
84
- def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
83
+ def resize_and_pad(width, height, background=:transparent, gravity='Center')
85
84
  process :resize_and_pad => [width, height, background, gravity]
86
85
  end
87
86
  end
@@ -103,10 +102,10 @@ module CarrierWave
103
102
  #
104
103
  # image.convert(:png)
105
104
  #
106
- def convert(format)
105
+ def convert(format, page=nil)
107
106
  @format = format
107
+ @page = page
108
108
  manipulate! do |img|
109
- img.format(format.to_s.downcase)
110
109
  img = yield(img) if block_given?
111
110
  img
112
111
  end
@@ -127,9 +126,12 @@ module CarrierWave
127
126
  #
128
127
  # [MiniMagick::Image] additional manipulations to perform
129
128
  #
130
- def resize_to_limit(width, height)
129
+ def resize_to_limit(width, height, combine_options: {})
131
130
  manipulate! do |img|
132
- img.resize "#{width}x#{height}>"
131
+ img.combine_options do |cmd|
132
+ cmd.resize "#{width}x#{height}>"
133
+ append_combine_options cmd, combine_options
134
+ end
133
135
  img = yield(img) if block_given?
134
136
  img
135
137
  end
@@ -149,9 +151,12 @@ module CarrierWave
149
151
  #
150
152
  # [MiniMagick::Image] additional manipulations to perform
151
153
  #
152
- def resize_to_fit(width, height)
154
+ def resize_to_fit(width, height, combine_options: {})
153
155
  manipulate! do |img|
154
- img.resize "#{width}x#{height}"
156
+ img.combine_options do |cmd|
157
+ cmd.resize "#{width}x#{height}"
158
+ append_combine_options cmd, combine_options
159
+ end
155
160
  img = yield(img) if block_given?
156
161
  img
157
162
  end
@@ -172,7 +177,7 @@ module CarrierWave
172
177
  #
173
178
  # [MiniMagick::Image] additional manipulations to perform
174
179
  #
175
- def resize_to_fill(width, height, gravity = 'Center')
180
+ def resize_to_fill(width, height, gravity = 'Center', combine_options: {})
176
181
  manipulate! do |img|
177
182
  cols, rows = img[:dimensions]
178
183
  img.combine_options do |cmd|
@@ -192,6 +197,7 @@ module CarrierWave
192
197
  cmd.gravity gravity
193
198
  cmd.background "rgba(255,255,255,0.0)"
194
199
  cmd.extent "#{width}x#{height}" if cols != width || rows != height
200
+ append_combine_options cmd, combine_options
195
201
  end
196
202
  img = yield(img) if block_given?
197
203
  img
@@ -218,7 +224,7 @@ module CarrierWave
218
224
  #
219
225
  # [MiniMagick::Image] additional manipulations to perform
220
226
  #
221
- def resize_and_pad(width, height, background=:transparent, gravity='Center')
227
+ def resize_and_pad(width, height, background=:transparent, gravity='Center', combine_options: {})
222
228
  manipulate! do |img|
223
229
  img.combine_options do |cmd|
224
230
  cmd.thumbnail "#{width}x#{height}>"
@@ -229,12 +235,35 @@ module CarrierWave
229
235
  end
230
236
  cmd.gravity gravity
231
237
  cmd.extent "#{width}x#{height}"
238
+ append_combine_options cmd, combine_options
232
239
  end
233
240
  img = yield(img) if block_given?
234
241
  img
235
242
  end
236
243
  end
237
244
 
245
+ ##
246
+ # Returns the width of the image in pixels.
247
+ #
248
+ # === Returns
249
+ #
250
+ # [Integer] the image's width in pixels
251
+ #
252
+ def width
253
+ mini_magick_image[:width]
254
+ end
255
+
256
+ ##
257
+ # Returns the height of the image in pixels.
258
+ #
259
+ # === Returns
260
+ #
261
+ # [Integer] the image's height in pixels
262
+ #
263
+ def height
264
+ mini_magick_image[:height]
265
+ end
266
+
238
267
  ##
239
268
  # Manipulate the image with MiniMagick. This method will load up an image
240
269
  # and then pass each of its frames to the supplied block. It will then
@@ -260,9 +289,15 @@ module CarrierWave
260
289
  image = ::MiniMagick::Image.open(current_path)
261
290
 
262
291
  begin
263
- image.format(@format.to_s.downcase) if @format
292
+ image.format(@format.to_s.downcase, @page) if @format
264
293
  image = yield(image)
265
294
  image.write(current_path)
295
+
296
+ if @format
297
+ move_to = current_path.chomp(File.extname(current_path)) + ".#{@format}"
298
+ file.move_to(move_to, permissions, directory_permissions)
299
+ end
300
+
266
301
  image.run_command("identify", current_path)
267
302
  ensure
268
303
  image.destroy!
@@ -273,5 +308,21 @@ module CarrierWave
273
308
  raise CarrierWave::ProcessingError, message
274
309
  end
275
310
 
311
+ private
312
+
313
+ def append_combine_options(cmd, combine_options)
314
+ combine_options.each do |method, options|
315
+ cmd.send(method, options)
316
+ end
317
+ end
318
+
319
+ def mini_magick_image
320
+ if url
321
+ ::MiniMagick::Image.open(url)
322
+ else
323
+ ::MiniMagick::Image.open(current_path)
324
+ end
325
+ end
326
+
276
327
  end # MiniMagick
277
328
  end # CarrierWave
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
 
5
3
  ##
@@ -251,6 +249,28 @@ module CarrierWave
251
249
  end
252
250
  end
253
251
 
252
+ ##
253
+ # Returns the width of the image.
254
+ #
255
+ # === Returns
256
+ #
257
+ # [Integer] the image's width in pixels
258
+ #
259
+ def width
260
+ rmagick_image.columns
261
+ end
262
+
263
+ ##
264
+ # Returns the height of the image.
265
+ #
266
+ # === Returns
267
+ #
268
+ # [Integer] the image's height in pixels
269
+ #
270
+ def height
271
+ rmagick_image.rows
272
+ end
273
+
254
274
  ##
255
275
  # Manipulate the image with RMagick. This method will load up an image
256
276
  # and then pass each of its frames to the supplied block. It will then
@@ -324,11 +344,15 @@ module CarrierWave
324
344
  frames.append(true) if block_given?
325
345
 
326
346
  write_block = create_info_block(options[:write])
347
+
327
348
  if options[:format] || @format
328
349
  frames.write("#{options[:format] || @format}:#{current_path}", &write_block)
350
+ move_to = current_path.chomp(File.extname(current_path)) + ".#{options[:format] || @format}"
351
+ file.move_to(move_to, permissions, directory_permissions)
329
352
  else
330
353
  frames.write(current_path, &write_block)
331
354
  end
355
+
332
356
  destroy_image(frames)
333
357
  rescue ::Magick::ImageMagickError => e
334
358
  raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.rmagick_processing_error", :e => e, :default => I18n.translate(:"errors.messages.rmagick_processing_error", :e => e, :locale => :en))
@@ -344,7 +368,11 @@ module CarrierWave
344
368
  end
345
369
 
346
370
  def destroy_image(image)
347
- image.destroy! if image.respond_to?(:destroy!)
371
+ image.try(:destroy!)
372
+ end
373
+
374
+ def rmagick_image
375
+ ::Magick::Image.read(current_path).first
348
376
  end
349
377
 
350
378
  end # RMagick
@@ -1,3 +1,2 @@
1
1
  require "carrierwave/processing/rmagick"
2
2
  require "carrierwave/processing/mini_magick"
3
- require "carrierwave/processing/mime_types"
@@ -1,8 +1,12 @@
1
- # encoding: utf-8
2
-
3
1
  require 'pathname'
4
2
  require 'active_support/core_ext/string/multibyte'
5
- require 'mime/types'
3
+
4
+ begin
5
+ # Use mime/types/columnar if available, for reduced memory usage
6
+ require 'mime/types/columnar'
7
+ rescue LoadError
8
+ require 'mime/types'
9
+ end
6
10
 
7
11
  module CarrierWave
8
12
 
@@ -22,7 +26,7 @@ module CarrierWave
22
26
  attr_writer :sanitize_regexp
23
27
 
24
28
  def sanitize_regexp
25
- @sanitize_regexp ||= /[^a-zA-Z0-9\.\-\+_]/
29
+ @sanitize_regexp ||= /[^[:word:]\.\-\+]/
26
30
  end
27
31
  end
28
32
 
@@ -142,8 +146,7 @@ module CarrierWave
142
146
  # [Boolean] Whether the file exists
143
147
  #
144
148
  def exists?
145
- return File.exists?(self.path) if self.path
146
- return false
149
+ self.path.present? && File.exist?(self.path)
147
150
  end
148
151
 
149
152
  ##
@@ -159,9 +162,9 @@ module CarrierWave
159
162
  elsif is_path?
160
163
  File.open(@file, "rb") {|file| file.read}
161
164
  else
162
- @file.rewind if @file.respond_to?(:rewind)
165
+ @file.try(:rewind)
163
166
  @content = @file.read
164
- @file.close if @file.respond_to?(:close) && @file.respond_to?(:closed?) && !@file.closed?
167
+ @file.try(:close) unless @file.try(:closed?)
165
168
  @content
166
169
  end
167
170
  end
@@ -175,19 +178,29 @@ module CarrierWave
175
178
  # [permissions (Integer)] permissions to set on the file in its new location.
176
179
  # [directory_permissions (Integer)] permissions to set on created directories.
177
180
  #
178
- def move_to(new_path, permissions=nil, directory_permissions=nil)
181
+ def move_to(new_path, permissions=nil, directory_permissions=nil, keep_filename=false)
179
182
  return if self.empty?
180
183
  new_path = File.expand_path(new_path)
181
184
 
182
185
  mkdir!(new_path, directory_permissions)
186
+ move!(new_path)
187
+ chmod!(new_path, permissions)
188
+ if keep_filename
189
+ self.file = {:tempfile => new_path, :filename => original_filename}
190
+ else
191
+ self.file = new_path
192
+ end
193
+ self
194
+ end
195
+ ##
196
+ # Helper to move file to new path.
197
+ #
198
+ def move!(new_path)
183
199
  if exists?
184
200
  FileUtils.mv(path, new_path) unless new_path == path
185
201
  else
186
202
  File.open(new_path, "wb") { |f| f.write(read) }
187
203
  end
188
- chmod!(new_path, permissions)
189
- self.file = new_path
190
- self
191
204
  end
192
205
 
193
206
  ##
@@ -208,13 +221,20 @@ module CarrierWave
208
221
  new_path = File.expand_path(new_path)
209
222
 
210
223
  mkdir!(new_path, directory_permissions)
224
+ copy!(new_path)
225
+ chmod!(new_path, permissions)
226
+ self.class.new({:tempfile => new_path, :content_type => content_type})
227
+ end
228
+
229
+ ##
230
+ # Helper to create copy of file in new path.
231
+ #
232
+ def copy!(new_path)
211
233
  if exists?
212
234
  FileUtils.cp(path, new_path) unless new_path == path
213
235
  else
214
236
  File.open(new_path, "wb") { |f| f.write(read) }
215
237
  end
216
- chmod!(new_path, permissions)
217
- self.class.new({:tempfile => new_path, :content_type => content_type})
218
238
  end
219
239
 
220
240
  ##
@@ -280,7 +300,7 @@ module CarrierWave
280
300
  if file.is_a?(Hash)
281
301
  @file = file["tempfile"] || file[:tempfile]
282
302
  @original_filename = file["filename"] || file[:filename]
283
- @content_type = file["content_type"] || file[:content_type]
303
+ @content_type = file["content_type"] || file[:content_type] || file["type"] || file[:type]
284
304
  else
285
305
  @file = file
286
306
  @original_filename = nil
@@ -292,7 +312,7 @@ module CarrierWave
292
312
  def mkdir!(path, directory_permissions)
293
313
  options = {}
294
314
  options[:mode] = directory_permissions if directory_permissions
295
- FileUtils.mkdir_p(File.dirname(path), options) unless File.exists?(File.dirname(path))
315
+ FileUtils.mkdir_p(File.dirname(path), options) unless File.exist?(File.dirname(path))
296
316
  end
297
317
 
298
318
  def chmod!(path, permissions)
@@ -301,7 +321,7 @@ module CarrierWave
301
321
 
302
322
  # Sanitize the filename, to prevent hacking
303
323
  def sanitize(name)
304
- name = name.gsub("\\", "/") # work-around for IE
324
+ name = name.tr("\\", "/") # work-around for IE
305
325
  name = File.basename(name)
306
326
  name = name.gsub(sanitize_regexp,"_")
307
327
  name = "_#{name}" if name =~ /\A\.+\z/
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Storage
5
3
 
@@ -25,6 +23,21 @@ module CarrierWave
25
23
  def retrieve!(identifier)
26
24
  end
27
25
 
26
+ def cache!(new_file)
27
+ raise NotImplementedError.new("Need to implement #cache! if you want to use #{self.class.name} as a cache storage.")
28
+ end
29
+
30
+ def retrieve_from_cache!(identifier)
31
+ raise NotImplementedError.new("Need to implement #retrieve_from_cache! if you want to use #{self.class.name} as a cache storage.")
32
+ end
33
+
34
+ def delete_dir!(path)
35
+ raise NotImplementedError.new("Need to implement #delete_dir! if you want to use #{self.class.name} as a cache storage.")
36
+ end
37
+
38
+ def clean_cache!(seconds)
39
+ raise NotImplementedError.new("Need to implement #clean_cache! if you want to use #{self.class.name} as a cache storage.")
40
+ end
28
41
  end # Abstract
29
42
  end # Storage
30
43
  end # CarrierWave
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Storage
5
3
 
@@ -51,6 +49,71 @@ module CarrierWave
51
49
  CarrierWave::SanitizedFile.new(path)
52
50
  end
53
51
 
52
+ ##
53
+ # Stores given file to cache directory.
54
+ #
55
+ # === Parameters
56
+ #
57
+ # [new_file (File, IOString, Tempfile)] any kind of file object
58
+ #
59
+ # === Returns
60
+ #
61
+ # [CarrierWave::SanitizedFile] a sanitized file
62
+ #
63
+ def cache!(new_file)
64
+ new_file.move_to(::File.expand_path(uploader.cache_path, uploader.root), uploader.permissions, uploader.directory_permissions, true)
65
+ rescue Errno::EMLINK => e
66
+ raise(e) if @cache_called
67
+ @cache_called = true
68
+
69
+ # NOTE: Remove cached files older than 10 minutes
70
+ clean_cache!(600)
71
+
72
+ cache!(new_file)
73
+ end
74
+
75
+ ##
76
+ # Retrieves the file with the given cache_name from the cache.
77
+ #
78
+ # === Parameters
79
+ #
80
+ # [cache_name (String)] uniquely identifies a cache file
81
+ #
82
+ # === Raises
83
+ #
84
+ # [CarrierWave::InvalidParameter] if the cache_name is incorrectly formatted.
85
+ #
86
+ def retrieve_from_cache!(identifier)
87
+ CarrierWave::SanitizedFile.new(::File.expand_path(uploader.cache_path(identifier), uploader.root))
88
+ end
89
+
90
+ ##
91
+ # Deletes a cache dir
92
+ #
93
+ def delete_dir!(path)
94
+ if path
95
+ begin
96
+ Dir.rmdir(::File.expand_path(path, uploader.root))
97
+ rescue Errno::ENOENT
98
+ # Ignore: path does not exist
99
+ rescue Errno::ENOTDIR
100
+ # Ignore: path is not a dir
101
+ rescue Errno::ENOTEMPTY, Errno::EEXIST
102
+ # Ignore: dir is not empty
103
+ end
104
+ end
105
+ end
106
+
107
+ def clean_cache!(seconds)
108
+ Dir.glob(::File.expand_path(::File.join(uploader.cache_dir, '*'), CarrierWave.root)).each do |dir|
109
+ # generate_cache_id returns key formated TIMEINT-PID-COUNTER-RND
110
+ time = dir.scan(/(\d+)-\d+-\d+-\d+/).first.map(&:to_i)
111
+ time = Time.at(*time)
112
+ if time < (Time.now.utc - seconds)
113
+ FileUtils.rm_rf(dir)
114
+ end
115
+ end
116
+ end
54
117
  end # File
55
118
  end # Storage
56
119
  end # CarrierWave