carrierwave 0.11.2 → 3.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +452 -178
  3. data/lib/carrierwave/compatibility/paperclip.rb +4 -4
  4. data/lib/carrierwave/downloader/base.rb +101 -0
  5. data/lib/carrierwave/downloader/remote_file.rb +68 -0
  6. data/lib/carrierwave/error.rb +1 -0
  7. data/lib/carrierwave/locale/en.yml +11 -5
  8. data/lib/carrierwave/mount.rb +217 -182
  9. data/lib/carrierwave/mounter.rb +255 -0
  10. data/lib/carrierwave/orm/activerecord.rb +29 -35
  11. data/lib/carrierwave/processing/mini_magick.rb +140 -84
  12. data/lib/carrierwave/processing/rmagick.rb +72 -21
  13. data/lib/carrierwave/processing/vips.rb +284 -0
  14. data/lib/carrierwave/processing.rb +1 -1
  15. data/lib/carrierwave/sanitized_file.rb +83 -84
  16. data/lib/carrierwave/storage/abstract.rb +16 -3
  17. data/lib/carrierwave/storage/file.rb +71 -3
  18. data/lib/carrierwave/storage/fog.rb +215 -57
  19. data/lib/carrierwave/storage.rb +1 -9
  20. data/lib/carrierwave/test/matchers.rb +88 -19
  21. data/lib/carrierwave/uploader/cache.rb +75 -45
  22. data/lib/carrierwave/uploader/callbacks.rb +1 -3
  23. data/lib/carrierwave/uploader/configuration.rb +80 -16
  24. data/lib/carrierwave/uploader/content_type_allowlist.rb +62 -0
  25. data/lib/carrierwave/uploader/content_type_denylist.rb +62 -0
  26. data/lib/carrierwave/uploader/default_url.rb +3 -5
  27. data/lib/carrierwave/uploader/dimension.rb +66 -0
  28. data/lib/carrierwave/uploader/download.rb +4 -74
  29. data/lib/carrierwave/uploader/extension_allowlist.rb +63 -0
  30. data/lib/carrierwave/uploader/extension_denylist.rb +64 -0
  31. data/lib/carrierwave/uploader/file_size.rb +43 -0
  32. data/lib/carrierwave/uploader/mountable.rb +13 -8
  33. data/lib/carrierwave/uploader/processing.rb +48 -13
  34. data/lib/carrierwave/uploader/proxy.rb +20 -9
  35. data/lib/carrierwave/uploader/remove.rb +0 -2
  36. data/lib/carrierwave/uploader/serialization.rb +2 -4
  37. data/lib/carrierwave/uploader/store.rb +59 -28
  38. data/lib/carrierwave/uploader/url.rb +8 -7
  39. data/lib/carrierwave/uploader/versions.rb +171 -123
  40. data/lib/carrierwave/uploader.rb +12 -10
  41. data/lib/carrierwave/utilities/file_name.rb +47 -0
  42. data/lib/carrierwave/utilities/uri.rb +14 -12
  43. data/lib/carrierwave/utilities.rb +1 -3
  44. data/lib/carrierwave/validations/active_model.rb +7 -11
  45. data/lib/carrierwave/version.rb +1 -1
  46. data/lib/carrierwave.rb +39 -21
  47. data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +6 -10
  48. data/lib/generators/uploader_generator.rb +3 -3
  49. metadata +135 -83
  50. data/lib/carrierwave/locale/cs.yml +0 -11
  51. data/lib/carrierwave/locale/de.yml +0 -11
  52. data/lib/carrierwave/locale/el.yml +0 -11
  53. data/lib/carrierwave/locale/es.yml +0 -11
  54. data/lib/carrierwave/locale/fr.yml +0 -11
  55. data/lib/carrierwave/locale/ja.yml +0 -11
  56. data/lib/carrierwave/locale/nb.yml +0 -11
  57. data/lib/carrierwave/locale/nl.yml +0 -11
  58. data/lib/carrierwave/locale/pl.yml +0 -11
  59. data/lib/carrierwave/locale/pt-BR.yml +0 -11
  60. data/lib/carrierwave/locale/pt-PT.yml +0 -11
  61. data/lib/carrierwave/locale/ru.yml +0 -11
  62. data/lib/carrierwave/locale/sk.yml +0 -11
  63. data/lib/carrierwave/locale/tr.yml +0 -11
  64. data/lib/carrierwave/processing/mime_types.rb +0 -74
  65. data/lib/carrierwave/uploader/content_type_blacklist.rb +0 -48
  66. data/lib/carrierwave/uploader/content_type_whitelist.rb +0 -48
  67. data/lib/carrierwave/uploader/extension_blacklist.rb +0 -47
  68. data/lib/carrierwave/uploader/extension_whitelist.rb +0 -49
  69. data/lib/carrierwave/utilities/deprecation.rb +0 -18
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Test
5
3
 
