carrierwave 0.9.0 → 0.10.0
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 +7 -0
- data/README.md +69 -9
- data/lib/carrierwave.rb +7 -0
- data/lib/carrierwave/compatibility/paperclip.rb +29 -19
- data/lib/carrierwave/locale/el.yml +11 -0
- data/lib/carrierwave/locale/es.yml +11 -0
- data/lib/carrierwave/locale/fr.yml +11 -0
- data/lib/carrierwave/locale/ja.yml +11 -0
- data/lib/carrierwave/locale/nb.yml +11 -0
- data/lib/carrierwave/locale/pl.yml +11 -0
- data/lib/carrierwave/locale/pt-BR.yml +11 -0
- data/lib/carrierwave/locale/pt-PT.yml +11 -0
- data/lib/carrierwave/locale/ru.yml +11 -0
- data/lib/carrierwave/locale/tr.yml +11 -0
- data/lib/carrierwave/mount.rb +39 -36
- data/lib/carrierwave/orm/activerecord.rb +1 -0
- data/lib/carrierwave/processing/mime_types.rb +1 -0
- data/lib/carrierwave/processing/mini_magick.rb +12 -5
- data/lib/carrierwave/processing/rmagick.rb +6 -18
- data/lib/carrierwave/sanitized_file.rb +6 -1
- data/lib/carrierwave/storage/fog.rb +6 -5
- data/lib/carrierwave/uploader/configuration.rb +8 -0
- data/lib/carrierwave/uploader/download.rb +16 -10
- data/lib/carrierwave/uploader/processing.rb +15 -17
- data/lib/carrierwave/uploader/proxy.rb +11 -0
- data/lib/carrierwave/uploader/serialization.rb +1 -1
- data/lib/carrierwave/uploader/versions.rb +45 -44
- data/lib/carrierwave/utilities.rb +2 -1
- data/lib/carrierwave/utilities/deprecation.rb +18 -0
- data/lib/carrierwave/validations/active_model.rb +0 -2
- data/lib/carrierwave/version.rb +1 -1
- data/lib/generators/templates/uploader.rb +1 -1
- data/lib/generators/uploader_generator.rb +1 -1
- metadata +100 -72
@@ -28,6 +28,7 @@ module CarrierWave
|
|
28
28
|
after_save :"store_#{column}!"
|
29
29
|
before_save :"write_#{column}_identifier"
|
30
30
|
after_commit :"remove_#{column}!", :on => :destroy
|
31
|
+
after_commit :"mark_remove_#{column}_false", :on => :update
|
31
32
|
before_update :"store_previous_model_for_#{column}"
|
32
33
|
after_save :"remove_previously_stored_#{column}"
|
33
34
|
|
@@ -27,6 +27,7 @@ module CarrierWave
|
|
27
27
|
extend ActiveSupport::Concern
|
28
28
|
|
29
29
|
included do
|
30
|
+
CarrierWave::Utilities::Deprecation.new "0.11.0", "CarrierWave::MimeTypes is deprecated and will be removed in the future, get the content_type from the SanitizedFile object directly."
|
30
31
|
begin
|
31
32
|
require "mime/types"
|
32
33
|
rescue LoadError => e
|
@@ -258,12 +258,19 @@ module CarrierWave
|
|
258
258
|
def manipulate!
|
259
259
|
cache_stored_file! if !cached?
|
260
260
|
image = ::MiniMagick::Image.open(current_path)
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
261
|
+
|
262
|
+
begin
|
263
|
+
image.format(@format.to_s.downcase) if @format
|
264
|
+
image = yield(image)
|
265
|
+
image.write(current_path)
|
266
|
+
image.run_command("identify", current_path)
|
267
|
+
ensure
|
268
|
+
image.destroy!
|
269
|
+
end
|
265
270
|
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
266
|
-
|
271
|
+
default = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :locale => :en)
|
272
|
+
message = I18n.translate(:"errors.messages.mini_magick_processing_error", :e => e, :default => default)
|
273
|
+
raise CarrierWave::ProcessingError, message
|
267
274
|
end
|
268
275
|
|
269
276
|
end # MiniMagick
|
@@ -62,8 +62,6 @@ module CarrierWave
|
|
62
62
|
|
63
63
|
included do
|
64
64
|
begin
|
65
|
-
require "rmagick"
|
66
|
-
rescue LoadError
|
67
65
|
require "RMagick"
|
68
66
|
rescue LoadError => e
|
69
67
|
e.message << " (You may need to install the rmagick gem)"
|
@@ -215,7 +213,7 @@ module CarrierWave
|
|
215
213
|
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
|
216
214
|
manipulate! do |img|
|
217
215
|
img.resize_to_fit!(width, height)
|
218
|
-
new_img = ::Magick::Image.new(width, height) { self.background_color = 'rgba(255,255,255,0)' }
|
216
|
+
new_img = ::Magick::Image.new(width, height) { self.background_color = background == :transparent ? 'rgba(255,255,255,0)' : background.to_s }
|
219
217
|
if background == :transparent
|
220
218
|
filled = new_img.matte_floodfill(1, 1)
|
221
219
|
else
|
@@ -315,23 +313,13 @@ module CarrierWave
|
|
315
313
|
|
316
314
|
read_block = create_info_block(options[:read])
|
317
315
|
image = ::Magick::Image.read(current_path, &read_block)
|
316
|
+
frames = ::Magick::ImageList.new
|
318
317
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
processed_frame = if block_given?
|
323
|
-
yield *[frame, index, options].take(block.arity)
|
324
|
-
else
|
325
|
-
frame
|
326
|
-
end
|
327
|
-
list << processed_frame if processed_frame
|
328
|
-
end
|
329
|
-
block_given? ? list : list.append(true)
|
330
|
-
else
|
331
|
-
frame = image.first
|
332
|
-
frame = yield( *[frame, 0, options].take(block.arity) ) if block_given?
|
333
|
-
frame
|
318
|
+
image.each_with_index do |frame, index|
|
319
|
+
frame = yield *[frame, index, options].take(block.arity) if block_given?
|
320
|
+
frames << frame if frame
|
334
321
|
end
|
322
|
+
frames.append(true) if block_given?
|
335
323
|
|
336
324
|
write_block = create_info_block(options[:write])
|
337
325
|
if options[:format] || @format
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'active_support/core_ext/string/multibyte'
|
5
|
+
require 'mime/types'
|
5
6
|
|
6
7
|
module CarrierWave
|
7
8
|
|
@@ -244,7 +245,11 @@ module CarrierWave
|
|
244
245
|
#
|
245
246
|
def content_type
|
246
247
|
return @content_type if @content_type
|
247
|
-
|
248
|
+
if @file.respond_to?(:content_type) and @file.content_type
|
249
|
+
@content_type = @file.content_type.to_s.chomp
|
250
|
+
elsif path
|
251
|
+
@content_type = ::MIME::Types.type_for(path).first.to_s
|
252
|
+
end
|
248
253
|
end
|
249
254
|
|
250
255
|
##
|
@@ -137,13 +137,13 @@ module CarrierWave
|
|
137
137
|
# [NilClass] no authenticated url available
|
138
138
|
#
|
139
139
|
def authenticated_url(options = {})
|
140
|
-
if ['AWS', 'Google', 'Rackspace'].include?(@uploader.fog_credentials[:provider])
|
140
|
+
if ['AWS', 'Google', 'Rackspace', 'OpenStack'].include?(@uploader.fog_credentials[:provider])
|
141
141
|
# avoid a get by using local references
|
142
142
|
local_directory = connection.directories.new(:key => @uploader.fog_directory)
|
143
143
|
local_file = local_directory.files.new(:key => path)
|
144
144
|
if @uploader.fog_credentials[:provider] == "AWS"
|
145
145
|
local_file.url(::Fog::Time.now + @uploader.fog_authenticated_url_expiration, options)
|
146
|
-
elsif @uploader.fog_credentials[:provider]
|
146
|
+
elsif ['Rackspace', 'OpenStack'].include?(@uploader.fog_credentials[:provider])
|
147
147
|
connection.get_object_https_url(@uploader.fog_directory, path, ::Fog::Time.now + @uploader.fog_authenticated_url_expiration)
|
148
148
|
else
|
149
149
|
local_file.url(::Fog::Time.now + @uploader.fog_authenticated_url_expiration)
|
@@ -192,10 +192,11 @@ module CarrierWave
|
|
192
192
|
#
|
193
193
|
# === Returns
|
194
194
|
#
|
195
|
-
# [String] extension of file
|
195
|
+
# [String] extension of file or nil if the file has no extension
|
196
196
|
#
|
197
197
|
def extension
|
198
|
-
path.split('.')
|
198
|
+
path_elements = path.split('.')
|
199
|
+
path_elements.last if path_elements.size > 1
|
199
200
|
end
|
200
201
|
|
201
202
|
##
|
@@ -338,7 +339,7 @@ module CarrierWave
|
|
338
339
|
#
|
339
340
|
def filename(options = {})
|
340
341
|
if file_url = url(options)
|
341
|
-
URI.decode(file_url).gsub(/.*\/(.*?$)/, '\1')
|
342
|
+
URI.decode(file_url).gsub(/.*\/(.*?$)/, '\1').split('?').first
|
342
343
|
end
|
343
344
|
end
|
344
345
|
|
@@ -78,8 +78,14 @@ module CarrierWave
|
|
78
78
|
|
79
79
|
def add_config(name)
|
80
80
|
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
|
85
|
+
|
81
86
|
def self.#{name}(value=nil)
|
82
87
|
@#{name} = value if value
|
88
|
+
eager_load_fog(value) if value && '#{name}' == 'fog_credentials'
|
83
89
|
return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
|
84
90
|
name = superclass.#{name}
|
85
91
|
return nil if name.nil? && !instance_variable_defined?("@#{name}")
|
@@ -87,10 +93,12 @@ module CarrierWave
|
|
87
93
|
end
|
88
94
|
|
89
95
|
def self.#{name}=(value)
|
96
|
+
eager_load_fog(value) if '#{name}' == 'fog_credentials'
|
90
97
|
@#{name} = value
|
91
98
|
end
|
92
99
|
|
93
100
|
def #{name}=(value)
|
101
|
+
self.class.eager_load_fog(value) if '#{name}' == 'fog_credentials'
|
94
102
|
@#{name} = value
|
95
103
|
end
|
96
104
|
|
@@ -17,11 +17,12 @@ module CarrierWave
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def original_filename
|
20
|
-
|
21
|
-
|
22
|
-
|
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}"
|
23
24
|
end
|
24
|
-
|
25
|
+
filename
|
25
26
|
end
|
26
27
|
|
27
28
|
def respond_to?(*args)
|
@@ -45,6 +46,13 @@ module CarrierWave
|
|
45
46
|
raise CarrierWave::DownloadError, "could not download file: #{e.message}"
|
46
47
|
end
|
47
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
|
+
|
48
56
|
def method_missing(*args, &block)
|
49
57
|
file.send(*args, &block)
|
50
58
|
end
|
@@ -58,12 +66,10 @@ module CarrierWave
|
|
58
66
|
# [url (String)] The URL where the remote file is stored
|
59
67
|
#
|
60
68
|
def download!(uri)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
cache!(file)
|
66
|
-
end
|
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?
|
72
|
+
cache!(file)
|
67
73
|
end
|
68
74
|
|
69
75
|
##
|
@@ -54,20 +54,14 @@ module CarrierWave
|
|
54
54
|
# end
|
55
55
|
#
|
56
56
|
def process(*args)
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
new_processors = args.inject({}) do |hash, arg|
|
58
|
+
arg = { arg => [] } unless arg.is_a?(Hash)
|
59
|
+
hash.merge!(arg)
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
arg.each do |method, args|
|
66
|
-
self.processors += [[method, args, condition]]
|
67
|
-
end
|
68
|
-
else
|
69
|
-
self.processors += [[arg, [], nil]]
|
70
|
-
end
|
62
|
+
condition = new_processors.delete(:if)
|
63
|
+
new_processors.each do |processor, processor_args|
|
64
|
+
self.processors += [[processor, processor_args, condition]]
|
71
65
|
end
|
72
66
|
end
|
73
67
|
|
@@ -77,13 +71,17 @@ module CarrierWave
|
|
77
71
|
# Apply all process callbacks added through CarrierWave.process
|
78
72
|
#
|
79
73
|
def process!(new_file=nil)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
74
|
+
return unless enable_processing
|
75
|
+
|
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)
|
84
82
|
end
|
85
|
-
self.send(method, *args)
|
86
83
|
end
|
84
|
+
self.send(method, *args)
|
87
85
|
end
|
88
86
|
end
|
89
87
|
|
@@ -72,6 +72,17 @@ module CarrierWave
|
|
72
72
|
size
|
73
73
|
end
|
74
74
|
|
75
|
+
##
|
76
|
+
# Read the content type of the file
|
77
|
+
#
|
78
|
+
# === Returns
|
79
|
+
#
|
80
|
+
# [String] content type of the file
|
81
|
+
#
|
82
|
+
def content_type
|
83
|
+
file.respond_to?(:content_type) ? file.content_type : nil
|
84
|
+
end
|
85
|
+
|
75
86
|
end # Proxy
|
76
87
|
end # Uploader
|
77
88
|
end # CarrierWave
|
@@ -50,23 +50,39 @@ module CarrierWave
|
|
50
50
|
#
|
51
51
|
def version(name, options = {}, &block)
|
52
52
|
name = name.to_sym
|
53
|
-
unless versions[name]
|
54
|
-
uploader = Class.new(self)
|
55
|
-
const_set("Uploader#{uploader.object_id}".gsub('-', '_'), uploader)
|
56
|
-
uploader.versions = {}
|
53
|
+
build_version(name, options) unless versions[name]
|
57
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
|
58
76
|
# Define the enable_processing method for versions so they get the
|
59
77
|
# value from the parent class unless explicitly overwritten
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
superclass.enable_processing
|
67
|
-
end
|
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
|
68
84
|
end
|
69
|
-
|
85
|
+
end
|
70
86
|
|
71
87
|
# Regardless of what is set in the parent uploader, do not enforce the
|
72
88
|
# move_to_cache config option on versions because it moves the original
|
@@ -81,42 +97,27 @@ module CarrierWave
|
|
81
97
|
# end
|
82
98
|
# end
|
83
99
|
#
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
100
|
+
def move_to_cache
|
101
|
+
false
|
102
|
+
end
|
103
|
+
RUBY
|
104
|
+
|
105
|
+
class_eval <<-RUBY
|
106
|
+
def #{name}
|
107
|
+
versions[:#{name}]
|
108
|
+
end
|
109
|
+
RUBY
|
89
110
|
|
90
|
-
|
91
|
-
|
92
|
-
|
111
|
+
# Add the current version hash to class attribute :versions
|
112
|
+
current_version = {
|
113
|
+
name => {
|
93
114
|
:uploader => uploader,
|
94
115
|
:options => options
|
95
116
|
}
|
96
|
-
|
97
|
-
|
98
|
-
versions[name][:uploader].version_names += [name]
|
99
|
-
|
100
|
-
class_eval <<-RUBY
|
101
|
-
def #{name}
|
102
|
-
versions[:#{name}]
|
103
|
-
end
|
104
|
-
RUBY
|
105
|
-
# as the processors get the output from the previous processors as their
|
106
|
-
# input we must not stack the processors here
|
107
|
-
versions[name][:uploader].processors = versions[name][:uploader].processors.dup
|
108
|
-
versions[name][:uploader].processors.clear
|
109
|
-
end
|
110
|
-
versions[name][:uploader].class_eval(&block) if block
|
111
|
-
versions[name]
|
117
|
+
}
|
118
|
+
self.versions = versions.merge(current_version)
|
112
119
|
end
|
113
120
|
|
114
|
-
def recursively_apply_block_to_versions(&block)
|
115
|
-
versions.each do |name, version|
|
116
|
-
version[:uploader].class_eval(&block)
|
117
|
-
version[:uploader].recursively_apply_block_to_versions(&block)
|
118
|
-
end
|
119
|
-
end
|
120
121
|
end # ClassMethods
|
121
122
|
|
122
123
|
##
|
@@ -199,7 +200,7 @@ module CarrierWave
|
|
199
200
|
if (version = args.first) && version.respond_to?(:to_sym)
|
200
201
|
raise ArgumentError, "Version #{version} doesn't exist!" if versions[version.to_sym].nil?
|
201
202
|
# recursively proxy to version
|
202
|
-
versions[version.to_sym].url(*args[1..-1])
|
203
|
+
versions[version.to_sym].url(*args[1..-1])
|
203
204
|
elsif args.first
|
204
205
|
super(args.first)
|
205
206
|
else
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'active_support/deprecation'
|
3
|
+
|
4
|
+
module CarrierWave
|
5
|
+
module Utilities
|
6
|
+
module Deprecation
|
7
|
+
|
8
|
+
def self.new version = '0.11.0', message = 'Carrierwave'
|
9
|
+
if ActiveSupport::VERSION::MAJOR < 4
|
10
|
+
ActiveSupport::Deprecation.warn("#{message} (will be removed from version #{version})")
|
11
|
+
else
|
12
|
+
ActiveSupport::Deprecation.new(version, message)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end # Deprecation
|
17
|
+
end # Utilities
|
18
|
+
end # CarrierWave
|