carrierwave 0.11.2 → 3.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +452 -178
- data/lib/carrierwave/compatibility/paperclip.rb +4 -4
- data/lib/carrierwave/downloader/base.rb +101 -0
- data/lib/carrierwave/downloader/remote_file.rb +68 -0
- data/lib/carrierwave/error.rb +1 -0
- data/lib/carrierwave/locale/en.yml +11 -5
- data/lib/carrierwave/mount.rb +217 -182
- data/lib/carrierwave/mounter.rb +255 -0
- data/lib/carrierwave/orm/activerecord.rb +29 -35
- data/lib/carrierwave/processing/mini_magick.rb +140 -84
- data/lib/carrierwave/processing/rmagick.rb +72 -21
- data/lib/carrierwave/processing/vips.rb +284 -0
- data/lib/carrierwave/processing.rb +1 -1
- data/lib/carrierwave/sanitized_file.rb +83 -84
- data/lib/carrierwave/storage/abstract.rb +16 -3
- data/lib/carrierwave/storage/file.rb +71 -3
- data/lib/carrierwave/storage/fog.rb +215 -57
- data/lib/carrierwave/storage.rb +1 -9
- data/lib/carrierwave/test/matchers.rb +88 -19
- data/lib/carrierwave/uploader/cache.rb +75 -45
- data/lib/carrierwave/uploader/callbacks.rb +1 -3
- data/lib/carrierwave/uploader/configuration.rb +80 -16
- data/lib/carrierwave/uploader/content_type_allowlist.rb +62 -0
- data/lib/carrierwave/uploader/content_type_denylist.rb +62 -0
- data/lib/carrierwave/uploader/default_url.rb +3 -5
- data/lib/carrierwave/uploader/dimension.rb +66 -0
- data/lib/carrierwave/uploader/download.rb +4 -74
- data/lib/carrierwave/uploader/extension_allowlist.rb +63 -0
- data/lib/carrierwave/uploader/extension_denylist.rb +64 -0
- data/lib/carrierwave/uploader/file_size.rb +43 -0
- data/lib/carrierwave/uploader/mountable.rb +13 -8
- data/lib/carrierwave/uploader/processing.rb +48 -13
- data/lib/carrierwave/uploader/proxy.rb +20 -9
- data/lib/carrierwave/uploader/remove.rb +0 -2
- data/lib/carrierwave/uploader/serialization.rb +2 -4
- data/lib/carrierwave/uploader/store.rb +59 -28
- data/lib/carrierwave/uploader/url.rb +8 -7
- data/lib/carrierwave/uploader/versions.rb +171 -123
- data/lib/carrierwave/uploader.rb +12 -10
- data/lib/carrierwave/utilities/file_name.rb +47 -0
- data/lib/carrierwave/utilities/uri.rb +14 -12
- data/lib/carrierwave/utilities.rb +1 -3
- data/lib/carrierwave/validations/active_model.rb +7 -11
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +39 -21
- data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +6 -10
- data/lib/generators/uploader_generator.rb +3 -3
- metadata +135 -83
- data/lib/carrierwave/locale/cs.yml +0 -11
- data/lib/carrierwave/locale/de.yml +0 -11
- data/lib/carrierwave/locale/el.yml +0 -11
- data/lib/carrierwave/locale/es.yml +0 -11
- data/lib/carrierwave/locale/fr.yml +0 -11
- data/lib/carrierwave/locale/ja.yml +0 -11
- data/lib/carrierwave/locale/nb.yml +0 -11
- data/lib/carrierwave/locale/nl.yml +0 -11
- data/lib/carrierwave/locale/pl.yml +0 -11
- data/lib/carrierwave/locale/pt-BR.yml +0 -11
- data/lib/carrierwave/locale/pt-PT.yml +0 -11
- data/lib/carrierwave/locale/ru.yml +0 -11
- data/lib/carrierwave/locale/sk.yml +0 -11
- data/lib/carrierwave/locale/tr.yml +0 -11
- data/lib/carrierwave/processing/mime_types.rb +0 -74
- data/lib/carrierwave/uploader/content_type_blacklist.rb +0 -48
- data/lib/carrierwave/uploader/content_type_whitelist.rb +0 -48
- data/lib/carrierwave/uploader/extension_blacklist.rb +0 -47
- data/lib/carrierwave/uploader/extension_whitelist.rb +0 -49
- data/lib/carrierwave/utilities/deprecation.rb +0 -18
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module CarrierWave
|
4
2
|
module Uploader
|
5
3
|
module Proxy
|
@@ -19,20 +17,33 @@ module CarrierWave
|
|
19
17
|
# [String] the path where the file is currently located.
|
20
18
|
#
|
21
19
|
def current_path
|
22
|
-
file.
|
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
|
-
|
33
|
+
@identifier || (file && storage.try(:identifier))
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Returns a String which is to be used as a temporary value which gets assigned to the column.
|
38
|
+
# The purpose is to mark the column that it will be updated. Finally before the save it will be
|
39
|
+
# overwritten by the #identifier value, which is usually #filename.
|
40
|
+
#
|
41
|
+
# === Returns
|
42
|
+
#
|
43
|
+
# [String] a temporary_identifier, by default the value of #cache_name is used
|
44
|
+
#
|
45
|
+
def temporary_identifier
|
46
|
+
cache_name || @identifier
|
36
47
|
end
|
37
48
|
|
38
49
|
##
|
@@ -42,8 +53,8 @@ module CarrierWave
|
|
42
53
|
#
|
43
54
|
# [String] contents of the file
|
44
55
|
#
|
45
|
-
def read
|
46
|
-
file.
|
56
|
+
def read(*args)
|
57
|
+
file.try(:read, *args)
|
47
58
|
end
|
48
59
|
|
49
60
|
##
|
@@ -54,7 +65,7 @@ module CarrierWave
|
|
54
65
|
# [Integer] size of the file
|
55
66
|
#
|
56
67
|
def size
|
57
|
-
file.
|
68
|
+
file.try(:size) || 0
|
58
69
|
end
|
59
70
|
|
60
71
|
##
|
@@ -80,7 +91,7 @@ module CarrierWave
|
|
80
91
|
# [String] content type of the file
|
81
92
|
#
|
82
93
|
def content_type
|
83
|
-
file.
|
94
|
+
file.try(:content_type)
|
84
95
|
end
|
85
96
|
|
86
97
|
end # Proxy
|
@@ -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
|
-
|
14
|
+
serializable_hash
|
17
15
|
end
|
18
16
|
|
19
17
|
def to_json(options=nil)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module CarrierWave
|
4
2
|
module Uploader
|
5
3
|
module Store
|
@@ -9,6 +7,15 @@ module CarrierWave
|
|
9
7
|
include CarrierWave::Uploader::Configuration
|
10
8
|
include CarrierWave::Uploader::Cache
|
11
9
|
|
10
|
+
included do
|
11
|
+
prepend Module.new {
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@file, @filename, @cache_id, @identifier, @deduplication_index = nil
|
15
|
+
end
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
12
19
|
##
|
13
20
|
# Override this in your Uploader to change the filename.
|
14
21
|
#
|
@@ -27,9 +34,26 @@ module CarrierWave
|
|
27
34
|
@filename
|
28
35
|
end
|
29
36
|
|
37
|
+
##
|
38
|
+
# Returns a filename which doesn't conflict with already-stored files.
|
39
|
+
#
|
40
|
+
# === Returns
|
41
|
+
#
|
42
|
+
# [String] the filename with suffix added for deduplication
|
43
|
+
#
|
44
|
+
def deduplicated_filename
|
45
|
+
return unless filename
|
46
|
+
return filename unless @deduplication_index
|
47
|
+
|
48
|
+
parts = filename.split('.')
|
49
|
+
basename = parts.shift
|
50
|
+
basename.sub!(/ ?\(\d+\)\z/, '')
|
51
|
+
([basename.to_s + (@deduplication_index > 1 ? "(#{@deduplication_index})" : '')] + parts).join('.')
|
52
|
+
end
|
53
|
+
|
30
54
|
##
|
31
55
|
# Calculates the path where the file should be stored. If +for_file+ is given, it will be
|
32
|
-
# used as the
|
56
|
+
# used as the identifier, otherwise +CarrierWave::Uploader#identifier+ is assumed.
|
33
57
|
#
|
34
58
|
# === Parameters
|
35
59
|
#
|
@@ -39,7 +63,7 @@ module CarrierWave
|
|
39
63
|
#
|
40
64
|
# [String] the store path
|
41
65
|
#
|
42
|
-
def store_path(for_file=
|
66
|
+
def store_path(for_file=identifier)
|
43
67
|
File.join([store_dir, full_filename(for_file)].compact)
|
44
68
|
end
|
45
69
|
|
@@ -53,32 +77,18 @@ module CarrierWave
|
|
53
77
|
# [new_file (File, IOString, Tempfile)] any kind of file object
|
54
78
|
#
|
55
79
|
def store!(new_file=nil)
|
56
|
-
cache!(new_file) if new_file &&
|
57
|
-
if @file
|
80
|
+
cache!(new_file) if new_file && !cached?
|
81
|
+
if !cache_only && @file && @cache_id
|
58
82
|
with_callbacks(:store, new_file) do
|
59
83
|
new_file = storage.store!(@file)
|
60
|
-
|
61
|
-
|
84
|
+
if delete_tmp_file_after_storage
|
85
|
+
@file.delete unless move_to_store
|
86
|
+
cache_storage.delete_dir!(cache_path(nil))
|
87
|
+
end
|
62
88
|
@file = new_file
|
63
|
-
@
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
##
|
69
|
-
# Deletes a cache id (tmp dir in cache)
|
70
|
-
#
|
71
|
-
def delete_cache_id
|
72
|
-
if @cache_id
|
73
|
-
path = File.expand_path(File.join(cache_dir, @cache_id), CarrierWave.root)
|
74
|
-
begin
|
75
|
-
Dir.rmdir(path)
|
76
|
-
rescue Errno::ENOENT
|
77
|
-
# Ignore: path does not exist
|
78
|
-
rescue Errno::ENOTDIR
|
79
|
-
# Ignore: path is not a dir
|
80
|
-
rescue Errno::ENOTEMPTY, Errno::EEXIST
|
81
|
-
# Ignore: dir is not empty
|
89
|
+
@identifier = storage.identifier
|
90
|
+
@original_filename = @cache_id = @deduplication_index = nil
|
91
|
+
@staged = false
|
82
92
|
end
|
83
93
|
end
|
84
94
|
end
|
@@ -93,13 +103,34 @@ module CarrierWave
|
|
93
103
|
def retrieve_from_store!(identifier)
|
94
104
|
with_callbacks(:retrieve_from_store, identifier) do
|
95
105
|
@file = storage.retrieve!(identifier)
|
106
|
+
@identifier = identifier
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Look for an identifier which doesn't collide with the given already-stored identifiers.
|
112
|
+
# It is done by adding a index number as the suffix.
|
113
|
+
# For example, if there's 'image.jpg' and the @deduplication_index is set to 2,
|
114
|
+
# The stored file will be named as 'image(2).jpg'.
|
115
|
+
#
|
116
|
+
# === Parameters
|
117
|
+
#
|
118
|
+
# [current_identifiers (Array[String])] List of identifiers for already-stored files
|
119
|
+
#
|
120
|
+
def deduplicate(current_identifiers)
|
121
|
+
@deduplication_index = nil
|
122
|
+
return unless current_identifiers.include?(identifier)
|
123
|
+
|
124
|
+
(1..current_identifiers.size + 1).each do |i|
|
125
|
+
@deduplication_index = i
|
126
|
+
break unless current_identifiers.include?(identifier)
|
96
127
|
end
|
97
128
|
end
|
98
129
|
|
99
130
|
private
|
100
131
|
|
101
132
|
def full_filename(for_file)
|
102
|
-
for_file
|
133
|
+
forcing_extension(for_file)
|
103
134
|
end
|
104
135
|
|
105
136
|
def storage
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module CarrierWave
|
4
2
|
module Uploader
|
5
3
|
module Url
|
@@ -17,12 +15,15 @@ module CarrierWave
|
|
17
15
|
# [String] the location where this file is accessible via a url
|
18
16
|
#
|
19
17
|
def url(options = {})
|
20
|
-
if file.respond_to?(:url)
|
21
|
-
file.method(:url).arity
|
22
|
-
|
23
|
-
|
18
|
+
if file.respond_to?(:url)
|
19
|
+
tmp_url = file.method(:url).arity.zero? ? file.url : file.url(options)
|
20
|
+
return tmp_url if tmp_url.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
if file.respond_to?(:path)
|
24
|
+
path = encode_path(file.path.sub(File.expand_path(root), ''))
|
24
25
|
|
25
|
-
if host = asset_host
|
26
|
+
if (host = asset_host)
|
26
27
|
if host.respond_to? :call
|
27
28
|
"#{host.call(file)}#{path}"
|
28
29
|
else
|
@@ -1,26 +1,113 @@
|
|
1
|
-
|
1
|
+
require "active_support/core_ext/object/deep_dup"
|
2
2
|
|
3
3
|
module CarrierWave
|
4
4
|
module Uploader
|
5
5
|
module Versions
|
6
|
+
class Builder
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
@options = {}
|
10
|
+
@blocks = []
|
11
|
+
@klass = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def configure(options, &block)
|
15
|
+
@options.merge!(options)
|
16
|
+
@blocks << block if block
|
17
|
+
@klass = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def build(superclass)
|
21
|
+
return @klass if @klass
|
22
|
+
@klass = Class.new(superclass)
|
23
|
+
superclass.const_set("#{@name.to_s.camelize}VersionUploader", @klass)
|
24
|
+
|
25
|
+
@klass.version_names += [@name]
|
26
|
+
@klass.versions = {}
|
27
|
+
@klass.processors = []
|
28
|
+
@klass.version_options = @options
|
29
|
+
@klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
30
|
+
# Define the enable_processing method for versions so they get the
|
31
|
+
# value from the parent class unless explicitly overwritten
|
32
|
+
def self.enable_processing(value=nil)
|
33
|
+
self.enable_processing = value if value
|
34
|
+
if defined?(@enable_processing) && !@enable_processing.nil?
|
35
|
+
@enable_processing
|
36
|
+
else
|
37
|
+
superclass.enable_processing
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Regardless of what is set in the parent uploader, do not enforce the
|
42
|
+
# move_to_cache config option on versions because it moves the original
|
43
|
+
# file to the version's target file.
|
44
|
+
#
|
45
|
+
# If you want to enforce this setting on versions, override this method
|
46
|
+
# in each version:
|
47
|
+
#
|
48
|
+
# version :thumb do
|
49
|
+
# def move_to_cache
|
50
|
+
# true
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
def move_to_cache
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
# Need to rely on the parent version's identifier, as versions don't have its own one.
|
59
|
+
def identifier
|
60
|
+
parent_version.identifier
|
61
|
+
end
|
62
|
+
RUBY
|
63
|
+
@blocks.each { |block| @klass.class_eval(&block) }
|
64
|
+
@klass
|
65
|
+
end
|
66
|
+
|
67
|
+
def deep_dup
|
68
|
+
other = dup
|
69
|
+
other.instance_variable_set(:@blocks, @blocks.dup)
|
70
|
+
other
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_missing(name, *args)
|
74
|
+
super
|
75
|
+
rescue NoMethodError => e
|
76
|
+
raise e.exception <<~ERROR
|
77
|
+
#{e.message}
|
78
|
+
If you're trying to configure a version, do it inside a block like `version(:thumb) { self.#{name} #{args.map(&:inspect).join(', ')} }`.
|
79
|
+
ERROR
|
80
|
+
end
|
81
|
+
|
82
|
+
def respond_to_missing?(*)
|
83
|
+
super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
6
87
|
extend ActiveSupport::Concern
|
7
88
|
|
8
89
|
include CarrierWave::Uploader::Callbacks
|
9
90
|
|
10
91
|
included do
|
11
|
-
class_attribute :versions, :version_names, :instance_reader => false, :instance_writer => false
|
92
|
+
class_attribute :versions, :version_names, :version_options, :instance_reader => false, :instance_writer => false
|
12
93
|
|
13
94
|
self.versions = {}
|
14
95
|
self.version_names = []
|
15
96
|
|
16
|
-
attr_accessor :
|
97
|
+
attr_accessor :parent_version
|
17
98
|
|
18
|
-
after :cache, :assign_parent_cache_id
|
19
99
|
after :cache, :cache_versions!
|
20
100
|
after :store, :store_versions!
|
21
101
|
after :remove, :remove_versions!
|
22
102
|
after :retrieve_from_cache, :retrieve_versions_from_cache!
|
23
103
|
after :retrieve_from_store, :retrieve_versions_from_store!
|
104
|
+
|
105
|
+
prepend Module.new {
|
106
|
+
def initialize(*)
|
107
|
+
super
|
108
|
+
@versions = nil
|
109
|
+
end
|
110
|
+
}
|
24
111
|
end
|
25
112
|
|
26
113
|
module ClassMethods
|
@@ -46,78 +133,33 @@ module CarrierWave
|
|
46
133
|
# process :scale => [200, 200]
|
47
134
|
# end
|
48
135
|
#
|
136
|
+
# version :square, :unless => :invalid_image_type? do
|
137
|
+
# process :scale => [100, 100]
|
138
|
+
# end
|
139
|
+
#
|
49
140
|
# end
|
50
141
|
#
|
51
142
|
def version(name, options = {}, &block)
|
52
143
|
name = name.to_sym
|
53
|
-
|
54
|
-
|
55
|
-
versions[name][:uploader].class_eval(&block) if block
|
56
|
-
versions[name]
|
57
|
-
end
|
58
|
-
|
59
|
-
def recursively_apply_block_to_versions(&block)
|
60
|
-
versions.each do |name, version|
|
61
|
-
version[:uploader].class_eval(&block)
|
62
|
-
version[:uploader].recursively_apply_block_to_versions(&block)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def build_version(name, options)
|
69
|
-
uploader = Class.new(self)
|
70
|
-
const_set("Uploader#{uploader.object_id}".gsub('-', '_'), uploader)
|
71
|
-
uploader.version_names += [name]
|
72
|
-
uploader.versions = {}
|
73
|
-
uploader.processors = []
|
74
|
-
|
75
|
-
uploader.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
76
|
-
# Define the enable_processing method for versions so they get the
|
77
|
-
# value from the parent class unless explicitly overwritten
|
78
|
-
def self.enable_processing(value=nil)
|
79
|
-
self.enable_processing = value if value
|
80
|
-
if !@enable_processing.nil?
|
81
|
-
@enable_processing
|
82
|
-
else
|
83
|
-
superclass.enable_processing
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Regardless of what is set in the parent uploader, do not enforce the
|
88
|
-
# move_to_cache config option on versions because it moves the original
|
89
|
-
# file to the version's target file.
|
90
|
-
#
|
91
|
-
# If you want to enforce this setting on versions, override this method
|
92
|
-
# in each version:
|
93
|
-
#
|
94
|
-
# version :thumb do
|
95
|
-
# def move_to_cache
|
96
|
-
# true
|
97
|
-
# end
|
98
|
-
# end
|
99
|
-
#
|
100
|
-
def move_to_cache
|
101
|
-
false
|
102
|
-
end
|
103
|
-
RUBY
|
144
|
+
versions[name] ||= Builder.new(name)
|
145
|
+
versions[name].configure(options, &block)
|
104
146
|
|
105
|
-
class_eval <<-RUBY
|
147
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
106
148
|
def #{name}
|
107
149
|
versions[:#{name}]
|
108
150
|
end
|
109
151
|
RUBY
|
110
152
|
|
111
|
-
|
112
|
-
current_version = {
|
113
|
-
name => {
|
114
|
-
:uploader => uploader,
|
115
|
-
:options => options
|
116
|
-
}
|
117
|
-
}
|
118
|
-
self.versions = versions.merge(current_version)
|
153
|
+
versions[name]
|
119
154
|
end
|
120
155
|
|
156
|
+
private
|
157
|
+
|
158
|
+
def inherited(subclass)
|
159
|
+
# To prevent subclass version changes affecting superclass versions
|
160
|
+
subclass.versions = versions.deep_dup
|
161
|
+
super
|
162
|
+
end
|
121
163
|
end # ClassMethods
|
122
164
|
|
123
165
|
##
|
@@ -131,7 +173,8 @@ module CarrierWave
|
|
131
173
|
return @versions if @versions
|
132
174
|
@versions = {}
|
133
175
|
self.class.versions.each do |name, version|
|
134
|
-
@versions[name] = version
|
176
|
+
@versions[name] = version.build(self.class).new(model, mounted_as)
|
177
|
+
@versions[name].parent_version = self
|
135
178
|
end
|
136
179
|
@versions
|
137
180
|
end
|
@@ -153,25 +196,44 @@ module CarrierWave
|
|
153
196
|
#
|
154
197
|
# === Returns
|
155
198
|
#
|
156
|
-
# [Boolean] True when the version exists according to its :if condition
|
199
|
+
# [Boolean] True when the version exists according to its :if or :unless condition
|
157
200
|
#
|
158
201
|
def version_exists?(name)
|
159
202
|
name = name.to_sym
|
160
203
|
|
161
|
-
return false unless
|
204
|
+
return false unless versions.has_key?(name)
|
205
|
+
|
206
|
+
if_condition = versions[name].class.version_options[:if]
|
207
|
+
unless_condition = versions[name].class.version_options[:unless]
|
162
208
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
209
|
+
if if_condition
|
210
|
+
if if_condition.respond_to?(:call)
|
211
|
+
if_condition.call(self, :version => name, :file => file)
|
212
|
+
else
|
213
|
+
send(if_condition, file)
|
214
|
+
end
|
215
|
+
elsif unless_condition
|
216
|
+
if unless_condition.respond_to?(:call)
|
217
|
+
!unless_condition.call(self, :version => name, :file => file)
|
167
218
|
else
|
168
|
-
send(
|
219
|
+
!send(unless_condition, file)
|
169
220
|
end
|
170
221
|
else
|
171
222
|
true
|
172
223
|
end
|
173
224
|
end
|
174
225
|
|
226
|
+
##
|
227
|
+
# Copies the parent's cache_id when caching a version file.
|
228
|
+
# This behavior is not essential but it makes easier to understand
|
229
|
+
# that the cached files are generated by the single upload attempt.
|
230
|
+
#
|
231
|
+
def cache!(*args)
|
232
|
+
self.cache_id = parent_version.cache_id if parent_version
|
233
|
+
|
234
|
+
super
|
235
|
+
end
|
236
|
+
|
175
237
|
##
|
176
238
|
# When given a version name as a parameter, will return the url for that version
|
177
239
|
# This also works with nested versions.
|
@@ -212,26 +274,26 @@ module CarrierWave
|
|
212
274
|
# Recreate versions and reprocess them. This can be used to recreate
|
213
275
|
# versions if their parameters somehow have changed.
|
214
276
|
#
|
215
|
-
def recreate_versions!(*
|
216
|
-
#
|
217
|
-
#
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
if versions.any?
|
223
|
-
file = sanitized_file if !cached?
|
224
|
-
store_versions!(file, versions)
|
225
|
-
else
|
226
|
-
cache! if !cached?
|
227
|
-
store!
|
277
|
+
def recreate_versions!(*names)
|
278
|
+
# As well as specified versions, we need to reprocess versions
|
279
|
+
# that are the source of another version.
|
280
|
+
|
281
|
+
self.cache_id = CarrierWave.generate_cache_id
|
282
|
+
derived_versions.each_value do |v|
|
283
|
+
v.cache!(file) if names.empty? || !(v.descendant_version_names & names).empty?
|
228
284
|
end
|
285
|
+
active_versions.each do |name, v|
|
286
|
+
v.store! if names.empty? || names.include?(name)
|
287
|
+
end
|
288
|
+
ensure
|
289
|
+
@cache_id = nil
|
229
290
|
end
|
230
291
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
292
|
+
protected
|
293
|
+
|
294
|
+
def descendant_version_names
|
295
|
+
[version_name] + derived_versions.flat_map do |name, version|
|
296
|
+
version.descendant_version_names
|
235
297
|
end
|
236
298
|
end
|
237
299
|
|
@@ -241,6 +303,20 @@ module CarrierWave
|
|
241
303
|
end
|
242
304
|
end
|
243
305
|
|
306
|
+
private
|
307
|
+
|
308
|
+
def derived_versions
|
309
|
+
active_versions.reject do |name, v|
|
310
|
+
v.class.version_options[:from_version]
|
311
|
+
end.merge(active_sibling_versions.select do |name, v|
|
312
|
+
v.class.version_options[:from_version] == self.class.version_names.last
|
313
|
+
end)
|
314
|
+
end
|
315
|
+
|
316
|
+
def active_sibling_versions
|
317
|
+
parent_version&.active_versions || {}
|
318
|
+
end
|
319
|
+
|
244
320
|
def full_filename(for_file)
|
245
321
|
[version_name, super(for_file)].compact.join('_')
|
246
322
|
end
|
@@ -250,51 +326,23 @@ module CarrierWave
|
|
250
326
|
end
|
251
327
|
|
252
328
|
def cache_versions!(new_file)
|
253
|
-
|
254
|
-
# initialized, so get the actual file based off of the current state of
|
255
|
-
# our file
|
256
|
-
processed_parent = SanitizedFile.new :tempfile => self.file,
|
257
|
-
:filename => new_file.original_filename
|
258
|
-
|
259
|
-
active_versions.each do |name, v|
|
260
|
-
next if v.cached?
|
261
|
-
|
262
|
-
v.send(:cache_id=, cache_id)
|
263
|
-
# If option :from_version is present, create cache using cached file from
|
264
|
-
# version indicated
|
265
|
-
if self.class.versions[name][:options] && self.class.versions[name][:options][:from_version]
|
266
|
-
# Maybe the reference version has not been cached yet
|
267
|
-
unless versions[self.class.versions[name][:options][:from_version]].cached?
|
268
|
-
versions[self.class.versions[name][:options][:from_version]].cache!(processed_parent)
|
269
|
-
end
|
270
|
-
processed_version = SanitizedFile.new :tempfile => versions[self.class.versions[name][:options][:from_version]],
|
271
|
-
:filename => new_file.original_filename
|
272
|
-
v.cache!(processed_version)
|
273
|
-
else
|
274
|
-
v.cache!(processed_parent)
|
275
|
-
end
|
276
|
-
end
|
329
|
+
derived_versions.each_value { |v| v.cache!(new_file) }
|
277
330
|
end
|
278
331
|
|
279
|
-
def store_versions!(new_file
|
280
|
-
|
281
|
-
active = Hash[active_versions]
|
282
|
-
versions.each { |v| active[v].try(:store!, new_file) } unless active.empty?
|
283
|
-
else
|
284
|
-
active_versions.each { |name, v| v.store!(new_file) }
|
285
|
-
end
|
332
|
+
def store_versions!(new_file)
|
333
|
+
active_versions.each_value { |v| v.store!(new_file) }
|
286
334
|
end
|
287
335
|
|
288
336
|
def remove_versions!
|
289
|
-
versions.
|
337
|
+
versions.each_value { |v| v.remove! }
|
290
338
|
end
|
291
339
|
|
292
340
|
def retrieve_versions_from_cache!(cache_name)
|
293
|
-
|
341
|
+
active_versions.each_value { |v| v.retrieve_from_cache!(cache_name) }
|
294
342
|
end
|
295
343
|
|
296
344
|
def retrieve_versions_from_store!(identifier)
|
297
|
-
|
345
|
+
active_versions.each_value { |v| v.retrieve_from_store!(identifier) }
|
298
346
|
end
|
299
347
|
|
300
348
|
end # Versions
|
data/lib/carrierwave/uploader.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require "carrierwave/uploader/configuration"
|
4
2
|
require "carrierwave/uploader/callbacks"
|
5
3
|
require "carrierwave/uploader/proxy"
|
@@ -9,10 +7,12 @@ require "carrierwave/uploader/cache"
|
|
9
7
|
require "carrierwave/uploader/store"
|
10
8
|
require "carrierwave/uploader/download"
|
11
9
|
require "carrierwave/uploader/remove"
|
12
|
-
require "carrierwave/uploader/
|
13
|
-
require "carrierwave/uploader/
|
14
|
-
require "carrierwave/uploader/
|
15
|
-
require "carrierwave/uploader/
|
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
|
+
require "carrierwave/uploader/file_size"
|
15
|
+
require "carrierwave/uploader/dimension"
|
16
16
|
require "carrierwave/uploader/processing"
|
17
17
|
require "carrierwave/uploader/versions"
|
18
18
|
require "carrierwave/uploader/default_url"
|
@@ -53,10 +53,12 @@ module CarrierWave
|
|
53
53
|
include CarrierWave::Uploader::Store
|
54
54
|
include CarrierWave::Uploader::Download
|
55
55
|
include CarrierWave::Uploader::Remove
|
56
|
-
include CarrierWave::Uploader::
|
57
|
-
include CarrierWave::Uploader::
|
58
|
-
include CarrierWave::Uploader::
|
59
|
-
include CarrierWave::Uploader::
|
56
|
+
include CarrierWave::Uploader::ExtensionAllowlist
|
57
|
+
include CarrierWave::Uploader::ExtensionDenylist
|
58
|
+
include CarrierWave::Uploader::ContentTypeAllowlist
|
59
|
+
include CarrierWave::Uploader::ContentTypeDenylist
|
60
|
+
include CarrierWave::Uploader::FileSize
|
61
|
+
include CarrierWave::Uploader::Dimension
|
60
62
|
include CarrierWave::Uploader::Processing
|
61
63
|
include CarrierWave::Uploader::Versions
|
62
64
|
include CarrierWave::Uploader::DefaultUrl
|