carrierwave 0.5.8 → 0.6.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.
- data/README.md +92 -61
- data/lib/carrierwave.rb +11 -16
- data/lib/carrierwave/mount.rb +4 -4
- data/lib/carrierwave/orm/activerecord.rb +16 -0
- data/lib/carrierwave/processing/mime_types.rb +1 -1
- data/lib/carrierwave/processing/mini_magick.rb +5 -3
- data/lib/carrierwave/processing/rmagick.rb +2 -2
- data/lib/carrierwave/sanitized_file.rb +2 -2
- data/lib/carrierwave/storage/file.rb +3 -3
- data/lib/carrierwave/storage/fog.rb +33 -8
- data/lib/carrierwave/test/matchers.rb +3 -3
- data/lib/carrierwave/uploader.rb +1 -0
- data/lib/carrierwave/uploader/cache.rb +3 -3
- data/lib/carrierwave/uploader/configuration.rb +4 -36
- data/lib/carrierwave/uploader/download.rb +1 -1
- data/lib/carrierwave/uploader/mountable.rb +2 -2
- data/lib/carrierwave/uploader/processing.rb +3 -1
- data/lib/carrierwave/uploader/serialization.rb +30 -0
- data/lib/carrierwave/uploader/store.rb +0 -2
- data/lib/carrierwave/uploader/url.rb +8 -23
- data/lib/carrierwave/uploader/versions.rb +37 -20
- data/lib/carrierwave/validations/active_model.rb +1 -2
- data/lib/carrierwave/version.rb +1 -1
- data/lib/generators/templates/uploader.rb +7 -0
- metadata +121 -180
- data/lib/carrierwave/storage/cloud_files.rb +0 -188
- data/lib/carrierwave/storage/right_s3.rb +0 -1
- data/lib/carrierwave/storage/s3.rb +0 -240
data/lib/carrierwave.rb
CHANGED
@@ -4,13 +4,7 @@ require 'fileutils'
|
|
4
4
|
require 'active_support/core_ext/object/blank'
|
5
5
|
require 'active_support/core_ext/class/attribute'
|
6
6
|
|
7
|
-
begin
|
8
|
-
require 'active_support/core_ext/class/inheritable_attributes'
|
9
|
-
rescue LoadError
|
10
|
-
end
|
11
|
-
|
12
7
|
require 'active_support/concern'
|
13
|
-
require 'active_support/memoizable'
|
14
8
|
|
15
9
|
module CarrierWave
|
16
10
|
|
@@ -44,10 +38,6 @@ module CarrierWave
|
|
44
38
|
autoload :Abstract, 'carrierwave/storage/abstract'
|
45
39
|
autoload :File, 'carrierwave/storage/file'
|
46
40
|
autoload :Fog, 'carrierwave/storage/fog'
|
47
|
-
autoload :S3, 'carrierwave/storage/s3'
|
48
|
-
autoload :GridFS, 'carrierwave/storage/grid_fs'
|
49
|
-
autoload :RightS3, 'carrierwave/storage/right_s3'
|
50
|
-
autoload :CloudFiles, 'carrierwave/storage/cloud_files'
|
51
41
|
end
|
52
42
|
|
53
43
|
module Uploader
|
@@ -65,6 +55,7 @@ module CarrierWave
|
|
65
55
|
autoload :Url, 'carrierwave/uploader/url'
|
66
56
|
autoload :Mountable, 'carrierwave/uploader/mountable'
|
67
57
|
autoload :Configuration, 'carrierwave/uploader/configuration'
|
58
|
+
autoload :Serialization, 'carrierwave/uploader/serialization'
|
68
59
|
end
|
69
60
|
|
70
61
|
module Compatibility
|
@@ -104,13 +95,17 @@ elsif defined?(Rails)
|
|
104
95
|
end
|
105
96
|
|
106
97
|
elsif defined?(Sinatra)
|
107
|
-
|
108
|
-
|
109
|
-
# Sinatra >= 1.3
|
110
|
-
Sinatra::Application.public_folder
|
98
|
+
if defined?(Padrino)
|
99
|
+
CarrierWave.root = File.join(PADRINO_ROOT, "public")
|
111
100
|
else
|
112
|
-
|
113
|
-
Sinatra::Application.
|
101
|
+
|
102
|
+
CarrierWave.root = if Sinatra::Application.respond_to?(:public_folder)
|
103
|
+
# Sinatra >= 1.3
|
104
|
+
Sinatra::Application.public_folder
|
105
|
+
else
|
106
|
+
# Sinatra < 1.3
|
107
|
+
Sinatra::Application.public
|
108
|
+
end
|
114
109
|
end
|
115
110
|
|
116
111
|
end
|
data/lib/carrierwave/mount.rb
CHANGED
@@ -281,8 +281,6 @@ module CarrierWave
|
|
281
281
|
# this is an internal class, used by CarrierWave::Mount so that
|
282
282
|
# we don't pollute the model with a lot of methods.
|
283
283
|
class Mounter #:nodoc:
|
284
|
-
extend ActiveSupport::Memoizable
|
285
|
-
|
286
284
|
attr_reader :column, :record, :remote_url, :integrity_error, :processing_error
|
287
285
|
attr_accessor :remove
|
288
286
|
|
@@ -369,12 +367,14 @@ module CarrierWave
|
|
369
367
|
option(:mount_on) || column
|
370
368
|
end
|
371
369
|
|
370
|
+
attr_accessor :uploader_options
|
371
|
+
|
372
372
|
private
|
373
373
|
|
374
374
|
def option(name)
|
375
|
-
|
375
|
+
self.uploader_options ||= {}
|
376
|
+
self.uploader_options[name] ||= record.class.uploader_option(column, name)
|
376
377
|
end
|
377
|
-
memoize :option
|
378
378
|
|
379
379
|
end # Mounter
|
380
380
|
|
@@ -36,6 +36,22 @@ module CarrierWave
|
|
36
36
|
send(:"\#{column}_will_change!")
|
37
37
|
super
|
38
38
|
end
|
39
|
+
|
40
|
+
def remote_#{column}_url=(url)
|
41
|
+
column = _mounter(:#{column}).serialization_column
|
42
|
+
send(:"\#{column}_will_change!")
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
def serializable_hash(options=nil)
|
47
|
+
hash = {}
|
48
|
+
self.class.uploaders.each do |column, uploader|
|
49
|
+
if (!options[:only] && !options[:except]) || (options[:only] && options[:only].include?(column)) || (options[:except] && !options[:except].include?(column))
|
50
|
+
hash[column.to_s] = _mounter(:#{column}).uploader.serializable_hash
|
51
|
+
end
|
52
|
+
end
|
53
|
+
super(options).merge(hash)
|
54
|
+
end
|
39
55
|
RUBY
|
40
56
|
|
41
57
|
end
|
@@ -47,7 +47,7 @@ module CarrierWave
|
|
47
47
|
if file.respond_to?(:content_type=)
|
48
48
|
file.content_type = new_content_type
|
49
49
|
else
|
50
|
-
file.
|
50
|
+
file.instance_variable_set(:@content_type, new_content_type)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
rescue ::MIME::InvalidContentType => e
|
@@ -70,8 +70,8 @@ module CarrierWave
|
|
70
70
|
process :resize_to_fit => [width, height]
|
71
71
|
end
|
72
72
|
|
73
|
-
def resize_to_fill(width, height)
|
74
|
-
process :resize_to_fill => [width, height]
|
73
|
+
def resize_to_fill(width, height, gravity='Center')
|
74
|
+
process :resize_to_fill => [width, height, gravity]
|
75
75
|
end
|
76
76
|
|
77
77
|
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
|
@@ -158,6 +158,7 @@ module CarrierWave
|
|
158
158
|
#
|
159
159
|
# [width (Integer)] the width to scale the image to
|
160
160
|
# [height (Integer)] the height to scale the image to
|
161
|
+
# [gravity (String)] the current gravity suggestion (default: 'Center'; options: 'NorthWest', 'North', 'NorthEast', 'West', 'Center', 'East', 'SouthWest', 'South', 'SouthEast')
|
161
162
|
#
|
162
163
|
# === Yields
|
163
164
|
#
|
@@ -174,6 +175,7 @@ module CarrierWave
|
|
174
175
|
cmd.resize "#{cols}x#{rows}"
|
175
176
|
end
|
176
177
|
cmd.gravity gravity
|
178
|
+
cmd.background "rgba(255,255,255,0.0)"
|
177
179
|
cmd.extent "#{width}x#{height}" if cols != width || rows != height
|
178
180
|
end
|
179
181
|
img = yield(img) if block_given?
|
@@ -206,7 +208,7 @@ module CarrierWave
|
|
206
208
|
img.combine_options do |cmd|
|
207
209
|
cmd.thumbnail "#{width}x#{height}>"
|
208
210
|
if background == :transparent
|
209
|
-
cmd.background "rgba(
|
211
|
+
cmd.background "rgba(255, 255, 255, 0.0)"
|
210
212
|
else
|
211
213
|
cmd.background background
|
212
214
|
end
|
@@ -250,9 +250,9 @@ module CarrierWave
|
|
250
250
|
frames = if image.size > 1
|
251
251
|
list = ::Magick::ImageList.new
|
252
252
|
image.each do |frame|
|
253
|
-
list << yield( frame )
|
253
|
+
list << (block_given? ? yield( frame ) : frame)
|
254
254
|
end
|
255
|
-
list
|
255
|
+
block_given? ? list : list.append(true)
|
256
256
|
else
|
257
257
|
frame = image.first
|
258
258
|
frame = yield( frame ) if block_given?
|
@@ -132,7 +132,7 @@ module CarrierWave
|
|
132
132
|
# [Boolean] whether the file is valid and has a non-zero size
|
133
133
|
#
|
134
134
|
def empty?
|
135
|
-
@file.nil? || self.size.nil? || self.size.zero?
|
135
|
+
@file.nil? || self.size.nil? || (self.size.zero? && ! self.exists?)
|
136
136
|
end
|
137
137
|
|
138
138
|
##
|
@@ -238,7 +238,7 @@ module CarrierWave
|
|
238
238
|
#
|
239
239
|
def content_type
|
240
240
|
return @content_type if @content_type
|
241
|
-
@file.content_type.chomp if @file.respond_to?(:content_type) and @file.content_type
|
241
|
+
@file.content_type.to_s.chomp if @file.respond_to?(:content_type) and @file.content_type
|
242
242
|
end
|
243
243
|
|
244
244
|
##
|
@@ -13,11 +13,11 @@ module CarrierWave
|
|
13
13
|
##
|
14
14
|
# Move the file to the uploader's store path.
|
15
15
|
#
|
16
|
-
# By default, store!() uses copy_to(), which operates by copying the file
|
17
|
-
# from the cache to the store, then deleting the file from the cache.
|
16
|
+
# By default, store!() uses copy_to(), which operates by copying the file
|
17
|
+
# from the cache to the store, then deleting the file from the cache.
|
18
18
|
# If move_to_store() is overriden to return true, then store!() uses move_to(),
|
19
19
|
# which simply moves the file from cache to store. Useful for large files.
|
20
|
-
#
|
20
|
+
#
|
21
21
|
# === Parameters
|
22
22
|
#
|
23
23
|
# [file (CarrierWave::SanitizedFile)] the file to store
|
@@ -62,6 +62,11 @@ module CarrierWave
|
|
62
62
|
# end
|
63
63
|
#
|
64
64
|
class Fog < Abstract
|
65
|
+
class << self
|
66
|
+
def connection_cache
|
67
|
+
@connection_cache ||= {}
|
68
|
+
end
|
69
|
+
end
|
65
70
|
|
66
71
|
##
|
67
72
|
# Store a file
|
@@ -97,7 +102,8 @@ module CarrierWave
|
|
97
102
|
|
98
103
|
def connection
|
99
104
|
@connection ||= begin
|
100
|
-
|
105
|
+
credentials = uploader.fog_credentials
|
106
|
+
self.class.connection_cache[credentials] ||= ::Fog::Storage.new(credentials)
|
101
107
|
end
|
102
108
|
end
|
103
109
|
|
@@ -133,12 +139,16 @@ module CarrierWave
|
|
133
139
|
# or
|
134
140
|
# [NilClass] no authenticated url available
|
135
141
|
#
|
136
|
-
def authenticated_url
|
142
|
+
def authenticated_url(options = {})
|
137
143
|
if ['AWS', 'Google'].include?(@uploader.fog_credentials[:provider])
|
138
144
|
# avoid a get by using local references
|
139
145
|
local_directory = connection.directories.new(:key => @uploader.fog_directory)
|
140
146
|
local_file = local_directory.files.new(:key => path)
|
141
|
-
|
147
|
+
if @uploader.fog_credentials[:provider] == "AWS"
|
148
|
+
local_file.url(::Fog::Time.now + @uploader.fog_authenticated_url_expiration, options)
|
149
|
+
else
|
150
|
+
local_file.url(::Fog::Time.now + @uploader.fog_authenticated_url_expiration)
|
151
|
+
end
|
142
152
|
else
|
143
153
|
nil
|
144
154
|
end
|
@@ -218,6 +228,16 @@ module CarrierWave
|
|
218
228
|
file.content_length
|
219
229
|
end
|
220
230
|
|
231
|
+
##
|
232
|
+
# Check if the file exists on the remote service
|
233
|
+
#
|
234
|
+
# === Returns
|
235
|
+
#
|
236
|
+
# [Boolean] true if file exists or false
|
237
|
+
def exists?
|
238
|
+
!!directory.files.head(path)
|
239
|
+
end
|
240
|
+
|
221
241
|
##
|
222
242
|
# Write file to service
|
223
243
|
#
|
@@ -233,6 +253,7 @@ module CarrierWave
|
|
233
253
|
:key => path,
|
234
254
|
:public => @uploader.fog_public
|
235
255
|
}.merge(@uploader.fog_attributes))
|
256
|
+
fog_file.close if fog_file && !fog_file.closed?
|
236
257
|
true
|
237
258
|
end
|
238
259
|
|
@@ -247,13 +268,17 @@ module CarrierWave
|
|
247
268
|
#
|
248
269
|
def public_url
|
249
270
|
if host = @uploader.fog_host
|
250
|
-
|
271
|
+
if host.respond_to? :call
|
272
|
+
"#{host.call(self)}/#{path}"
|
273
|
+
else
|
274
|
+
"#{host}/#{path}"
|
275
|
+
end
|
251
276
|
else
|
252
277
|
# AWS/Google optimized for speed over correctness
|
253
278
|
case @uploader.fog_credentials[:provider]
|
254
279
|
when 'AWS'
|
255
280
|
# if directory is a valid subdomain, use that style for access
|
256
|
-
if @uploader.fog_directory.to_s =~ /^(?:[a-z]|\d(?!\d{0,2}(
|
281
|
+
if @uploader.fog_directory.to_s =~ /^(?:[a-z]|\d(?!\d{0,2}(?:\d{1,3}){3}$))(?:[a-z0-9]|(?![\-])|\-(?![\.])){1,61}[a-z0-9]$/
|
257
282
|
"https://#{@uploader.fog_directory}.s3.amazonaws.com/#{path}"
|
258
283
|
else
|
259
284
|
# directory is not a valid subdomain, so use path style for access
|
@@ -277,9 +302,9 @@ module CarrierWave
|
|
277
302
|
# or
|
278
303
|
# [NilClass] no url available
|
279
304
|
#
|
280
|
-
def url
|
305
|
+
def url(options = {})
|
281
306
|
if !@uploader.fog_public
|
282
|
-
authenticated_url
|
307
|
+
authenticated_url(options)
|
283
308
|
else
|
284
309
|
public_url
|
285
310
|
end
|
@@ -322,7 +347,7 @@ module CarrierWave
|
|
322
347
|
# [Fog::#{provider}::File] file data from remote service
|
323
348
|
#
|
324
349
|
def file
|
325
|
-
@file ||= directory.files.
|
350
|
+
@file ||= directory.files.head(path)
|
326
351
|
end
|
327
352
|
|
328
353
|
end
|
@@ -48,11 +48,11 @@ module CarrierWave
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def failure_message
|
51
|
-
"expected #{@actual.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
|
51
|
+
"expected #{@actual.current_path.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
|
52
52
|
end
|
53
53
|
|
54
54
|
def negative_failure_message
|
55
|
-
"expected #{@actual.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
|
55
|
+
"expected #{@actual.current_path.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
|
56
56
|
end
|
57
57
|
|
58
58
|
def description
|
@@ -182,7 +182,7 @@ module CarrierWave
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
-
def
|
185
|
+
def be_no_taller_than(height)
|
186
186
|
BeNoTallerThan.new(height)
|
187
187
|
end
|
188
188
|
|
data/lib/carrierwave/uploader.rb
CHANGED
@@ -90,9 +90,9 @@ module CarrierWave
|
|
90
90
|
##
|
91
91
|
# Caches the given file. Calls process! to trigger any process callbacks.
|
92
92
|
#
|
93
|
-
# By default, cache!() uses copy_to(), which operates by copying the file
|
94
|
-
# to the cache, then deleting the original file. If move_to_cache() is
|
95
|
-
# overriden to return true, then cache!() uses move_to(), which simply
|
93
|
+
# By default, cache!() uses copy_to(), which operates by copying the file
|
94
|
+
# to the cache, then deleting the original file. If move_to_cache() is
|
95
|
+
# overriden to return true, then cache!() uses move_to(), which simply
|
96
96
|
# moves the file to the cache. Useful for large files.
|
97
97
|
#
|
98
98
|
# === Parameters
|
@@ -11,28 +11,6 @@ module CarrierWave
|
|
11
11
|
add_config :base_path
|
12
12
|
add_config :permissions
|
13
13
|
add_config :storage_engines
|
14
|
-
add_config :s3_access_policy
|
15
|
-
add_config :s3_bucket
|
16
|
-
add_config :s3_access_key_id
|
17
|
-
add_config :s3_secret_access_key
|
18
|
-
add_config :s3_cnamed
|
19
|
-
add_config :s3_headers
|
20
|
-
add_config :s3_region
|
21
|
-
add_config :s3_use_ssl
|
22
|
-
add_config :s3_authentication_timeout
|
23
|
-
add_config :cloud_files_username
|
24
|
-
add_config :cloud_files_api_key
|
25
|
-
add_config :cloud_files_container
|
26
|
-
add_config :cloud_files_cdn_host
|
27
|
-
add_config :cloud_files_auth_url
|
28
|
-
add_config :cloud_files_snet
|
29
|
-
add_config :grid_fs_connection
|
30
|
-
add_config :grid_fs_database
|
31
|
-
add_config :grid_fs_host
|
32
|
-
add_config :grid_fs_port
|
33
|
-
add_config :grid_fs_username
|
34
|
-
add_config :grid_fs_password
|
35
|
-
add_config :grid_fs_access_url
|
36
14
|
add_config :store_dir
|
37
15
|
add_config :cache_dir
|
38
16
|
add_config :enable_processing
|
@@ -109,7 +87,8 @@ module CarrierWave
|
|
109
87
|
end
|
110
88
|
|
111
89
|
def #{name}
|
112
|
-
self.class.#{name}
|
90
|
+
value = self.class.#{name}
|
91
|
+
value.instance_of?(Proc) ? value.call : value
|
113
92
|
end
|
114
93
|
RUBY
|
115
94
|
end
|
@@ -126,20 +105,9 @@ module CarrierWave
|
|
126
105
|
config.permissions = 0644
|
127
106
|
config.storage_engines = {
|
128
107
|
:file => "CarrierWave::Storage::File",
|
129
|
-
:fog
|
130
|
-
:s3 => "CarrierWave::Storage::S3",
|
131
|
-
:grid_fs => "CarrierWave::Storage::GridFS",
|
132
|
-
:right_s3 => "CarrierWave::Storage::RightS3",
|
133
|
-
:cloud_files => "CarrierWave::Storage::CloudFiles"
|
108
|
+
:fog => "CarrierWave::Storage::Fog"
|
134
109
|
}
|
135
110
|
config.storage = :file
|
136
|
-
config.s3_headers = {}
|
137
|
-
config.s3_access_policy = :public_read
|
138
|
-
config.s3_region = 'us-east-1'
|
139
|
-
config.s3_authentication_timeout = 600
|
140
|
-
config.grid_fs_database = 'carrierwave'
|
141
|
-
config.grid_fs_host = 'localhost'
|
142
|
-
config.grid_fs_port = 27017
|
143
111
|
config.fog_attributes = {}
|
144
112
|
config.fog_credentials = {}
|
145
113
|
config.fog_public = true
|
@@ -154,7 +122,7 @@ module CarrierWave
|
|
154
122
|
config.ignore_processing_errors = true
|
155
123
|
config.validate_integrity = true
|
156
124
|
config.validate_processing = true
|
157
|
-
config.root = CarrierWave.root
|
125
|
+
config.root = lambda { CarrierWave.root }
|
158
126
|
config.base_path = CarrierWave.base_path
|
159
127
|
config.enable_processing = true
|
160
128
|
config.ensure_multipart_form = true
|
@@ -7,7 +7,7 @@ module CarrierWave
|
|
7
7
|
attr_reader :model, :mounted_as
|
8
8
|
|
9
9
|
##
|
10
|
-
# If a model is given as the first parameter, it will stored in the uploader, and
|
10
|
+
# If a model is given as the first parameter, it will be stored in the uploader, and
|
11
11
|
# available throught +#model+. Likewise, mounted_as stores the name of the column
|
12
12
|
# where this instance of the uploader is mounted. These values can then be used inside
|
13
13
|
# your uploader.
|
@@ -36,4 +36,4 @@ module CarrierWave
|
|
36
36
|
|
37
37
|
end # Mountable
|
38
38
|
end # Uploader
|
39
|
-
end # CarrierWave
|
39
|
+
end # CarrierWave
|
@@ -79,7 +79,9 @@ module CarrierWave
|
|
79
79
|
def process!(new_file=nil)
|
80
80
|
if enable_processing
|
81
81
|
self.class.processors.each do |method, args, condition|
|
82
|
-
|
82
|
+
if(condition)
|
83
|
+
next if !(condition.respond_to?(:call) ? condition.call(self, :args => args, :method => method, :file => new_file) : self.send(condition, new_file))
|
84
|
+
end
|
83
85
|
self.send(method, *args)
|
84
86
|
end
|
85
87
|
end
|