carrierwave 2.2.5 → 3.0.0.beta

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04ecbb3b2d0424203756bda1f73e89bdf32d52f3fbcda13b979e9904d1d4f2c9
4
- data.tar.gz: e7474ccefff230df0f9d6564825c63acd3176c2a37e2a4b66a797a864d610f74
3
+ metadata.gz: 5777918bb6d5edc1006f2f0bfb10f47e1576bc9b4dcbabbc00d42a0cbd59a93f
4
+ data.tar.gz: 3f9a90b9c715e67c753909de2ee5a4c9ff5bd8c51ad5e7ed4730a128690c6a34
5
5
  SHA512:
6
- metadata.gz: 9a2cff0c002d2d31c1a61bf4d7158a4d648a88bb69843092130bfc48cf2026386becdc707e00f6eff379929ff88f7c20929fa67310e874fe3b4ad3197793b269
7
- data.tar.gz: fe8c49e5858818fd2e8f3e271ba884a839d627aefe420f1c4e5d63c00601b4c2e71cb07cdb77ccf0758121173b932c4a12b95762b2b60ee6d0930c9a290f375a
6
+ metadata.gz: c0ff141f52c94d57863789c6255629301317182991e5676394efde778122645da9e38fa9bcac926886e8e8d22d778250803dd8fdd2437d5f4ce3c97dedb2cd3a
7
+ data.tar.gz: 4130502d8c30bebf77189f9ca281f2b1cdf285bc6445a260ea3b49bd6597f0e7becad9983d33388eab0ca8f8fcb53e1ae0ebc1b7978c1cca62268e324cb42a2e
data/README.md CHANGED
@@ -30,14 +30,11 @@ $ gem install carrierwave
30
30
  In Rails, add it to your Gemfile:
31
31
 
32
32
  ```ruby
33
- gem 'carrierwave', '~> 2.0'
33
+ gem 'carrierwave', '>= 3.0.0.beta', '< 4.0'
34
34
  ```
35
35
 
36
36
  Finally, restart the server to apply the changes.
37
37
 
38
- As of version 2.0, CarrierWave requires Rails 5.0 or higher and Ruby 2.2
39
- or higher. If you're on Rails 4, you should use 1.x.
40
-
41
38
  ## Getting Started
42
39
 
43
40
  Start off by generating an uploader:
@@ -531,6 +528,16 @@ failures automatically with attribute validation errors. If you aren't, or you
531
528
  disable CarrierWave's `validate_download` option, you'll need to handle those
532
529
  errors yourself.
533
530
 
531
+ ### Retry option for download from remote location
532
+ If you want to retry the download from the Remote URL, enable the download_retry_count option, an error occurs during download, it will try to execute the specified number of times every 5 second.
533
+ This option is effective when the remote destination is unstable.
534
+
535
+ ```rb
536
+ CarrierWave.configure do |config|
537
+ config.download_retry_count = 3 # Default 0
538
+ end
539
+ ```
540
+
534
541
  ## Providing a default URL
535
542
 
536
543
  In many cases, especially when working with images, it might be a good idea to
@@ -951,7 +958,7 @@ See the MiniMagick site for more details:
951
958
 
952
959
  https://github.com/minimagick/minimagick
953
960
 
954
- And the ImageMagick command line options for more for whats on offer:
961
+ And the ImageMagick command line options for more for what's on offer:
955
962
 
956
963
  http://www.imagemagick.org/script/command-line-options.php
957
964
 
@@ -1000,8 +1007,7 @@ errors:
1000
1007
  extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
1001
1008
  content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
1002
1009
  content_type_denylist_error: "You are not allowed to upload %{content_type} files"
1003
- rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
1004
- mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
1010
+ processing_error: "Failed to manipulate, maybe it is not an image?"
1005
1011
  min_size_error: "File size should be greater than %{min_size}"
1006
1012
  max_size_error: "File size should be less than %{max_size}"
1007
1013
  ```
@@ -1066,6 +1072,30 @@ class User
1066
1072
  end
1067
1073
  ```
1068
1074
 
1075
+ ## Uploader Callbacks
1076
+
1077
+ In addition to the ActiveRecord callbacks described above, uploaders also have callbacks.
1078
+
1079
+ ```ruby
1080
+ class MyUploader < ::CarrierWave::Uploader::Base
1081
+ before :remove, :log_removal
1082
+ private
1083
+ def log_removal
1084
+ ::Rails.logger.info(format('Deleting file on S3: %s', @file))
1085
+ end
1086
+ end
1087
+ ```
1088
+
1089
+ Uploader callbacks can be `before` or `after` the following events:
1090
+
1091
+ ```
1092
+ cache
1093
+ process
1094
+ remove
1095
+ retrieve_from_cache
1096
+ store
1097
+ ```
1098
+
1069
1099
  ## Contributing to CarrierWave
1070
1100
 
1071
1101
  See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
@@ -21,6 +21,7 @@ module CarrierWave
21
21
  # [remote_headers (Hash)] Request headers
22
22
  #
23
23
  def download(url, remote_headers = {})
24
+ @current_download_retry_count = 0
24
25
  headers = remote_headers.
25
26
  reverse_merge('User-Agent' => "CarrierWave/#{CarrierWave::VERSION}")
26
27
  uri = process_uri(url.to_s)
@@ -42,7 +43,13 @@ module CarrierWave
42
43
  response.value
43
44
  end
44
45
  rescue StandardError => e
45
- raise CarrierWave::DownloadError, "could not download file: #{e.message}"
46
+ if @current_download_retry_count < @uploader.download_retry_count
47
+ @current_download_retry_count += 1
48
+ sleep 5
49
+ retry
50
+ else
51
+ raise CarrierWave::DownloadError, "could not download file: #{e.message}"
52
+ end
46
53
  end