@@ -23,13 +21,16 @@ module CarrierWave
23
21
  "expected #{@actual.inspect} to be identical to #{@expected.inspect}"
24
22
  end
25
23
 
26
- def negative_failure_message
24
+ def failure_message_when_negated
27
25
  "expected #{@actual.inspect} to not be identical to #{@expected.inspect}"
28
26
  end
29
27
 
30
28
  def description
31
29
  "be identical to #{@expected.inspect}"
32
30
  end
31
+
32
+ # RSpec 2 compatibility:
33
+ alias_method :negative_failure_message, :failure_message_when_negated
33
34
  end
34
35
 
35
36
  def be_identical_to(expected)
@@ -44,20 +45,23 @@ module CarrierWave
44
45
  def matches?(actual)
45
46
  @actual = actual
46
47
  # Satisfy expectation here. Return false or raise an error if it's not met.
47
- (File.stat(@actual.path).mode & 0777) == @expected
48
+ (File.stat(@actual.path).mode & 0o777) == @expected
48
49
  end
49
50
 
50
51
  def failure_message
51
- "expected #{@actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
52
+ "expected #{@actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0o777).to_s(8)}"
52
53
  end
53
54
 
54
- def negative_failure_message
55
+ def failure_message_when_negated
55
56
  "expected #{@actual.current_path.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
56
57
  end
57
58
 
58
59
  def description
59
60
  "have permissions #{@expected.to_s(8)}"
60
61
  end
62
+
63
+ # RSpec 2 compatibility:
64
+ alias_method :negative_failure_message, :failure_message_when_negated
61
65
  end
62
66
 
63
67
  def have_permissions(expected)
@@ -72,20 +76,23 @@ module CarrierWave
72
76
  def matches?(actual)
73
77
  @actual = actual
74
78
  # Satisfy expectation here. Return false or raise an error if it's not met.
75
- (File.stat(File.dirname @actual.path).mode & 0777) == @expected
79
+ (File.stat(File.dirname(@actual.path)).mode & 0o777) == @expected
76
80
  end
77
81
 
78
82
  def failure_message
79
- "expected #{File.dirname @actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
83
+ "expected #{File.dirname @actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0o777).to_s(8)}"
80
84
  end
81
85
 
82
- def negative_failure_message
86
+ def failure_message_when_negated
83
87
  "expected #{File.dirname @actual.current_path.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
84
88
  end
85
89
 
86
90
  def description
87
91
  "have permissions #{@expected.to_s(8)}"
88
92
  end
93
+
94
+ # RSpec 2 compatibility:
95
+ alias_method :negative_failure_message, :failure_message_when_negated
89
96
  end
90
97
 
91
98
  def have_directory_permissions(expected)
@@ -110,13 +117,16 @@ module CarrierWave
110
117
  "expected #{@actual.current_path.inspect} to be no larger than #{@width} by #{@height}, but it was #{@actual_width} by #{@actual_height}."
111
118
  end
112
119
 
