carrierwave 0.11.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +294 -124
  3. data/lib/carrierwave.rb +34 -8
  4. data/lib/carrierwave/compatibility/paperclip.rb +0 -2
  5. data/lib/carrierwave/downloader/base.rb +50 -0
  6. data/lib/carrierwave/downloader/remote_file.rb +44 -0
  7. data/lib/carrierwave/error.rb +1 -0
  8. data/lib/carrierwave/locale/en.yml +7 -4
  9. data/lib/carrierwave/mount.rb +229 -180
  10. data/lib/carrierwave/mounter.rb +188 -0
  11. data/lib/carrierwave/orm/activerecord.rb +59 -24
  12. data/lib/carrierwave/processing.rb +0 -1
  13. data/lib/carrierwave/processing/mini_magick.rb +137 -83
  14. data/lib/carrierwave/processing/rmagick.rb +54 -5
  15. data/lib/carrierwave/sanitized_file.rb +50 -30
  16. data/lib/carrierwave/storage.rb +1 -9
  17. data/lib/carrierwave/storage/abstract.rb +15 -2
  18. data/lib/carrierwave/storage/file.rb +69 -2
  19. data/lib/carrierwave/storage/fog.rb +177 -37
  20. data/lib/carrierwave/test/matchers.rb +77 -12
  21. data/lib/carrierwave/uploader.rb +2 -2
  22. data/lib/carrierwave/uploader/cache.rb +60 -38
  23. data/lib/carrierwave/uploader/callbacks.rb +0 -2
  24. data/lib/carrierwave/uploader/configuration.rb +71 -13
  25. data/lib/carrierwave/uploader/content_type_whitelist.rb +1 -1
  26. data/lib/carrierwave/uploader/default_url.rb +3 -5
  27. data/lib/carrierwave/uploader/download.rb +4 -74
  28. data/lib/carrierwave/uploader/extension_blacklist.rb +14 -10
  29. data/lib/carrierwave/uploader/extension_whitelist.rb +13 -10
  30. data/lib/carrierwave/uploader/file_size.rb +43 -0
  31. data/lib/carrierwave/uploader/mountable.rb +13 -8
  32. data/lib/carrierwave/uploader/processing.rb +10 -10
  33. data/lib/carrierwave/uploader/proxy.rb +6 -8
  34. data/lib/carrierwave/uploader/remove.rb +0 -2
  35. data/lib/carrierwave/uploader/serialization.rb +2 -4
  36. data/lib/carrierwave/uploader/store.rb +17 -24
  37. data/lib/carrierwave/uploader/url.rb +3 -5
  38. data/lib/carrierwave/uploader/versions.rb +123 -93
  39. data/lib/carrierwave/utilities.rb +0 -3
  40. data/lib/carrierwave/utilities/uri.rb +5 -6
  41. data/lib/carrierwave/validations/active_model.rb +3 -5
  42. data/lib/carrierwave/version.rb +1 -1
  43. data/lib/generators/templates/uploader.rb +4 -8
  44. metadata +80 -65
  45. data/lib/carrierwave/locale/cs.yml +0 -11
  46. data/lib/carrierwave/locale/de.yml +0 -11
  47. data/lib/carrierwave/locale/el.yml +0 -11
  48. data/lib/carrierwave/locale/es.yml +0 -11
  49. data/lib/carrierwave/locale/fr.yml +0 -11
  50. data/lib/carrierwave/locale/ja.yml +0 -11
  51. data/lib/carrierwave/locale/nb.yml +0 -11
  52. data/lib/carrierwave/locale/nl.yml +0 -11
  53. data/lib/carrierwave/locale/pl.yml +0 -11
  54. data/lib/carrierwave/locale/pt-BR.yml +0 -11
  55. data/lib/carrierwave/locale/pt-PT.yml +0 -11
  56. data/lib/carrierwave/locale/ru.yml +0 -11
  57. data/lib/carrierwave/locale/sk.yml +0 -11
  58. data/lib/carrierwave/locale/tr.yml +0 -11
  59. data/lib/carrierwave/processing/mime_types.rb +0 -74
  60. data/lib/carrierwave/utilities/deprecation.rb +0 -18