47
54
  CarrierWave::Downloader::RemoteFile.new(response)
48
55
  end
@@ -8,7 +8,10 @@ module CarrierWave
8
8
  when String
9
9
  @file = StringIO.new(file)
10
10
  when Net::HTTPResponse
11
- @file = StringIO.new(file.body)
11
+ body = file.body
12
+ raise CarrierWave::DownloadError, 'could not download file: No Content' if body.nil?
13
+
14
+ @file = StringIO.new(body)
12
15
  @content_type = file.content_type
13
16
  @headers = file
14
17
  @uri = file.uri
@@ -30,9 +33,10 @@ module CarrierWave
30
33
 
31
34
  def original_filename
32
35
  filename = filename_from_header || filename_from_uri
33
- mime_type = MiniMime.lookup_by_content_type(content_type)
36
+ mime_type = Marcel::TYPES[content_type]
34
37
  unless File.extname(filename).present? || mime_type.blank?
35
- filename = "#{filename}.#{mime_type.extension}"
38
+ extension = mime_type[0].first
39
+ filename = "#{filename}.#{extension}"
36
40
  end
37
41
  filename
38
42
  end
@@ -8,8 +8,6 @@ en:
8
8
  extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
9
9
  content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
10
10
  content_type_denylist_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?"
12
- mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
13
- vips_processing_error: "Failed to manipulate with vips, maybe it is not an image? Original Error: %{e}"
11
+ processing_error: "Failed to manipulate, maybe it is not an image?"
14
12
  min_size_error: "File size should be greater than %{min_size}"
15
13
  max_size_error: "File size should be less than %{max_size}"
@@ -174,8 +174,12 @@ module CarrierWave
174
174
  return if frozen?