113
- def negative_failure_message
120
+ def failure_message_when_negated
114
121
  "expected #{@actual.current_path.inspect} to be larger than #{@width} by #{@height}, but it wasn't."
115
122
  end
116
123
 
117
124
  def description
118
125
  "be no larger than #{@width} by #{@height}"
119
126
  end
127
+
128
+ # RSpec 2 compatibility:
129
+ alias_method :negative_failure_message, :failure_message_when_negated
120
130
  end
121
131
 
122
132
  def be_no_larger_than(width, height)
@@ -141,13 +151,16 @@ module CarrierWave
141
151
  "expected #{@actual.current_path.inspect} to have an exact size of #{@width} by #{@height}, but it was #{@actual_width} by #{@actual_height}."
142
152
  end
143
153
 
144
- def negative_failure_message
154
+ def failure_message_when_negated
145
155
  "expected #{@actual.current_path.inspect} not to have an exact size of #{@width} by #{@height}, but it did."
146
156
  end
147
157
 
148
158
  def description
149
159
  "have an exact size of #{@width} by #{@height}"
150
160
  end
161
+
162
+ # RSpec 2 compatibility:
163
+ alias_method :negative_failure_message, :failure_message_when_negated
151
164
  end
152
165
 
153
166
  def have_dimensions(width, height)
@@ -171,13 +184,16 @@ module CarrierWave
171
184
  "expected #{@actual.current_path.inspect} to have an exact size of #{@height}, but it was #{@actual_height}."
172
185
  end
173
186
 
174
- def negative_failure_message
187
+ def failure_message_when_negated
175
188
  "expected #{@actual.current_path.inspect} not to have an exact size of #{@height}, but it did."
176
189
  end
177
190
 
178
191
  def description
179
192
  "have an exact height of #{@height}"
180
193
  end
194
+
195
+ # RSpec 2 compatibility:
196
+ alias_method :negative_failure_message, :failure_message_when_negated
181
197
  end
182
198
 
183
199
  def have_height(height)
@@ -201,13 +217,16 @@ module CarrierWave
201
217
  "expected #{@actual.current_path.inspect} to have an exact size of #{@width}, but it was #{@actual_width}."
202
218
  end
203
219
 
204
- def negative_failure_message
220
+ def failure_message_when_negated
205
221
  "expected #{@actual.current_path.inspect} not to have an exact size of #{@width}, but it did."
206
222
  end
207
223
 
208
224
  def description
209
225
  "have an exact width of #{@width}"
210
226
  end
227
+
228
+ # RSpec 2 compatibility:
229
+ alias_method :negative_failure_message, :failure_message_when_negated
211
230
  end
212
231
 
213
232
  def have_width(width)
@@ -231,13 +250,16 @@ module CarrierWave
231
250
  "expected #{@actual.current_path.inspect} to be no wider than #{@width}, but it was #{@actual_width}."
232
251
  end
233
252
 
234
- def negative_failure_message
253
+ def failure_message_when_negated
235
254
  "expected #{@actual.current_path.inspect} not to be wider than #{@width}, but it is."
236
255
  end
237
256
 
238
257
  def description
239
258
  "have a width less than or equal to #{@width}"
240
259
  end
260
+
261
+ # RSpec 2 compatibility:
262
+ alias_method :negative_failure_message, :failure_message_when_negated
241
263
  end
242
264
 
243
265
  def be_no_wider_than(width)
@@ -261,19 +283,55 @@ module CarrierWave
261
283
  "expected #{@actual.current_path.inspect} to be no taller than #{@height}, but it was #{@actual_height}."
262
284
  end
263
285
 
264
- def negative_failure_message
286
+ def failure_message_when_negated
265
287
  "expected #{@actual.current_path.inspect} not to be taller than #{@height}, but it is."
266
288
  end
267
289
 
268
290
  def description
269
291
  "have a height less than or equal to #{@height}"
270
292
  end