@@ -35,7 +35,7 @@ module CarrierWave
35
35
  def check_content_type_whitelist!(new_file)
36
36
  content_type = new_file.content_type
37
37
  if content_type_whitelist && !whitelisted_content_type?(content_type)
38
- raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_whitelist_error", content_type: content_type)
38
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.content_type_whitelist_error", content_type: content_type, allowed_types: Array(content_type_whitelist).join(", "))
39
39
  end
40
40
  end
41
41
 
@@ -1,19 +1,17 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Uploader
5
3
  module DefaultUrl
6
4
 
7
5
  def url(*args)
8
- super || default_url
6
+ super || default_url(*args)
9
7
  end
10
8
 
11
9
  ##
12
10
  # Override this method in your uploader to provide a default url
13
11
  # in case no file has been cached/stored yet.
14
12
  #
15
- def default_url; end
13
+ def default_url(*args); end
16
14
 
17
15
  end # DefaultPath
18
16
  end # Uploader
19
- end # CarrierWave
17
+ end # CarrierWave
@@ -1,7 +1,3 @@
1
- # encoding: utf-8
2
-
3
- require 'open-uri'
4
-
5
1
  module CarrierWave
6
2
  module Uploader
7
3
  module Download
@@ -11,84 +7,18 @@ module CarrierWave
11
7
  include CarrierWave::Uploader::Configuration
12
8
  include CarrierWave::Uploader::Cache
13
9
 
14
- class RemoteFile
15
- def initialize(uri)
16
- @uri = uri
17
- end
18
-
19
- def original_filename
20
- filename = filename_from_header || File.basename(file.base_uri.path)
21
- mime_type = MIME::Types[file.content_type].first
22
- unless File.extname(filename).present? || mime_type.blank?
23
- filename = "#{filename}.#{mime_type.extensions.first}"
24
- end
25
- filename
26
- end
27
-
28
- def respond_to?(*args)
29
- super or file.respond_to?(*args)
30
- end
31
-
32
- def http?
33
- @uri.scheme =~ /^https?$/
34
- end
35
-
36
- private
37
-
38
- def file
39
- if @file.blank?
40
- @file = Kernel.open(@uri.to_s)
41
- @file = @file.is_a?(String) ? StringIO.new(@file) : @file
42
- end
43
- @file
44
-
45
- rescue Exception => e
46
- raise CarrierWave::DownloadError, "could not download file: #{e.message}"
47
- end
48
-
49
- def filename_from_header
50
- if file.meta.include? 'content-disposition'
51
- match = file.meta['content-disposition'].match(/filename="?([^"]+)/)
52
- return match[1] unless match.nil? || match[1].empty?
53
- end
54
- end
55
-
56
- def method_missing(*args, &block)
57
- file.send(*args, &block)
58
- end
59
- end
60
-
61
10
  ##
62
- # Caches the file by downloading it from the given URL.
11
+ # Caches the file by downloading it from the given URL, using downloader.
63
12
  #
64
13
  # === Parameters
65
14
  #
66
15
  # [url (String)] The URL where the remote file is stored
16
+ # [remote_headers (Hash)] Request headers
67
17
  #
68
- def download!(uri)
69
- processed_uri = process_uri(uri)
70
- file = RemoteFile.new(processed_uri)
71
- raise CarrierWave::DownloadError, "trying to download a file which is not served over HTTP" unless file.http?
18
+ def download!(uri, remote_headers = {})
19
+ file = downloader.new(self).download(uri, remote_headers)
72
20
  cache!(file)
73
21
  end