175
175
  mounter = _mounter(:#{column})
176
176
 
177
- mounter.clear! if mounter.remove?
178
- write_uploader(mounter.serialization_column, mounter.identifiers.first)
177
+ if mounter.remove?
178
+ mounter.clear!
179
+ write_uploader(mounter.serialization_column, nil)
180
+ elsif mounter.identifiers.first
181
+ write_uploader(mounter.serialization_column, mounter.identifiers.first)
182
+ end
179
183
  end
180
184
 
181
185
  def #{column}_identifier
@@ -195,14 +199,25 @@ module CarrierWave
195
199
  end
196
200
 
197
201
  def store_previous_changes_for_#{column}
198
- attribute_changes = ::ActiveRecord.version.to_s.to_f >= 5.1 ? saved_changes : changes
199
- @_previous_changes_for_#{column} = attribute_changes[_mounter(:#{column}).serialization_column]
202
+ @_previous_changes_for_#{column} = saved_changes[_mounter(:#{column}).serialization_column]
203
+ end
204
+
205
+ def reset_previous_changes_for_#{column}
206
+ # We use this variable to pass information from save time to commit time.
207
+ # Make sure this doesn't persist across multiple transactions
208
+ @_previous_changes_for_#{column} = nil
200
209
  end
201
210
 
202
211
  def remove_previously_stored_#{column}
203
212
  before, after = @_previous_changes_for_#{column}
204
213
  _mounter(:#{column}).remove_previous([before], [after])
205
214
  end
215
+
216
+ def remove_rolled_back_#{column}
217
+ before, after = @_previous_changes_for_#{column}
218
+ _mounter(:#{column}).remove_previous([after], [before])
219
+ @_previous_changes_for_#{column} = nil
220
+ end
206
221
  RUBY
207
222
  end
208
223
 
@@ -338,8 +353,12 @@ module CarrierWave
338
353
  return if frozen?
339
354
  mounter = _mounter(:#{column})
340
355
 
341
- mounter.clear! if mounter.remove?
342
- write_uploader(mounter.serialization_column, mounter.identifiers.presence)
356
+ if mounter.remove?
357
+ mounter.clear!
358
+ write_uploader(mounter.serialization_column, nil)
359
+ elsif mounter.identifiers.any?
360
+ write_uploader(mounter.serialization_column, mounter.identifiers)
361
+ end
343
362
  end
344
363
 
345
364
  def #{column}_identifiers
@@ -347,13 +366,26 @@ module CarrierWave
347
366
  end
348
367
 
349
368
  def store_previous_changes_for_#{column}
350
- attribute_changes = ::ActiveRecord.version.to_s.to_f >= 5.1 ? saved_changes : changes
351
- @_previous_changes_for_#{column} = attribute_changes[_mounter(:#{column}).serialization_column]
369
+ @_previous_changes_for_#{column} = saved_changes[_mounter(:#{column}).serialization_column]
370
+ end
371
+
372
+ def reset_previous_changes_for_#{column}
373
+ # We use this variable to pass information from save time to commit time.
374
+ # Make sure this doesn't persist across multiple transactions
375
+ @_previous_changes_for_#{column} = nil
352
376
  end
353
377
 
354
378
  def remove_previously_stored_#{column}
379
+ return unless @_previous_changes_for_#{column}
355
380
  _mounter(:#{column}).remove_previous(*@_previous_changes_for_#{column})
356
381
  end
382
+
383
+ def remove_rolled_back_#{column}
384
+ return unless @_previous_changes_for_#{column}
385
+ before, after = @_previous_changes_for_#{column}
386
+ _mounter(:#{column}).remove_previous(after, before)
387
+ @_previous_changes_for_#{column} = nil
388
+ end
357
389
  RUBY
358
390
  end
359
391
 
@@ -92,7 +92,7 @@ module CarrierWave
92
92
  @remote_urls = urls
93
93
 
94
94
  clear_unstaged
95
- urls.zip(remote_request_headers || []).each do |url, header|
95
+ urls.zip(remote_request_headers || []) do |url, header|
96
96
  handle_error do
97
97
  uploader = blank_uploader
98
98
  uploader.download!(url, header || {})
@@ -56,12 +56,15 @@ module CarrierWave
56
56
  validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
57
57
  validates_download_of column if uploader_option(column.to_sym, :validate_download)
58
58
 
59
+ after_save :"store_#{column}!"
59
60
  before_save :"write_#{column}_identifier"
60
- after_save :"store_previous_changes_for_#{column}"
61
61
  after_commit :"remove_#{column}!", :on => :destroy
62
62
  after_commit :"mark_remove_#{column}_false", :on => :update
63
+
64
+ after_save :"store_previous_changes_for_#{column}"
65
+ after_commit :"reset_previous_changes_for_#{column}"
63
66
  after_commit :"remove_previously_stored_#{column}", :on => :update
64
- after_commit :"store_#{column}!", :on => [:create, :update]
67
+ after_rollback :"remove_rolled_back_#{column}"
65
68
 
66
69
  mod = Module.new
67
70
  prepend mod
@@ -88,7 +88,7 @@ module CarrierWave
88
88
  #
89
89
  # === Parameters
90
90
  #
91
- # [format (#to_s)] an abreviation of the format
91
+ # [format (#to_s)] an abbreviation of the format
92
92
  #
93
93
  # === Yields
94
94
  #
@@ -263,8 +263,8 @@ module CarrierWave
263
263
  FileUtils.mv image.path, current_path
264
264
 
265
265
  image.run_command("identify", current_path)
266
- rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
267
- message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e)
266
+ rescue ::MiniMagick::Error, ::MiniMagick::Invalid
267
+ message = I18n.translate(:"errors.messages.processing_error")
268
268
  raise CarrierWave::ProcessingError, message
269
269
  ensure
270
270
  image.destroy! if image
@@ -306,11 +306,11 @@ module CarrierWave
306
306
 
307
307
  if File.extname(result.path) != File.extname(current_path)
308
308
  move_to = current_path.chomp(File.extname(current_path)) + File.extname(result.path)
309
- file.content_type = ::MiniMime.lookup_by_filename(move_to).content_type
309
+ file.content_type = Marcel::Magic.by_path(move_to).try(:type)
310
310
  file.move_to(move_to, permissions, directory_permissions)
311
311
  end
312
- rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
313
- message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e)
312
+ rescue ::MiniMagick::Error, ::MiniMagick::Invalid
313
+ message = I18n.translate(:"errors.messages.processing_error")
314
314
  raise CarrierWave::ProcessingError, message
315
315
  end
316
316
 
@@ -109,7 +109,7 @@ module CarrierWave
109
109
  #
110
110
  # === Parameters
111
111
  #
112
- # [format (#to_s)] an abreviation of the format
112
+ # [format (#to_s)] an abbreviation of the format
113
113
  #
114
114
  # === Yields
115
115
  #
@@ -363,15 +363,15 @@ module CarrierWave
363
363
  if options[:format] || @format
364
364
  frames.write("#{options[:format] || @format}:#{current_path}", &write_block)
365
365
  move_to = current_path.chomp(File.extname(current_path)) + ".#{options[:format] || @format}"
366
- file.content_type = ::MiniMime.lookup_by_filename(move_to).content_type
366
+ file.content_type = Marcel::Magic.by_path(move_to).try(:type)
367
367
  file.move_to(move_to, permissions, directory_permissions)
368
368
  else
369
369
  frames.write(current_path, &write_block)
370
370
  end
371
371
 
372
372
  destroy_image(frames)
373
- rescue ::Magick::ImageMagickError => e
374
- raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.rmagick_processing_error", :e => e)
373
+ rescue ::Magick::ImageMagickError
374
+ raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.processing_error")
375
375
  end
376
376
 
377
377
  private
@@ -259,11 +259,11 @@ module CarrierWave
259
259
 
260
260
  if File.extname(result.path) != File.extname(current_path)
261
261
  move_to = current_path.chomp(File.extname(current_path)) + File.extname(result.path)
262
- file.content_type = ::MiniMime.lookup_by_filename(move_to).content_type
262
+ file.content_type = Marcel::Magic.by_path(move_to).try(:type)
263
263
  file.move_to(move_to, permissions, directory_permissions)
264
264
  end
265
- rescue ::Vips::Error => e
266
- message = I18n.translate(:"errors.messages.vips_processing_error", :e => e)
265
+ rescue ::Vips::Error
266
+ message = I18n.translate(:"errors.messages.processing_error")
267
267
  raise CarrierWave::ProcessingError, message
268
268
  end
269
269
 
@@ -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
 
@@ -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
  #
@@ -159,7 +136,7 @@ module CarrierWave
159
136
  else
160
137
  @file.try(:rewind)
161
138
  @content = @file.read
162
- @file.try(:close) unless @file.try(:closed?)
139
+ @file.try(:close) unless @file.class.ancestors.include?(::StringIO) || @file.try(:closed?)
163
140
  @content
164
141
  end
165
142
  end
@@ -261,8 +238,8 @@ module CarrierWave
261
238
  def content_type
262
239
  @content_type ||=
263
240
  existing_content_type ||
264
- marcel_magic_content_type ||
265
- mini_mime_content_type
241
+ marcel_magic_by_mime_type ||
242
+ marcel_magic_by_path
266
243
  end
267
244
 
268
245
  ##
@@ -314,6 +291,7 @@ module CarrierWave
314
291
 
315
292
  # Sanitize the filename, to prevent hacking
316
293
  def sanitize(name)
294
+ name = name.scrub
317
295
  name = name.tr("\\", "/") # work-around for IE
318
296
  name = File.basename(name)
319
297
  name = name.gsub(sanitize_regexp,"_")
@@ -328,43 +306,27 @@ module CarrierWave
328
306
  end
329
307
  end
330
308
 
331
- def marcel_magic_content_type
332
- if path
333
- type = File.open(path) do |file|
334
- Marcel::Magic.by_magic(file).try(:type)
335
- end
309
+ def marcel_magic_by_mime_type
310
+ return unless path
336
311
 
337
- if type.nil?
338
- type = Marcel::Magic.by_path(path).try(:type)
339
- type = 'invalid/invalid' unless type.nil? || type.start_with?('text/')
340
- end
312
+ type = File.open(path) do |file|
313
+ Marcel::Magic.by_magic(file).try(:type)
314
+ end
341
315
 
342
- type
316
+ if type.nil?
317
+ type = Marcel::Magic.by_path(path).try(:type)
318
+ type = 'invalid/invalid' unless type.nil? || type.start_with?('text/') || type.start_with?('application/json')
343
319
  end
320
+
321
+ type
344
322
  rescue Errno::ENOENT
345
323
  nil
346
324
  end
347
325
 
348
- def mini_mime_content_type
326
+ def marcel_magic_by_path
349
327
  return unless path
350
- mime_type = ::MiniMime.lookup_by_filename(path)
351
- @content_type = (mime_type && mime_type.content_type).to_s
352
- end
353
328
 
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
364
- end
365
- end
366
- return filename, "" # In case we weren't able to split the extension
329
+ Marcel::Magic.by_path(path).to_s
367
330
  end
368
-
369
331
  end # SanitizedFile
370
332
  end # CarrierWave
@@ -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 overriden to return true, then store!() uses move_to(),
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
@@ -110,7 +110,7 @@ module CarrierWave
110
110
 
111
111
  def clean_cache!(seconds)
112
112
  Dir.glob(::File.expand_path(::File.join(uploader.cache_dir, '*'), CarrierWave.root)).each do |dir|
113
- # generate_cache_id returns key formated TIMEINT-PID(-COUNTER)-RND
113
+ # generate_cache_id returns key formatted TIMEINT-PID(-COUNTER)-RND
114
114
  time = dir.scan(/(\d+)-\d+-\d+(?:-\d+)?/).first.map(&:to_i)
115
115
  time = Time.at(*time)
116
116
  if time < (Time.now.utc - seconds)
@@ -146,7 +146,7 @@ module CarrierWave
146
146
  :key => uploader.fog_directory,
147
147
  :public => uploader.fog_public
148
148
  ).files.all(:prefix => uploader.cache_dir).each do |file|
149
- # generate_cache_id returns key formated TIMEINT-PID(-COUNTER)-RND
149
+ # generate_cache_id returns key formatted TIMEINT-PID(-COUNTER)-RND
150
150
  matched = file.key.match(/(\d+)-\d+-\d+(?:-\d+)?/)
151
151
  next unless matched
152
152
  time = Time.at(matched[1].to_i)
@@ -165,6 +165,7 @@ module CarrierWave
165
165
  DEFAULT_S3_REGION = 'us-east-1'
166
166
 
167
167
  include CarrierWave::Utilities::Uri
168
+ include CarrierWave::Utilities::FileName
168
169
 
169
170
  ##
170
171
  # Current local path to file
@@ -258,18 +259,6 @@ module CarrierWave
258
259
  end
259
260
  end
260
261
 
261
- ##
262
- # Return extension of file
263
- #
264
- # === Returns
265
- #
266
- # [String] extension of file or nil if the file has no extension
267
- #
268
- def extension
269
- path_elements = path.split('.')
270
- path_elements.last if path_elements.size > 1
271
- end
272
-
273
262
  ##
274
263
  # deprecated: All attributes from file (includes headers)
275
264
  #
@@ -409,7 +398,7 @@ module CarrierWave
409
398
  end
410
399
 
411
400
  ##
412
- # Return url to file, if avaliable
401
+ # Return url to file, if available
413
402
  #
414
403
  # === Returns
415
404
  #
@@ -451,7 +440,7 @@ module CarrierWave
451
440
  # @return [CarrierWave::Storage::Fog::File] the location where the file will be stored.
452
441
  #
453
442
  def copy_to(new_path)
454
- connection.copy_object(@uploader.fog_directory, file.key, @uploader.fog_directory, new_path, copy_options)
443
+ file.copy(@uploader.fog_directory, new_path, copy_options)
455
444
  CarrierWave::Storage::Fog::File.new(@uploader, @base, new_path)
456
445
  end
457
446
 
@@ -498,7 +487,7 @@ module CarrierWave
498
487
  def copy_options
499
488
  options = {}
500
489
  options.merge!(acl_header) if acl_header.present?
501
- options['Content-Type'] ||= content_type if content_type
490
+ options[fog_provider == "Google" ? :content_type : 'Content-Type'] ||= content_type if content_type
502
491
  options.merge(@uploader.fog_attributes)
503
492
  end
504
493
 
@@ -110,7 +110,7 @@ module CarrierWave
110
110
  #
111
111
  # By default, cache!() uses copy_to(), which operates by copying the file
112
112
  # to the cache, then deleting the original file. If move_to_cache() is
113
- # overriden to return true, then cache!() uses move_to(), which simply
113
+ # overridden to return true, then cache!() uses move_to(), which simply
114
114
  # moves the file to the cache. Useful for large files.
115
115
  #
116
116
  # === Parameters
@@ -44,6 +44,7 @@ module CarrierWave
44
44
  add_config :validate_download
45
45
  add_config :mount_on
46
46
  add_config :cache_only
47
+ add_config :download_retry_count
47
48
 
48
49
  # set default values
49
50
  reset_config
@@ -210,6 +211,7 @@ module CarrierWave
210
211
  config.base_path = CarrierWave.base_path
211
212
  config.enable_processing = true
212
213
  config.ensure_multipart_form = true
214
+ config.download_retry_count = 0
213
215
  end
214
216
  end
215
217
  end
@@ -1,10 +1,10 @@
1
1
  module CarrierWave
2
2
  module Uploader
3
- module ContentTypeWhitelist
3
+ module ContentTypeAllowlist
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- before :cache, :check_content_type_whitelist!
7
+ before :cache, :check_content_type_allowlist!
8
8
  end
9
9
 
10
10
  ##
@@ -29,32 +29,34 @@ module CarrierWave
29
29
  # end
30
30
  #
31
31
  def content_type_allowlist
32
- if respond_to?(:content_type_whitelist)
33
- ActiveSupport::Deprecation.warn "#content_type_whitelist is deprecated, use #content_type_allowlist instead." unless instance_variable_defined?(:@content_type_whitelist_warned)
34
- @content_type_whitelist_warned = true
35
- content_type_whitelist
36
- end
37
32
  end
38
33
 
39
34
  private
40
35
 
41
- def check_content_type_whitelist!(new_file)
42
- return unless content_type_allowlist
36
+ def check_content_type_allowlist!(new_file)
37
+ allowlist = content_type_allowlist
38
+ if !allowlist && respond_to?(:content_type_whitelist) && content_type_whitelist
39
+ ActiveSupport::Deprecation.warn "#content_type_whitelist is deprecated, use #content_type_allowlist instead." unless instance_variable_defined?(:@content_type_whitelist_warned)
40
+ @content_type_whitelist_warned = true
41
+ allowlist = content_type_whitelist
42
+ end
43
+
44
+ return unless allowlist
43
45
 
44
46
  content_type = new_file.content_type
45
- if !whitelisted_content_type?(content_type)
46
- raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_whitelist_error", content_type: content_type,
47
- allowed_types: Array(content_type_allowlist).join(", "), default: :"errors.messages.content_type_allowlist_error")
47
+ if !allowlisted_content_type?(allowlist, content_type)
48
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_allowlist_error", content_type: content_type,
49
+ allowed_types: Array(allowlist).join(", "), default: :"errors.messages.content_type_whitelist_error")
48
50
  end
49
51
  end
50
52
 
51
- def whitelisted_content_type?(content_type)
52
- Array(content_type_allowlist).any? do |item|
53
+ def allowlisted_content_type?(allowlist, content_type)
54
+ Array(allowlist).any? do |item|
53
55
  item = Regexp.quote(item) if item.class != Regexp
54
- content_type =~ /\A#{item}/
56
+ content_type =~ /#{item}/
55
57
  end
56
58
  end
57
59
 
58
- end # ContentTypeWhitelist
60
+ end # ContentTypeAllowlist
59
61
  end # Uploader
60
62
  end # CarrierWave
@@ -1,10 +1,10 @@
1
1
  module CarrierWave
2
2
  module Uploader
3
- module ContentTypeBlacklist
3
+ module ContentTypeDenylist
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- before :cache, :check_content_type_blacklist!
7
+ before :cache, :check_content_type_denylist!
8
8
  end
9
9
 
10
10
  ##
@@ -29,29 +29,34 @@ module CarrierWave
29
29
  # end
30
30
  #
31
31
  def content_type_denylist
32
- if respond_to?(:content_type_blacklist)
32
+ end
33
+
34
+ private
35
+
36
+ def check_content_type_denylist!(new_file)
37
+ denylist = content_type_denylist
38
+ if !denylist && respond_to?(:content_type_blacklist) && content_type_blacklist
33
39
  ActiveSupport::Deprecation.warn "#content_type_blacklist is deprecated, use #content_type_denylist instead." unless instance_variable_defined?(:@content_type_blacklist_warned)
34
40
  @content_type_blacklist_warned = true
35
- content_type_blacklist
41
+ denylist = content_type_blacklist
36
42
  end
37
- end
38
43
 
39
- private
44
+ return unless denylist
40
45
 
41
- def check_content_type_blacklist!(new_file)
42
- return unless content_type_denylist
46
+ ActiveSupport::Deprecation.warn "Use of #content_type_denylist is deprecated for the security reason, use #content_type_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@content_type_denylist_warned)
47
+ @content_type_denylist_warned = true
43
48
 
44
49
  content_type = new_file.content_type
45
- if blacklisted_content_type?(content_type)
46
- raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_blacklist_error",
47
- content_type: content_type, default: :"errors.messages.content_type_denylist_error")
50
+ if denylisted_content_type?(denylist, content_type)
51
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_denylist_error",
52
+ content_type: content_type, default: :"errors.messages.content_type_blacklist_error")
48
53
  end