293
+
294
+ # RSpec 2 compatibility:
295
+ alias_method :negative_failure_message, :failure_message_when_negated
271
296
  end
272
297
 
273
298
  def be_no_taller_than(height)
274
299
  BeNoTallerThan.new(height)
275
300
  end
276
301
 
302
+ class BeFormat # :nodoc:
303
+ def initialize(expected)
304
+ @expected = expected
305
+ end
306
+
307
+ def matches?(actual)
308
+ @actual = actual
309
+ # Satisfy expectation here. Return false or raise an error if it's not met.
310
+ image = ImageLoader.load_image(@actual.current_path)
311
+ @actual_expected = image.format
312
+ !@expected.nil? && @actual_expected.casecmp(@expected).zero?
313
+ end
314
+
315
+ def failure_message
316
+ "expected #{@actual.current_path.inspect} to have #{@expected} format, but it was #{@actual_expected}."
317
+ end
318
+
319
+ def failure_message_when_negated
320
+ "expected #{@actual.current_path.inspect} not to have #{@expected} format, but it did."
321
+ end
322
+
323
+ def description
324
+ "have #{@expected} format"
325
+ end
326
+
327
+ # RSpec 2 compatibility:
328
+ alias_method :negative_failure_message, :failure_message_when_negated
329
+ end
330
+
331
+ def be_format(expected)
332
+ BeFormat.new(expected)
333
+ end
334
+
277
335
  class ImageLoader # :nodoc:
278
336
  def self.load_image(filename)
279
337
  if defined? ::MiniMagick
@@ -283,9 +341,11 @@ module CarrierWave
283
341
  begin
284
342
  require 'rmagick'
285
343
  rescue LoadError
286
- require 'RMagick'
287
- rescue LoadError
288
- puts "WARNING: Failed to require rmagick, image processing may fail!"
344
+ begin
345
+ require 'RMagick'
346
+ rescue LoadError
347
+ puts "WARNING: Failed to require rmagick, image processing may fail!"
348
+ end
289
349
  end
290
350
  end
291
351
  MagickWrapper.new(filename)
@@ -295,6 +355,7 @@ module CarrierWave
295
355
 
296
356
  class MagickWrapper # :nodoc:
297
357
  attr_reader :image
358
+
298
359
  def width
299
360
  image.columns
300
361
  end
@@ -303,6 +364,10 @@ module CarrierWave
303
364
  image.rows
304
365
  end
305
366
 
367
+ def format
368
+ image.format
369
+ end
370
+
306
371
  def initialize(filename)
307
372
  @image = ::Magick::Image.read(filename).first
308
373
  end
@@ -310,6 +375,7 @@ module CarrierWave
310
375
 
311
376
  class MiniMagickWrapper # :nodoc:
312
377
  attr_reader :image
378
+
313
379
  def width
314
380
  image[:width]
315
381
  end
@@ -318,6 +384,10 @@ module CarrierWave
318
384
  image[:height]
319
385
  end
320
386
 
387
+ def format
388
+ image[:format]
389
+ end
390
+
321
391
  def initialize(filename)
322
392
  @image = ::MiniMagick::Image.open(filename)
323
393
  end
@@ -326,4 +396,3 @@ module CarrierWave
326
396
  end # Matchers
327
397
  end # Test
328
398
  end # CarrierWave
329
-
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ require 'securerandom'
2
2
 
3
3
  module CarrierWave
4
4
 
@@ -24,10 +24,11 @@ module CarrierWave
24
24
  # [String] a cache id in the format TIMEINT-PID-COUNTER-RND
25
25
  #
26
26
  def self.generate_cache_id