74
-
75
- ##
76
- # Processes the given URL by parsing and escaping it. Public to allow overriding.
77
- #
78
- # === Parameters
79
- #
80
- # [url (String)] The URL where the remote file is stored
81
- #
82
- def process_uri(uri)
83
- URI.parse(uri)
84
- rescue URI::InvalidURIError
85
- uri_parts = uri.split('?')
86
- # regexp from Ruby's URI::Parser#regexp[:UNSAFE], with [] specifically removed
87
- encoded_uri = URI.encode(uri_parts.shift, /[^\-_.!~*'()a-zA-Z\d;\/?:@&=+$,]/)
88
- encoded_uri << '?' << URI.encode(uri_parts.join('?')) if uri_parts.any?
89
- URI.parse(encoded_uri) rescue raise CarrierWave::DownloadError, "couldn't parse URL"
90
- end
91
-
92
22
  end # Download
93
23
  end # Uploader
94
24
  end # CarrierWave
@@ -4,7 +4,7 @@ module CarrierWave
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- before :cache, :check_blacklist!
7
+ before :cache, :check_extension_blacklist!
8
8
  end
9
9
 
10
10
  ##
@@ -16,32 +16,36 @@ module CarrierWave
16
16
  # the Regexp expression, also case insensitive.
17
17
  #
18
18
  # === Returns
19
-
20
- # [NilClass, Array[String,Regexp]] a black list of extensions which are prohibited to be uploaded
19
+
20
+ # [NilClass, String, Regexp, Array[String, Regexp]] a black list of extensions which are prohibited to be uploaded
21
21
  #
22
22
  # === Examples
23
23
  #
24
- # def extension_black_list
24
+ # def extension_blacklist
25
25
  # %w(swf tiff)
26
26
  # end
27
27
  #
28
28
  # Basically the same, but using a Regexp:
29
29
  #
30
- # def extension_black_list
30
+ # def extension_blacklist
31
31
  # [/swf/, 'tiff']
32
32
  # end
33
33
  #
34
-
35
- def extension_black_list; end
34
+
35
+ def extension_blacklist; end
36
36
 
37
37
  private
38
38
 
39
- def check_blacklist!(new_file)
39
+ def check_extension_blacklist!(new_file)
40
40
  extension = new_file.extension.to_s
41
- if extension_black_list and extension_black_list.detect { |item| extension =~ /\A#{item}\z/i }
42
- raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_black_list_error", :extension => new_file.extension.inspect, :prohibited_types => extension_black_list.join(", "))
41
+ if extension_blacklist && blacklisted_extension?(extension)
42
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_blacklist_error", extension: new_file.extension.inspect, prohibited_types: Array(extension_blacklist).join(", "))
43
43
  end
44
44
  end
45
+
46
+ def blacklisted_extension?(extension)
47
+ Array(extension_blacklist).any? { |item| extension =~ /\A#{item}\z/i }
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -1,12 +1,10 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Uploader
5
3
  module ExtensionWhitelist
6
4
  extend ActiveSupport::Concern
7
5
 
8
6
  included do
9
- before :cache, :check_whitelist!
7
+ before :cache, :check_extension_whitelist!
10
8
  end
11
9
 
12
10
  ##
@@ -19,31 +17,36 @@ module CarrierWave
19
17
  #
20
18
  # === Returns
21
19
  #
22
- # [NilClass, Array[String,Regexp]] a white list of extensions which are allowed to be uploaded
20
+ # [NilClass, String, Regexp, Array[String, Regexp]] a white list of extensions which are allowed to be uploaded
23
21
  #
24
22
  # === Examples
25
23
  #
26
- # def extension_white_list
24
+ # def extension_whitelist
27
25
  # %w(jpg jpeg gif png)
28
26
  # end
29
27
  #
30
28
  # Basically the same, but using a Regexp:
31
29
  #
32
- # def extension_white_list
30
+ # def extension_whitelist
33
31
  # [/jpe?g/, 'gif', 'png']
34
32
  # end
35
33
  #
36
- def extension_white_list; end
34
+ def extension_whitelist; end
37
35
 
38
36
  private
39
37
 
40
- def check_whitelist!(new_file)
38
+ def check_extension_whitelist!(new_file)
41
39
  extension = new_file.extension.to_s
42
- if extension_white_list and not extension_white_list.detect { |item| extension =~ /\A#{item}\z/i }
43
- raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_white_list_error", :extension => new_file.extension.inspect, :allowed_types => extension_white_list.join(", "))
40
+ if extension_whitelist && !whitelisted_extension?(extension)
41
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.extension_whitelist_error", extension: new_file.extension.inspect, allowed_types: Array(extension_whitelist).join(", "))
44
42
  end
45
43
  end
46
44
 
45
+ def whitelisted_extension?(extension)
46
+ downcase_extension = extension.downcase
47
+ Array(extension_whitelist).any? { |item| downcase_extension =~ /\A#{item}\z/i }
48
+ end
49
+
47
50
  end # ExtensionWhitelist
48
51
  end # Uploader
49
52
  end # CarrierWave
@@ -0,0 +1,43 @@
1
+ require 'active_support'
2
+
3
+ module CarrierWave
4
+ module Uploader
5
+ module FileSize
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ before :cache, :check_size!
10
+ end
11
+
12
+ ##
13
+ # Override this method in your uploader to provide a Range of Size which
14
+ # are allowed to be uploaded.
15
+ # === Returns
16
+ #
17
+ # [NilClass, Range] a size range which are permitted to be uploaded
18
+ #
19
+ # === Examples
20
+ #
21
+ # def size_range
22
+ # 3256...5748
23
+ # end
24
+ #
25
+ def size_range; end
26
+
27
+ private
28
+
29
+ def check_size!(new_file)
30
+ size = new_file.size
31
+ expected_size_range = size_range
32
+ if expected_size_range.is_a?(::Range)
33
+ if size < expected_size_range.min
34
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.min_size_error", :min_size => ActiveSupport::NumberHelper.number_to_human_size(expected_size_range.min))
35
+ elsif size > expected_size_range.max
36
+ raise CarrierWave::IntegrityError, I18n.translate(:"errors.messages.max_size_error", :max_size => ActiveSupport::NumberHelper.number_to_human_size(expected_size_range.max))
37
+ end
38
+ end
39
+ end
40
+
41
+ end # FileSize
42
+ end # Uploader
43
+ end # CarrierWave
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Uploader
5
3
  module Mountable
@@ -7,13 +5,14 @@ module CarrierWave
7
5
  attr_reader :model, :mounted_as
8
6
 
9
7
  ##
10
- # If a model is given as the first parameter, it will be stored in the uploader, and
11
- # available throught +#model+. Likewise, mounted_as stores the name of the column
12
- # where this instance of the uploader is mounted. These values can then be used inside
13
- # your uploader.
8
+ # If a model is given as the first parameter, it will be stored in the
9
+ # uploader, and available through +#model+. Likewise, mounted_as stores
10
+ # the name of the column where this instance of the uploader is mounted.
11
+ # These values can then be used inside your uploader.
14
12
  #
15
- # If you do not wish to mount your uploaders with the ORM extensions in -more then you
16
- # can override this method inside your uploader. Just be sure to call +super+
13
+ # If you do not wish to mount your uploaders with the ORM extensions in
14
+ # -more then you can override this method inside your uploader. Just be
15
+ # sure to call +super+
17
16
  #
18
17
  # === Parameters
19
18
  #
@@ -34,6 +33,12 @@ module CarrierWave
34
33
  @mounted_as = mounted_as
35
34
  end
36
35
 
36
+ ##
37
+ # Returns array index of given uploader within currently mounted uploaders
38
+ #
39
+ def index
40
+ model.__send__(:_mounter, mounted_as).uploaders.index(self)
41
+ end
37
42
  end # Mountable
38
43
  end # Uploader
39
44
  end # CarrierWave
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Uploader
5
3
  module Processing
@@ -11,7 +9,7 @@ module CarrierWave
11
9
  class_attribute :processors, :instance_writer => false
12
10
  self.processors = []
13
11
 
14
- after :cache, :process!
12
+ before :cache, :process!
15
13
  end
16
14
 
17
15
  module ClassMethods
@@ -73,15 +71,17 @@ module CarrierWave
73
71
  def process!(new_file=nil)
74
72
  return unless enable_processing
75
73
 
76
- self.class.processors.each do |method, args, condition|
77
- if(condition)
78
- if condition.respond_to?(:call)
79
- next unless condition.call(self, :args => args, :method => method, :file => new_file)
80
- else
81
- next unless self.send(condition, new_file)
74
+ with_callbacks(:process, new_file) do
75
+ self.class.processors.each do |method, args, condition|
76
+ if(condition)
77
+ if condition.respond_to?(:call)
78
+ next unless condition.call(self, :args => args, :method => method, :file => new_file)
79
+ else
80
+ next unless self.send(condition, new_file)
81
+ end
82
82
  end
83
+ self.send(method, *args)
83
84
  end
84
- self.send(method, *args)
85
85
  end
86
86
  end
87
87
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Uploader
5
3
  module Proxy
@@ -19,20 +17,20 @@ module CarrierWave
19
17
  # [String] the path where the file is currently located.
20
18
  #
21
19
  def current_path
22
- file.path if file.respond_to?(:path)
20
+ file.try(:path)
23
21
  end
24
22
 
25
23
  alias_method :path, :current_path
26
24
 
27
25
  ##
28
- # Returns a string that uniquely identifies the last stored file
26
+ # Returns a string that uniquely identifies the retrieved or last stored file
29
27
  #
30
28
  # === Returns
31
29
  #
32
30
  # [String] uniquely identifies a file
33
31
  #
34
32
  def identifier
35
- storage.identifier if storage.respond_to?(:identifier)
33
+ @identifier || storage.try(:identifier)
36
34
  end
37
35
 
38
36
  ##
@@ -43,7 +41,7 @@ module CarrierWave
43
41
  # [String] contents of the file
44
42
  #
45
43
  def read
46
- file.read if file.respond_to?(:read)
44
+ file.try(:read)
47
45
  end
48
46
 
49
47
  ##
@@ -54,7 +52,7 @@ module CarrierWave
54
52
  # [Integer] size of the file
55
53
  #
56
54
  def size
57
- file.respond_to?(:size) ? file.size : 0
55
+ file.try(:size) || 0
58
56
  end
59
57
 
60
58
  ##
@@ -80,7 +78,7 @@ module CarrierWave
80
78
  # [String] content type of the file
81
79
  #
82
80
  def content_type
83
- file.respond_to?(:content_type) ? file.content_type : nil
81
+ file.try(:content_type)
84
82
  end
85
83
 
86
84
  end # Proxy
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module CarrierWave
4
2
  module Uploader
5
3
  module Remove
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require "json"
4
2
  require "active_support/core_ext/hash"
5
3
 
@@ -9,11 +7,11 @@ module CarrierWave
9
7
  extend ActiveSupport::Concern
10
8
 
11
9
  def serializable_hash(options = nil)
12
- {"url" => url}.merge Hash[versions.map { |name, version| [name, { "url" => version.url }] }]
10
+ {"url" => url}.merge Hash[versions.map { |name, version| [name.to_s, { "url" => version.url }] }]
13
11
  end
14
12
 
15
13
  def as_json(options=nil)
16
- Hash[mounted_as || "uploader", serializable_hash]
14
+ serializable_hash
17
15
  end
18
16
 
19
17
  def to_json(options=nil)