49
54
  end
50
55
 
51
- def blacklisted_content_type?(content_type)
52
- Array(content_type_denylist).any? { |item| content_type =~ /#{item}/ }
56
+ def denylisted_content_type?(denylist, content_type)
57
+ Array(denylist).any? { |item| content_type =~ /#{item}/ }
53
58
  end
54
59
 
55
- end # ContentTypeBlacklist
60
+ end # ContentTypeDenylist
56
61
  end # Uploader
57
62
  end # CarrierWave
@@ -1,10 +1,10 @@
1
1
  module CarrierWave
2
2
  module Uploader
3
- module ExtensionWhitelist
3
+ module ExtensionAllowlist
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- before :cache, :check_extension_whitelist!
7
+ before :cache, :check_extension_allowlist!
8
8
  end
9
9
 
10
10
  ##
@@ -32,30 +32,32 @@ module CarrierWave
32
32
  # end
33
33
  #
34
34
  def extension_allowlist
35
- if respond_to?(:extension_whitelist)
36
- ActiveSupport::Deprecation.warn "#extension_whitelist is deprecated, use #extension_allowlist instead." unless instance_variable_defined?(:@extension_whitelist_warned)
37
- @extension_whitelist_warned = true
38
- extension_whitelist
39
- end
40
35
  end
41
36
 
42
37
  private
43
38
 
44
- def check_extension_whitelist!(new_file)
45
- return unless extension_allowlist
39
+ def check_extension_allowlist!(new_file)
40
+ allowlist = extension_allowlist
41
+ if !allowlist && respond_to?(:extension_whitelist) && extension_whitelist
42
+ ActiveSupport::Deprecation.warn "#extension_whitelist is deprecated, use #extension_allowlist instead." unless instance_variable_defined?(:@extension_whitelist_warned)
43
+ @extension_whitelist_warned = true
44
+ allowlist = extension_whitelist
45
+ end
46
+
47
+ return unless allowlist
46
48
 
47
49
  extension = new_file.extension.to_s
48
- if !whitelisted_extension?(extension)
50
+ if !allowlisted_extension?(allowlist, extension)
49
51
  # Look for whitelist first, then fallback to allowlist
50
- raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_whitelist_error", extension: new_file.extension.inspect,
51
- allowed_types: Array(extension_allowlist).join(", "), default: :"errors.messages.extension_allowlist_error")
52
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_allowlist_error", extension: new_file.extension.inspect,
53
+ allowed_types: Array(allowlist).join(", "), default: :"errors.messages.extension_whitelist_error")
52
54
  end