27
- [Time.now.utc.to_i,
28
- Process.pid,
29
- '%04d' % (CarrierWave::CacheCounter.increment % 1000),
30
- '%04d' % rand(9999)
27
+ [
28
+ Time.now.utc.to_i,
29
+ SecureRandom.random_number(1_000_000_000_000_000),
30
+ '%04d' % (CarrierWave::CacheCounter.increment % 10_000),
31
+ '%04d' % SecureRandom.random_number(10_000)
31
32
  ].map(&:to_s).join('-')
32
33
  end
33
34
 
@@ -38,6 +39,16 @@ module CarrierWave
38
39
  include CarrierWave::Uploader::Callbacks
39
40
  include CarrierWave::Uploader::Configuration
40
41
 
42
+ included do
43
+ prepend Module.new {
44
+ def initialize(*)
45
+ super
46
+ @staged = false
47
+ end
48
+ }
49
+ attr_accessor :staged
50
+ end
51
+
41
52
  module ClassMethods
42
53
 
43
54
  ##
@@ -54,13 +65,7 @@ module CarrierWave
54
65
  # It's recommended that you keep cache files in one place only.
55
66
  #
56
67
  def clean_cached_files!(seconds=60*60*24)
57
- Dir.glob(File.expand_path(File.join(cache_dir, '*'), CarrierWave.root)).each do |dir|
58
- time = dir.scan(/(\d+)-\d+-\d+/).first.map { |t| t.to_i }
59
- time = Time.at(*time)
60
- if time < (Time.now.utc - seconds)
61
- FileUtils.rm_rf(dir)
62
- end
63
- end
68
+ (cache_storage || storage).new(new).clean_cache!(seconds)
64
69
  end
65
70
  end
66
71
 
@@ -72,7 +77,7 @@ module CarrierWave
72
77
  # [Bool] whether the current file is cached
73
78
  #
74
79
  def cached?
75
- @cache_id
80
+ !!@cache_id
76
81
  end
77
82
 
78
83
  ##
@@ -86,16 +91,8 @@ module CarrierWave
86
91
  end
87
92
 
88
93
  def sanitized_file
89
- _content = file.read
90
- if _content.is_a?(File) # could be if storage is Fog
91
- sanitized = CarrierWave::Storage::Fog.new(self).retrieve!(File.basename(_content.path))
92
- sanitized.read if sanitized.exists?
93
-
94
- else
95
- sanitized = SanitizedFile.new :tempfile => StringIO.new(file.read),
96
- :filename => File.basename(path), :content_type => file.content_type
97
- end
98
- sanitized
94
+ ActiveSupport::Deprecation.warn('#sanitized_file is deprecated, use #file instead.')
95
+ file
99
96
  end
100
97
 
101
98
  ##
@@ -106,7 +103,7 @@ module CarrierWave
106
103
  # [String] a cache name, in the format TIMEINT-PID-COUNTER-RND/filename.txt
107
104
  #
108
105
  def cache_name
109
- File.join(cache_id, full_original_filename) if cache_id and original_filename
106
+ File.join(cache_id, original_filename) if cache_id && original_filename
110
107
  end
111
108
 
112
109
  ##
@@ -114,7 +111,7 @@ module CarrierWave
114
111
  #
115
112
  # By default, cache!() uses copy_to(), which operates by copying the file
116
113
  # to the cache, then deleting the original file. If move_to_cache() is
117
- # overriden to return true, then cache!() uses move_to(), which simply
114
+ # overridden to return true, then cache!() uses move_to(), which simply
118
115
  # moves the file to the cache. Useful for large files.
119
116
  #
120
117
  # === Parameters
@@ -125,24 +122,32 @@ module CarrierWave
125
122
  #
126
123
  # [CarrierWave::FormNotMultipart] if the assigned parameter is a string
127
124
  #
128
- def cache!(new_file = sanitized_file)
125
+ def cache!(new_file = file)
129
126
  new_file = CarrierWave::SanitizedFile.new(new_file)
127
+ return if new_file.empty?
128
+
129
+ raise CarrierWave::FormNotMultipart if new_file.is_path? && ensure_multipart_form
130
130
 
131
- unless new_file.empty?
132
- raise CarrierWave::FormNotMultipart if new_file.is_path? && ensure_multipart_form
131
+ self.cache_id = CarrierWave.generate_cache_id unless cache_id
133
132
 
134
- with_callbacks(:cache, new_file) do
135
- self.cache_id = CarrierWave.generate_cache_id unless cache_id
133
+ @identifier = nil
134
+ @staged = true
135
+ @filename = new_file.filename
136
+ self.original_filename = new_file.filename
136
137
 
137
- @filename = new_file.filename
138
- self.original_filename = new_file.filename
138
+ begin
139
+ # first, create a workfile on which we perform processings
140
+ if move_to_cache
141
+ @file = new_file.move_to(File.expand_path(workfile_path, root), permissions, directory_permissions)
142
+ else
143
+ @file = new_file.copy_to(File.expand_path(workfile_path, root), permissions, directory_permissions)
144
+ end
139
145
 
140
- if move_to_cache
141
- @file = new_file.move_to(cache_path, permissions, directory_permissions)
142
- else
143
- @file = new_file.copy_to(cache_path, permissions, directory_permissions)
144
- end
146
+ with_callbacks(:cache, @file) do
147
+ @file = cache_storage.cache!(@file)
145
148
  end
149
+ ensure
150
+ FileUtils.rm_rf(workfile_path(''))
146
151
  end
147
152
  end
148
153
 
@@ -160,26 +165,43 @@ module CarrierWave
160
165
  def retrieve_from_cache!(cache_name)
161
166
  with_callbacks(:retrieve_from_cache, cache_name) do
162
167
  self.cache_id, self.original_filename = cache_name.to_s.split('/', 2)
168
+ @staged = true
163
169
  @filename = original_filename
164
- @file = CarrierWave::SanitizedFile.new(cache_path)
170
+ @file = cache_storage.retrieve_from_cache!(full_original_filename)
165
171
  end
166
172
  end
167
173
 
174
+ ##
175
+ # Calculates the path where the cache file should be stored.
176
+ #
177
+ # === Parameters
178
+ #
179
+ # [for_file (String)] name of the file <optional>
180
+ #
181
+ # === Returns
182
+ #
183
+ # [String] the cache path
184
+ #
185
+ def cache_path(for_file=full_original_filename)
186
+ File.join(*[cache_dir, @cache_id, for_file].compact)
187
+ end
188
+
189
+ protected
190
+
191
+ attr_reader :cache_id
192
+
168
193
  private
169
194
 
170
- def cache_path
171
- File.expand_path(File.join(cache_dir, cache_name), root)
195
+ def workfile_path(for_file=original_filename)
196
+ File.join(CarrierWave.tmp_path, @cache_id, version_name.to_s, for_file)
172
197
  end
173
198
 
174
- attr_reader :cache_id, :original_filename
175
-
176
- # We can override the full_original_filename method in other modules
177
- alias_method :full_original_filename, :original_filename
199
+ attr_reader :original_filename
178
200
 
179
201
  def cache_id=(cache_id)
180
202
  # Earlier version used 3 part cache_id. Thus we should allow for
181
203
  # the cache_id to have both 3 part and 4 part formats.
182
- raise CarrierWave::InvalidParameter, "invalid cache id" unless cache_id =~ /\A[\d]+\-[\d]+(\-[\d]{4})?\-[\d]{4}\z/
204
+ raise CarrierWave::InvalidParameter, "invalid cache id" unless cache_id =~ /\A(-)?[\d]+\-[\d]+(\-[\d]{4})?\-[\d]{4}\z/
183
205
  @cache_id = cache_id
184
206
  end
185
207
 
@@ -188,6 +210,14 @@ module CarrierWave
188
210
  @original_filename = filename
189
211
  end
190
212
 
213
+ def cache_storage
214
+ @cache_storage ||= (self.class.cache_storage || self.class.storage).new(self)
215
+ end
216
+
217
+ # We can override the full_original_filename method in other modules
218
+ def full_original_filename
219
+ forcing_extension(original_filename)
220
+ end
191
221
  end # Cache
192
222
  end # Uploader
193
223
  end # CarrierWave
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Uploader
5
3
  module Callbacks
@@ -7,7 +5,7 @@ module CarrierWave
7
5
 
8
6
  included do
9
7
  class_attribute :_before_callbacks, :_after_callbacks,
10
- :instance_writer => false
8
+ :instance_writer => false
11
9
  self._before_callbacks = Hash.new []
12
10
  self._after_callbacks = Hash.new []
13
11
  end
@@ -1,3 +1,5 @@
1
+ require 'carrierwave/downloader/base'
2
+
1
3
  module CarrierWave
2
4
 
3
5
  module Uploader
@@ -5,7 +7,7 @@ module CarrierWave
5
7
  extend ActiveSupport::Concern
6
8
 
7
9
  included do
8
- class_attribute :_storage, :instance_writer => false
10
+ class_attribute :_storage, :_cache_storage, :instance_writer => false
9
11
 
10
12
  add_config :root
11
13
  add_config :base_path
@@ -21,14 +23,18 @@ module CarrierWave
21
23
  add_config :move_to_cache
22
24
  add_config :move_to_store
23
25
  add_config :remove_previously_stored_files_after_update
26
+ add_config :downloader
27
+ add_config :force_extension
24
28
 
25
29
  # fog
30
+ add_deprecated_config :fog_provider
26
31
  add_config :fog_attributes
27
32
  add_config :fog_credentials
28
33
  add_config :fog_directory
29
34
  add_config :fog_public
30
35
  add_config :fog_authenticated_url_expiration
31
36
  add_config :fog_use_ssl_for_aws
37
+ add_config :fog_aws_accelerate
32
38
 
33
39
  # Mounting
34
40
  add_config :ignore_integrity_errors
@@ -38,6 +44,9 @@ module CarrierWave
38
44
  add_config :validate_processing
39
45
  add_config :validate_download
40
46
  add_config :mount_on
47
+ add_config :cache_only
48
+ add_config :download_retry_count
49
+ add_config :download_retry_wait_time
41
50
 
42
51
  # set default values
43
52
  reset_config
@@ -69,36 +78,66 @@ module CarrierWave
69
78
  # storage MyCustomStorageEngine
70
79
  #
71
80
  def storage(storage = nil)
72
- if storage
73
- self._storage = storage.is_a?(Symbol) ? eval(storage_engines[storage]) : storage
81
+ case storage
82
+ when Symbol
83
+ if (storage_engine = storage_engines[storage])
84
+ self._storage = eval storage_engine
85
+ else
86
+ raise CarrierWave::UnknownStorageError, "Unknown storage: #{storage}"
87
+ end
88
+ when nil
89
+ storage
90
+ else
91
+ self._storage = storage
74
92
  end
75
93
  _storage
76
94
  end
77
95
  alias_method :storage=, :storage
78
96
 
97
+ ##
98
+ # Sets the cache storage engine to be used when storing cache files with this uploader.
99
+ # Same as .storage except for required methods being #cache!(CarrierWave::SanitizedFile),
100
+ # #retrieve_from_cache! and #delete_dir!.
101
+ #
102
+ # === Parameters
103
+ #
104
+ # [storage (Symbol, Class)] The cache storage engine to use for this uploader
105
+ #
106
+ # === Returns
107
+ #
108
+ # [Class] the cache storage engine to be used with this uploader
109
+ #
110
+ # === Examples
111
+ #
112
+ # cache_storage :file
113
+ # cache_storage CarrierWave::Storage::File
114
+ # cache_storage MyCustomStorageEngine
115
+ #
116
+ def cache_storage(storage = false)
117
+ unless storage == false
118
+ self._cache_storage = storage.is_a?(Symbol) ? eval(storage_engines[storage]) : storage
119
+ end
120
+ _cache_storage
121
+ end
122
+ alias_method :cache_storage=, :cache_storage
123
+
79
124
  def add_config(name)
80
125
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
81
- def self.eager_load_fog(fog_credentials)
82
- # see #1198. This will hopefully no longer be necessary after fog 2.0
83
- Fog::Storage.new(fog_credentials) if fog_credentials.present?
84
- end
126
+ @#{name} = nil
85
127
 
86
128
  def self.#{name}(value=nil)
87
- @#{name} = value if value
88
- eager_load_fog(value) if value && '#{name}' == 'fog_credentials'
129
+ @#{name} = value unless value.nil?
89
130
  return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
90
131
  name = superclass.#{name}
91
- return nil if name.nil? && !instance_variable_defined?("@#{name}")
132
+ return nil if name.nil? && !instance_variable_defined?(:@#{name})
92
133
  @#{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
93
134
  end
94
135
 
95
136
  def self.#{name}=(value)
96
- eager_load_fog(value) if '#{name}' == 'fog_credentials'
97
137
  @#{name} = value
98
138
  end
99
139
 
100
140
  def #{name}=(value)
101
- self.class.eager_load_fog(value) if '#{name}' == 'fog_credentials'
102
141
  @#{name} = value
103
142
  end
104
143
 
@@ -107,13 +146,33 @@ module CarrierWave
107
146
  value = self.class.#{name} unless instance_variable_defined?(:@#{name})
108
147
  if value.instance_of?(Proc)
109
148
  value.arity >= 1 ? value.call(self) : value.call
110
- else
149
+ else
111
150
  value
112
151
  end
113
152
  end
114
153
  RUBY
115
154
  end
116
155
 
156
+ def add_deprecated_config(name)
157
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
158
+ def self.#{name}(value=nil)
159
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
160
+ end
161
+
162
+ def self.#{name}=(value)
163
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
164
+ end
165
+
166
+ def #{name}=(value)
167
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
168
+ end
169
+
170
+ def #{name}
171
+ ActiveSupport::Deprecation.warn "##{name} is deprecated and has no effect"
172
+ end
173
+ RUBY
174
+ end
175
+
117
176
  def configure
118
177
  yield self
119
178
  end
@@ -123,24 +182,28 @@ module CarrierWave
123
182
  #
124
183
  def reset_config
125
184
  configure do |config|
126
- config.permissions = 0644
127
- config.directory_permissions = 0755
185
+ config.permissions = 0o644
186
+ config.directory_permissions = 0o755
128
187
  config.storage_engines = {
129
188
  :file => "CarrierWave::Storage::File",
130
189
  :fog => "CarrierWave::Storage::Fog"
131
190
  }
132
191
  config.storage = :file
192
+ config.cache_storage = nil
133
193
  config.fog_attributes = {}
134
194
  config.fog_credentials = {}
135
195
  config.fog_public = true
136
196
  config.fog_authenticated_url_expiration = 600
137
197
  config.fog_use_ssl_for_aws = true
198
+ config.fog_aws_accelerate = false
138
199
  config.store_dir = 'uploads'
139
200
  config.cache_dir = 'uploads/tmp'
140
201
  config.delete_tmp_file_after_storage = true
141
202
  config.move_to_cache = false
142
203
  config.move_to_store = false
143
204
  config.remove_previously_stored_files_after_update = true
205
+ config.downloader = CarrierWave::Downloader::Base
206
+ config.force_extension = false
144
207
  config.ignore_integrity_errors = true
145
208
  config.ignore_processing_errors = true
146
209
  config.ignore_download_errors = true
@@ -151,6 +214,8 @@ module CarrierWave
151
214
  config.base_path = CarrierWave.base_path
152
215
  config.enable_processing = true
153
216
  config.ensure_multipart_form = true
217
+ config.download_retry_count = 0
218
+ config.download_retry_wait_time = 5
154
219
  end
155
220
  end
156
221
  end
@@ -158,4 +223,3 @@ module CarrierWave
158
223
  end
159
224
  end
160
225
  end
161
-