53
55
  end
54
56
 
55
- def whitelisted_extension?(extension)
57
+ def allowlisted_extension?(allowlist, extension)
56
58
  downcase_extension = extension.downcase
57
- Array(extension_allowlist).any? { |item| downcase_extension =~ /\A#{item}\z/i }
59
+ Array(allowlist).any? { |item| downcase_extension =~ /\A#{item}\z/i }
58
60
  end
59
- end # ExtensionWhitelist
61
+ end # ExtensionAllowlist
60
62
  end # Uploader
61
63
  end # CarrierWave
@@ -1,10 +1,10 @@
1
1
  module CarrierWave
2
2
  module Uploader
3
- module ExtensionBlacklist
3
+ module ExtensionDenylist
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- before :cache, :check_extension_blacklist!
7
+ before :cache, :check_extension_denylist!
8
8
  end
9
9
 
10
10
  ##
@@ -32,27 +32,32 @@ module CarrierWave
32
32
  # end
33
33
  #
34
34
  def extension_denylist
35
- if respond_to?(:extension_blacklist)
35
+ end
36
+
37
+ private
38
+
39
+ def check_extension_denylist!(new_file)
40
+ denylist = extension_denylist
41
+ if !denylist && respond_to?(:extension_blacklist) && extension_blacklist
36
42
  ActiveSupport::Deprecation.warn "#extension_blacklist is deprecated, use #extension_denylist instead." unless instance_variable_defined?(:@extension_blacklist_warned)
37
43
  @extension_blacklist_warned = true
38
- extension_blacklist
44
+ denylist = extension_blacklist
39
45
  end
40
- end
41
46
 
42
- private
47
+ return unless denylist
43
48
 
44
- def check_extension_blacklist!(new_file)
45
- return unless extension_denylist
49
+ ActiveSupport::Deprecation.warn "Use of #extension_denylist is deprecated for the security reason, use #extension_allowlist instead to explicitly state what are safe to accept" unless instance_variable_defined?(:@extension_denylist_warned)
50
+ @extension_denylist_warned = true
46
51
 
47
52
  extension = new_file.extension.to_s
48
- if blacklisted_extension?(extension)
49
- raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_blacklist_error", extension: new_file.extension.inspect,
50
- prohibited_types: Array(extension_denylist).join(", "), default: :"errors.messages.extension_denylist_error")
53
+ if denylisted_extension?(denylist, extension)
54
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_denylist_error", extension: new_file.extension.inspect,
55
+ prohibited_types: Array(extension_denylist).join(", "), default: :"errors.messages.extension_blacklist_error")
51
56
  end
52
57
  end
53
58
 
54
- def blacklisted_extension?(extension)
55
- Array(extension_denylist).any? { |item| extension =~ /\A#{item}\z/i }
59
+ def denylisted_extension?(denylist, extension)
60
+ Array(denylist).any? { |item| extension =~ /\A#{item}\z/i }
56
61
  end
57
62
  end
58
63
  end
@@ -18,7 +18,7 @@ module CarrierWave
18
18
  # Adds a processor callback which applies operations as a file is uploaded.
19
19
  # The argument may be the name of any method of the uploader, expressed as a symbol,
20
20
  # or a list of such methods, or a hash where the key is a method and the value is
21
- # an array of arguments to call the method with
21
+ # an array of arguments to call the method with. Also accepts an :if or :unless condition
22
22
  #
23
23
  # === Parameters
24
24
  #
@@ -31,6 +31,7 @@ module CarrierWave
31
31
  # process :sepiatone, :vignette
32
32
  # process :scale => [200, 200]
33
33
  # process :scale => [200, 200], :if => :image?
34
+ # process :scale => [200, 200], :unless => :disallowed_image_type?
34
35
  # process :sepiatone, :if => :image?
35
36
  #
36
37
  # def sepiatone
@@ -49,6 +50,10 @@ module CarrierWave
49
50
  # ...
50
51
  # end
51
52
  #
53
+ # def disallowed_image_type?
54
+ # ...
55
+ # end
56
+ #
52
57
  # end
53
58
  #
54
59
  def process(*args)
@@ -57,12 +62,12 @@ module CarrierWave
57
62
  hash.merge!(arg)
58
63
  end
59
64
 
60
- condition = new_processors.delete(:if)
65
+ condition_type = new_processors.keys.detect { |key| [:if, :unless].include?(key) }
66
+ condition = new_processors.delete(:if) || new_processors.delete(:unless)
61
67
  new_processors.each do |processor, processor_args|
62
- self.processors += [[processor, processor_args, condition]]
68
+ self.processors += [[processor, processor_args, condition, condition_type]]
63
69
  end
64
70
  end
65
-
66
71
  end # ClassMethods
67
72
 
68
73
  ##
@@ -72,13 +77,19 @@ module CarrierWave
72
77
  return unless enable_processing
73
78
 
74
79
  with_callbacks(:process, new_file) do
75
- self.class.processors.each do |method, args, condition|
76
- if(condition)
80
+ self.class.processors.each do |method, args, condition, condition_type|
81
+ if(condition && condition_type == :if)
77
82
  if condition.respond_to?(:call)
78
83
  next unless condition.call(self, :args => args, :method => method, :file => new_file)
79
84
  else
80
85
  next unless self.send(condition, new_file)
81
86
  end
87
+ elsif(condition && condition_type == :unless)
88
+ if condition.respond_to?(:call)
89
+ next if condition.call(self, :args => args, :method => method, :file => new_file)
90
+ else
91
+ next if self.send(condition, new_file)
92
+ end
82
93
  end
83
94
 
84
95
  if args.is_a? Array
@@ -51,6 +51,10 @@ module CarrierWave
51
51
  # process :scale => [200, 200]
52
52
  # end
53
53
  #
54
+ # version :square, :unless => :invalid_image_type? do
55
+ # process :scale => [100, 100]
56
+ # end
57
+ #
54
58
  # end
55
59
  #
56
60
  def version(name, options = {}, &block)
@@ -161,7 +165,7 @@ module CarrierWave
161
165
  #
162
166
  # === Returns
163
167
  #
164
- # [Boolean] True when the version exists according to its :if condition
168
+ # [Boolean] True when the version exists according to its :if or :unless condition
165
169
  #
166
170
  def version_exists?(name)
167
171
  name = name.to_sym
@@ -169,11 +173,20 @@ module CarrierWave
169
173
  return false unless self.class.versions.has_key?(name)
170
174
 
171
175
  condition = self.class.versions[name].version_options[:if]
172
- if(condition)
173
- if(condition.respond_to?(:call))
174
- condition.call(self, :version => name, :file => file)
176
+ if_condition = self.class.versions[name].version_options[:if]
177
+ unless_condition = self.class.versions[name].version_options[:unless]
178
+
179
+ if(if_condition)
180
+ if(if_condition.respond_to?(:call))
181
+ if_condition.call(self, :version => name, :file => file)
175
182
  else
176
- send(condition, file)
183
+ send(if_condition, file)
184
+ end
185
+ elsif(unless_condition)
186
+ if(unless_condition.respond_to?(:call))
187
+ !unless_condition.call(self, :version => name, :file => file)
188
+ else
189
+ !send(unless_condition, file)
177
190
  end
178
191
  else
179
192
  true
@@ -7,10 +7,10 @@ require "carrierwave/uploader/cache"
7
7
  require "carrierwave/uploader/store"
8
8
  require "carrierwave/uploader/download"
9
9
  require "carrierwave/uploader/remove"
10
- require "carrierwave/uploader/extension_whitelist"
11
- require "carrierwave/uploader/extension_blacklist"
12
- require "carrierwave/uploader/content_type_whitelist"
13
- require "carrierwave/uploader/content_type_blacklist"
10
+ require "carrierwave/uploader/extension_allowlist"
11
+ require "carrierwave/uploader/extension_denylist"
12
+ require "carrierwave/uploader/content_type_allowlist"
13
+ require "carrierwave/uploader/content_type_denylist"
14
14
  require "carrierwave/uploader/file_size"
15
15
  require "carrierwave/uploader/processing"
16
16
  require "carrierwave/uploader/versions"
@@ -52,10 +52,10 @@ module CarrierWave
52
52
  include CarrierWave::Uploader::Store
53
53
  include CarrierWave::Uploader::Download
54
54
  include CarrierWave::Uploader::Remove
55
- include CarrierWave::Uploader::ExtensionWhitelist
56
- include CarrierWave::Uploader::ExtensionBlacklist
57
- include CarrierWave::Uploader::ContentTypeWhitelist
58
- include CarrierWave::Uploader::ContentTypeBlacklist
55
+ include CarrierWave::Uploader::ExtensionAllowlist
56
+ include CarrierWave::Uploader::ExtensionDenylist
57
+ include CarrierWave::Uploader::ContentTypeAllowlist
58
+ include CarrierWave::Uploader::ContentTypeDenylist
59
59
  include CarrierWave::Uploader::FileSize
60
60
  include CarrierWave::Uploader::Processing
61
61
  include CarrierWave::Uploader::Versions
@@ -0,0 +1,47 @@
1
+ module CarrierWave
2
+ module Utilities
3
+ module FileName
4
+
5
+ ##
6
+ # Returns the part of the filename before the extension. So if a file is called 'test.jpeg'
7
+ # this would return 'test'
8
+ #
9
+ # === Returns
10
+ #
11
+ # [String] the first part of the filename
12
+ #
13
+ def basename
14
+ split_extension(filename)[0] if filename
15
+ end
16
+
17
+ ##
18
+ # Returns the file extension
19
+ #
20
+ # === Returns
21
+ #
22
+ # [String] extension of file or "" if the file has no extension
23
+ #
24
+ def extension
25
+ split_extension(filename)[1] if filename
26
+ end
27
+
28
+ private
29
+
30
+ def split_extension(filename)
31
+ # regular expressions to try for identifying extensions
32
+ extension_matchers = [
33
+ /\A(.+)\.(tar\.([glx]?z|bz2))\z/, # matches "something.tar.gz"
34
+ /\A(.+)\.([^\.]+)\z/ # matches "something.jpg"
35
+ ]
36
+
37
+ extension_matchers.each do |regexp|
38
+ if filename =~ regexp
39
+ return $1, $2
40
+ end
41
+ end
42
+
43
+ return filename, "" # In case we weren't able to split the extension
44
+ end
45
+ end # FileName
46
+ end # Utilities
47
+ end # CarrierWave
@@ -1,4 +1,5 @@
1
1
  require 'carrierwave/utilities/uri'
2
+ require 'carrierwave/utilities/file_name'
2
3
 
3
4
  module CarrierWave
4
5
  module Utilities
@@ -1,3 +1,3 @@
1
1
  module CarrierWave
2
- VERSION = "2.2.5"
2
+ VERSION = "3.0.0.beta"
3
3
  end
data/lib/carrierwave.rb CHANGED
@@ -25,16 +25,7 @@ module CarrierWave
25
25
 
26
26
  end
27
27
 
28
- if defined?(Merb)
29
-
30
- CarrierWave.root = Merb.dir_for(:public)
31
- Merb::BootLoader.before_app_loads do
32
- # Setup path for uploaders and load all of them before classes are loaded
33
- Merb.push_path(:uploaders, Merb.root / 'app' / 'uploaders', '*.rb')
34
- Dir.glob(File.join(Merb.load_paths[:uploaders])).each {|f| require f }
35
- end
36
-
37
- elsif defined?(Jets)
28
+ if defined?(Jets)
38
29
 
39
30
  module CarrierWave
40
31
  class Turbine < Jets::Turbine
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carrierwave
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.5
4
+ version: 3.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Nicklas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-29 00:00:00.000000000 Z
11
+ date: 2022-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,42 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.0
19
+ version: 6.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 5.0.0
26
+ version: 6.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 5.0.0
33
+ version: 6.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 5.0.0
41
- - !ruby/object:Gem::Dependency
42
- name: mini_mime
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 0.1.3
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: 0.1.3
40
+ version: 6.0.0
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: image_processing
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -108,34 +94,20 @@ dependencies:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
96
  version: '1.0'
111
- - !ruby/object:Gem::Dependency
112
- name: pg
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
97
  - !ruby/object:Gem::Dependency
126
98
  name: rails
127
99
  requirement: !ruby/object:Gem::Requirement
128
100
  requirements:
129
101
  - - ">="
130
102
  - !ruby/object:Gem::Version
131
- version: 5.0.0
103
+ version: 6.0.0
132
104
  type: :development
133
105
  prerelease: false
134
106
  version_requirements: !ruby/object:Gem::Requirement
135
107
  requirements:
136
108
  - - ">="
137
109
  - !ruby/object:Gem::Version
138
- version: 5.0.0
110
+ version: 6.0.0
139
111
  - !ruby/object:Gem::Dependency
140
112
  name: cucumber
141
113
  requirement: !ruby/object:Gem::Requirement
@@ -371,12 +343,12 @@ files:
371
343
  - lib/carrierwave/uploader/cache.rb
372
344
  - lib/carrierwave/uploader/callbacks.rb
373
345
  - lib/carrierwave/uploader/configuration.rb
374
- - lib/carrierwave/uploader/content_type_blacklist.rb
375
- - lib/carrierwave/uploader/content_type_whitelist.rb
346
+ - lib/carrierwave/uploader/content_type_allowlist.rb
347
+ - lib/carrierwave/uploader/content_type_denylist.rb
376
348
  - lib/carrierwave/uploader/default_url.rb
377
349
  - lib/carrierwave/uploader/download.rb
378
- - lib/carrierwave/uploader/extension_blacklist.rb
379
- - lib/carrierwave/uploader/extension_whitelist.rb
350
+ - lib/carrierwave/uploader/extension_allowlist.rb
351
+ - lib/carrierwave/uploader/extension_denylist.rb
380
352
  - lib/carrierwave/uploader/file_size.rb
381
353
  - lib/carrierwave/uploader/mountable.rb
382
354
  - lib/carrierwave/uploader/processing.rb
@@ -387,6 +359,7 @@ files:
387
359
  - lib/carrierwave/uploader/url.rb
388
360
  - lib/carrierwave/uploader/versions.rb
389
361
  - lib/carrierwave/utilities.rb
362
+ - lib/carrierwave/utilities/file_name.rb
390
363
  - lib/carrierwave/utilities/uri.rb
391
364
  - lib/carrierwave/validations/active_model.rb
392
365
  - lib/carrierwave/version.rb
@@ -405,14 +378,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
405
378
  requirements:
406
379
  - - ">="
407
380
  - !ruby/object:Gem::Version
408
- version: 2.2.2
381
+ version: 2.5.0
409
382
  required_rubygems_version: !ruby/object:Gem::Requirement
410
383
  requirements:
411
- - - ">="
384
+ - - ">"
412
385
  - !ruby/object:Gem::Version
413
- version: '0'
386
+ version: 1.3.1
414
387
  requirements: []
415
- rubygems_version: 3.4.10
388
+ rubygems_version: 3.3.7
416
389
  signing_key:
417
390
  specification_version: 4
418
391
  summary: Ruby file upload library