carrierwave 0.4.3 → 0.4.4
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/History.txt +22 -0
- data/Manifest.txt +4 -0
- data/README.rdoc +43 -8
- data/Rakefile +2 -1
- data/features/download.feature +20 -0
- data/features/step_definitions/download_steps.rb +4 -0
- data/features/step_definitions/file_steps.rb +12 -1
- data/lib/carrierwave.rb +7 -1
- data/lib/carrierwave/mount.rb +20 -2
- data/lib/carrierwave/orm/mongoid.rb +1 -1
- data/lib/carrierwave/processing/rmagick.rb +14 -16
- data/lib/carrierwave/storage/grid_fs.rb +10 -2
- data/lib/carrierwave/storage/right_s3.rb +18 -31
- data/lib/carrierwave/storage/s3.rb +19 -3
- data/lib/carrierwave/uploader.rb +1 -0
- data/lib/carrierwave/uploader/cache.rb +27 -1
- data/lib/carrierwave/uploader/configuration.rb +2 -0
- data/lib/carrierwave/uploader/download.rb +59 -0
- data/spec/mount_spec.rb +47 -1
- data/spec/orm/mongoid_spec.rb +4 -3
- data/spec/processing/rmagick_spec.rb +7 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/storage/grid_fs_spec.rb +7 -1
- data/spec/storage/s3_spec.rb +20 -8
- data/spec/uploader/cache_spec.rb +26 -1
- data/spec/uploader/download_spec.rb +75 -0
- metadata +39 -4
data/History.txt
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
=== Version 0.4.5 2010-02-20
|
2
|
+
|
3
|
+
* [added] Support for Rackspace Cloudfiles
|
4
|
+
* [added] GridFS now accepts a port
|
5
|
+
* [fixed] s3_headers is now properly initialized
|
6
|
+
* [fixed] work around DataMapper's patching of core method
|
7
|
+
|
8
|
+
=== Version 0.4.4 2010-01-31
|
9
|
+
|
10
|
+
* [added] Support for downloading remote files
|
11
|
+
* [added] CarrierWave.clean_cached_files! to remove old cached files
|
12
|
+
* [added] Option to set headers for S3
|
13
|
+
* [added] GridStore now has authentication
|
14
|
+
* [fixed] Rmagick convert method now does what it says
|
15
|
+
* [fixed] Content type is stored on GridStore and Amazon S3
|
16
|
+
* [fixed] Metadata is no longer broken for S3
|
17
|
+
|
18
|
+
=== Version 0.4.3 2009-12-19
|
19
|
+
|
20
|
+
* [fixed] cnamed URLs on S3 no longer have a third slash after http
|
21
|
+
* [fixed] fixed deprecation warnings on Rails 2.3.5
|
22
|
+
|
1
23
|
=== Version 0.4.2 2009-11-26
|
2
24
|
|
3
25
|
* [added] RightAWS as an alternative S3 implementation
|
data/Manifest.txt
CHANGED
@@ -5,6 +5,7 @@ README.rdoc
|
|
5
5
|
Rakefile
|
6
6
|
cucumber.yml
|
7
7
|
features/caching.feature
|
8
|
+
features/download.feature
|
8
9
|
features/file_storage.feature
|
9
10
|
features/file_storage_overridden_filename.feature
|
10
11
|
features/file_storage_overridden_store_dir.feature
|
@@ -17,6 +18,7 @@ features/mount_datamapper.feature
|
|
17
18
|
features/step_definitions/activerecord_steps.rb
|
18
19
|
features/step_definitions/caching_steps.rb
|
19
20
|
features/step_definitions/datamapper_steps.rb
|
21
|
+
features/step_definitions/download_steps.rb
|
20
22
|
features/step_definitions/file_steps.rb
|
21
23
|
features/step_definitions/general_steps.rb
|
22
24
|
features/step_definitions/mount_steps.rb
|
@@ -54,6 +56,7 @@ lib/carrierwave/uploader/cache.rb
|
|
54
56
|
lib/carrierwave/uploader/callbacks.rb
|
55
57
|
lib/carrierwave/uploader/configuration.rb
|
56
58
|
lib/carrierwave/uploader/default_url.rb
|
59
|
+
lib/carrierwave/uploader/download.rb
|
57
60
|
lib/carrierwave/uploader/extension_whitelist.rb
|
58
61
|
lib/carrierwave/uploader/mountable.rb
|
59
62
|
lib/carrierwave/uploader/processing.rb
|
@@ -92,6 +95,7 @@ spec/storage/s3_spec.rb
|
|
92
95
|
spec/uploader/cache_spec.rb
|
93
96
|
spec/uploader/configuration_spec.rb
|
94
97
|
spec/uploader/default_url_spec.rb
|
98
|
+
spec/uploader/download_spec.rb
|
95
99
|
spec/uploader/extension_whitelist_spec.rb
|
96
100
|
spec/uploader/mountable_spec.rb
|
97
101
|
spec/uploader/paths_spec.rb
|
data/README.rdoc
CHANGED
@@ -13,6 +13,7 @@ upload files.
|
|
13
13
|
* Source code {hosted at GitHub}[http://github.com/jnicklas/carrierwave]
|
14
14
|
* Please {report any issues}[http://github.com/jnicklas/carrierwave/issues] on GitHub
|
15
15
|
* Please direct any questions at the {mailing list}[http://groups.google.com/group/carrierwave]
|
16
|
+
* Check out the {example app}[http://github.com/jnicklas/carrierwave-example-app]
|
16
17
|
|
17
18
|
== Getting Started
|
18
19
|
|
@@ -20,8 +21,6 @@ Install the latest stable release:
|
|
20
21
|
|
21
22
|
[sudo] gem install carrierwave
|
22
23
|
|
23
|
-
CarrierWave is hosted *only* on {Gemcutter}[http://gemcutter.org] as of version 0.4.0.
|
24
|
-
|
25
24
|
In Merb, add it as a dependency to your config/dependencies.rb:
|
26
25
|
|
27
26
|
dependency 'carrierwave'
|
@@ -183,12 +182,48 @@ case of images, a small thumbnail would be a good indicator:
|
|
183
182
|
<% form_for @user do |f| %>
|
184
183
|
<p>
|
185
184
|
<label>My Avatar</label>
|
186
|
-
<%= image_tag(@user.
|
185
|
+
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
187
186
|
<%= f.file_field :avatar %>
|
188
187
|
<%= f.hidden_field :avatar_cache %>
|
189
188
|
</p>
|
190
189
|
<% end %>
|
191
190
|
|
191
|
+
== Removing uploaded files
|
192
|
+
|
193
|
+
If you want to remove a previously uploaded file on a mounted uploader, you can
|
194
|
+
easily add a checkbox to the form which will remove the file when checked.
|
195
|
+
|
196
|
+
<% form_for @user do |f| %>
|
197
|
+
<p>
|
198
|
+
<label>My Avatar</label>
|
199
|
+
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
200
|
+
<%= f.file_field :avatar %>
|
201
|
+
</p>
|
202
|
+
|
203
|
+
<p>
|
204
|
+
<label>
|
205
|
+
<%= f.check_box :remove_avatar %>
|
206
|
+
Remove avatar
|
207
|
+
</label>
|
208
|
+
</p>
|
209
|
+
<% end %>
|
210
|
+
|
211
|
+
If you want to remove the file manually, you can call <code>remove_avatar!</code>.
|
212
|
+
|
213
|
+
== Uploading files from a remote location
|
214
|
+
|
215
|
+
Your users may find it convenient to upload a file from a location on the Internet
|
216
|
+
via a URL. CarrierWave makes this simple, just add the appropriate column to your
|
217
|
+
form and you're good to go:
|
218
|
+
|
219
|
+
<% form_for @user do |f| %>
|
220
|
+
<p>
|
221
|
+
<label>My Avatar URL:</label>
|
222
|
+
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
223
|
+
<%= f.text_field :remote_avatar_url %>
|
224
|
+
</p>
|
225
|
+
<% end %>
|
226
|
+
|
192
227
|
== Providing a default URL
|
193
228
|
|
194
229
|
In many cases, especially when working with images, it might be a good idea to
|
@@ -224,7 +259,7 @@ tests, it's recommended to switch off processing in your tests, and to use the
|
|
224
259
|
file storage. In Rails you could do that by adding an initializer with:
|
225
260
|
|
226
261
|
if Rails.env.test?
|
227
|
-
|
262
|
+
CarrierWave.configure do |config|
|
228
263
|
config.storage = :file
|
229
264
|
config.enable_processing = false
|
230
265
|
end
|
@@ -283,7 +318,7 @@ And then in your uploader, set the storage to :s3
|
|
283
318
|
storage :s3
|
284
319
|
end
|
285
320
|
|
286
|
-
That's it! You can still use the
|
321
|
+
That's it! You can still use the <code>CarrierWave::Uploader#url</code> method to return
|
287
322
|
the url to the file on Amazon S3.
|
288
323
|
|
289
324
|
Alternatively, and especially if your bucket is located in Europe, you can use the
|
@@ -308,7 +343,7 @@ You'll need to configure the database and host to use:
|
|
308
343
|
|
309
344
|
The defaults are 'carrierwave' and 'localhost'.
|
310
345
|
|
311
|
-
And then in your uploader, set the storage to
|
346
|
+
And then in your uploader, set the storage to <code>:grid_fs</code>:
|
312
347
|
|
313
348
|
class AvatarUploader < CarrierWave::Uploader::Base
|
314
349
|
storage :grid_fs
|
@@ -335,7 +370,7 @@ include it in your Uploader:
|
|
335
370
|
end
|
336
371
|
|
337
372
|
The RMagick module gives you a few methods, like
|
338
|
-
|
373
|
+
<code>CarrierWave::RMagick#resize_to_fill</code> which manipulate the image file in some
|
339
374
|
way. You can set a +process+ callback, which will call that method any time a
|
340
375
|
file is uploaded.
|
341
376
|
|
@@ -394,7 +429,7 @@ If you are using Paperclip, you can use the provided compatibility module:
|
|
394
429
|
include CarrierWave::Compatibility::Paperclip
|
395
430
|
end
|
396
431
|
|
397
|
-
See the documentation for
|
432
|
+
See the documentation for <code>Paperclip::Compatibility::Paperclip</code> for more
|
398
433
|
detaills.
|
399
434
|
|
400
435
|
Be sure to use mount_on to specify the correct column:
|
data/Rakefile
CHANGED
@@ -26,8 +26,9 @@ $hoe = Hoe.spec 'carrierwave' do
|
|
26
26
|
self.extra_dev_deps << ['rmagick', '>=2.10.0']
|
27
27
|
self.extra_dev_deps << ['mini_magick', '>=1.2.5']
|
28
28
|
self.extra_dev_deps << ['mongo_mapper', '>=0.6.8']
|
29
|
-
self.extra_dev_deps << ['mongoid', '>=0.
|
29
|
+
self.extra_dev_deps << ['mongoid', '>=0.10.4']
|
30
30
|
self.extra_dev_deps << ['aws-s3', '>=0.6.2']
|
31
|
+
self.extra_dev_deps << ['timecop', '>=0.3.4']
|
31
32
|
self.extra_rdoc_files << 'README.rdoc'
|
32
33
|
end
|
33
34
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: downloading files
|
2
|
+
In order to allow users to upload remote files
|
3
|
+
As a developer using CarrierWave
|
4
|
+
I want to download files to the filesystem via HTTP
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given an uploader class that uses the 'file' storage
|
8
|
+
And an instance of that class
|
9
|
+
|
10
|
+
Scenario: download a file
|
11
|
+
When I download the file 'http://s3.amazonaws.com/Monkey/testfile.txt'
|
12
|
+
Then there should be a file called 'testfile.txt' somewhere in a subdirectory of 'public/uploads/tmp'
|
13
|
+
And the file called 'testfile.txt' in a subdirectory of 'public/uploads/tmp' should contain 'S3 Remote File'
|
14
|
+
|
15
|
+
Scenario: downloading a file then storing
|
16
|
+
When I download the file 'http://s3.amazonaws.com/Monkey/testfile.txt'
|
17
|
+
And I store the file
|
18
|
+
Then there should be a file at 'public/uploads/testfile.txt'
|
19
|
+
And the file at 'public/uploads/testfile.txt' should contain 'S3 Remote File'
|
20
|
+
|
@@ -34,9 +34,20 @@ Then /^the file called '(.*?)' in a subdirectory of '(.*?)' should not be identi
|
|
34
34
|
File.read(Dir.glob(File.join(file_path(directory), '**', file)).first).should_not == File.read(file_path(other))
|
35
35
|
end
|
36
36
|
|
37
|
+
###
|
38
|
+
# CONTENT
|
39
|
+
|
40
|
+
Then /^the file called '([^']+)' in a subdirectory of '([^']+)' should contain '([^']+)'$/ do |file, directory, content|
|
41
|
+
File.read(Dir.glob(File.join(file_path(directory), '**', file)).first).should include(content)
|
42
|
+
end
|
43
|
+
|
44
|
+
Then /^the file at '([^']+)' should contain '([^']+)'$/ do |path, content|
|
45
|
+
File.read(file_path(path)).should include(content)
|
46
|
+
end
|
47
|
+
|
37
48
|
###
|
38
49
|
# REVERSING
|
39
50
|
|
40
51
|
Then /^the file at '(.*?)' should be the reverse of the file at '(.*?)'$/ do |one, two|
|
41
52
|
File.read(file_path(one)).should == File.read(file_path(two)).reverse
|
42
|
-
end
|
53
|
+
end
|
data/lib/carrierwave.rb
CHANGED
@@ -7,7 +7,7 @@ require 'carrierwave/core_ext/inheritable_attributes'
|
|
7
7
|
|
8
8
|
module CarrierWave
|
9
9
|
|
10
|
-
VERSION = "0.4.
|
10
|
+
VERSION = "0.4.4"
|
11
11
|
|
12
12
|
class << self
|
13
13
|
attr_accessor :root
|
@@ -15,12 +15,17 @@ module CarrierWave
|
|
15
15
|
def configure(&block)
|
16
16
|
CarrierWave::Uploader::Base.configure(&block)
|
17
17
|
end
|
18
|
+
|
19
|
+
def clean_cached_files!
|
20
|
+
CarrierWave::Uploader::Base.clean_cached_files!
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
class UploadError < StandardError; end
|
21
25
|
class IntegrityError < UploadError; end
|
22
26
|
class InvalidParameter < UploadError; end
|
23
27
|
class ProcessingError < UploadError; end
|
28
|
+
class DownloadError < UploadError; end
|
24
29
|
|
25
30
|
autoload :SanitizedFile, 'carrierwave/sanitized_file'
|
26
31
|
autoload :Mount, 'carrierwave/mount'
|
@@ -40,6 +45,7 @@ module CarrierWave
|
|
40
45
|
autoload :Base, 'carrierwave/uploader'
|
41
46
|
autoload :Cache, 'carrierwave/uploader/cache'
|
42
47
|
autoload :Store, 'carrierwave/uploader/store'
|
48
|
+
autoload :Download, 'carrierwave/uploader/download'
|
43
49
|
autoload :Callbacks, 'carrierwave/uploader/callbacks'
|
44
50
|
autoload :Processing, 'carrierwave/uploader/processing'
|
45
51
|
autoload :Versions, 'carrierwave/uploader/versions'
|
data/lib/carrierwave/mount.rb
CHANGED
@@ -85,6 +85,9 @@ module CarrierWave
|
|
85
85
|
# [image_cache] Returns a string that identifies the cache location of the file
|
86
86
|
# [image_cache=] Retrieves the file from the cache based on the given cache name
|
87
87
|
#
|
88
|
+
# [remote_image_url] Returns previously cached remote url
|
89
|
+
# [remote_image_url=] Retrieve the file from the remote url
|
90
|
+
#
|
88
91
|
# [remove_image] An attribute reader that can be used with a checkbox to mark a file for removal
|
89
92
|
# [remove_image=] An attribute writer that can be used with a checkbox to mark a file for removal
|
90
93
|
# [remove_image?] Whether the file should be removed when store_image! is called.
|
@@ -92,7 +95,7 @@ module CarrierWave
|
|
92
95
|
# [store_image!] Stores a file that has been assigned with +image=+
|
93
96
|
# [remove_image!] Removes the uploaded file from the filesystem.
|
94
97
|
#
|
95
|
-
# [image_integrity_error] Returns an error object if the last file to be assigned caused an
|
98
|
+
# [image_integrity_error] Returns an error object if the last file to be assigned caused an integrity error
|
96
99
|
# [image_processing_error] Returns an error object if the last file to be assigned caused a processing error
|
97
100
|
#
|
98
101
|
# [write_image_identifier] Uses the write_uploader method to set the identifier.
|
@@ -185,6 +188,14 @@ module CarrierWave
|
|
185
188
|
_mounter(:#{column}).cache_name = cache_name
|
186
189
|
end
|
187
190
|
|
191
|
+
def remote_#{column}_url
|
192
|
+
_mounter(:#{column}).remote_url
|
193
|
+
end
|
194
|
+
|
195
|
+
def remote_#{column}_url=(url)
|
196
|
+
_mounter(:#{column}).remote_url = url
|
197
|
+
end
|
198
|
+
|
188
199
|
def remove_#{column}
|
189
200
|
_mounter(:#{column}).remove
|
190
201
|
end
|
@@ -248,7 +259,7 @@ module CarrierWave
|
|
248
259
|
# we don't pollute the model with a lot of methods.
|
249
260
|
class Mounter #:nodoc:
|
250
261
|
|
251
|
-
attr_reader :column, :record, :integrity_error, :processing_error
|
262
|
+
attr_reader :column, :record, :remote_url, :integrity_error, :processing_error
|
252
263
|
attr_accessor :remove
|
253
264
|
|
254
265
|
def initialize(record, column, options={})
|
@@ -299,6 +310,13 @@ module CarrierWave
|
|
299
310
|
rescue CarrierWave::InvalidParameter
|
300
311
|
end
|
301
312
|
|
313
|
+
def remote_url=(url)
|
314
|
+
unless uploader.cached?
|
315
|
+
@remote_url = url
|
316
|
+
uploader.download!(url)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
302
320
|
def store!
|
303
321
|
unless uploader.blank?
|
304
322
|
if remove?
|
@@ -76,7 +76,7 @@ module CarrierWave
|
|
76
76
|
|
77
77
|
module ClassMethods
|
78
78
|
def convert(format)
|
79
|
-
process :
|
79
|
+
process :convert => format
|
80
80
|
end
|
81
81
|
|
82
82
|
def resize_to_limit(width, height)
|
@@ -91,10 +91,6 @@ module CarrierWave
|
|
91
91
|
process :resize_to_fill => [width, height]
|
92
92
|
end
|
93
93
|
|
94
|
-
def resize_and_pad(width, height)
|
95
|
-
process :resize_to_fit => [width, height]
|
96
|
-
end
|
97
|
-
|
98
94
|
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
|
99
95
|
process :resize_and_pad => [width, height, background, gravity]
|
100
96
|
end
|
@@ -118,11 +114,7 @@ module CarrierWave
|
|
118
114
|
# image.convert(:png)
|
119
115
|
#
|
120
116
|
def convert(format)
|
121
|
-
manipulate!
|
122
|
-
img.format = format.to_s.upcase
|
123
|
-
img = yield(img) if block_given?
|
124
|
-
img
|
125
|
-
end
|
117
|
+
manipulate!(:format => format)
|
126
118
|
end
|
127
119
|
|
128
120
|
##
|
@@ -255,21 +247,27 @@ module CarrierWave
|
|
255
247
|
#
|
256
248
|
# [CarrierWave::ProcessingError] if manipulation failed.
|
257
249
|
#
|
258
|
-
def manipulate!
|
250
|
+
def manipulate!(options={})
|
259
251
|
image = ::Magick::Image.read(current_path)
|
260
252
|
|
261
|
-
if image.size > 1
|
253
|
+
frames = if image.size > 1
|
262
254
|
list = ::Magick::ImageList.new
|
263
255
|
image.each do |frame|
|
264
256
|
list << yield( frame )
|
265
257
|
end
|
266
|
-
list
|
267
|
-
destroy_image(list)
|
258
|
+
list
|
268
259
|
else
|
269
260
|
frame = image.first
|
270
|
-
yield( frame )
|
271
|
-
|
261
|
+
frame = yield( frame ) if block_given?
|
262
|
+
frame
|
263
|
+
end
|
264
|
+
|
265
|
+
if options[:format]
|
266
|
+
frames.write("#{options[:format]}:#{current_path}")
|
267
|
+
else
|
268
|
+
frames.write(current_path)
|
272
269
|
end
|
270
|
+
destroy_image(frames)
|
273
271
|
rescue ::Magick::ImageMagickError => e
|
274
272
|
raise CarrierWave::ProcessingError.new("Failed to manipulate with rmagick, maybe it is not an image? Original Error: #{e}")
|
275
273
|
end
|
@@ -38,6 +38,10 @@ module CarrierWave
|
|
38
38
|
::GridFS::GridStore.unlink(@database, @path)
|
39
39
|
end
|
40
40
|
|
41
|
+
def content_type
|
42
|
+
::GridFS::GridStore.open(@database, @path, 'r') { |f| return f.content_type }
|
43
|
+
end
|
44
|
+
|
41
45
|
end
|
42
46
|
|
43
47
|
##
|
@@ -52,7 +56,7 @@ module CarrierWave
|
|
52
56
|
# [CarrierWave::SanitizedFile] a sanitized file
|
53
57
|
#
|
54
58
|
def store!(file)
|
55
|
-
::GridFS::GridStore.open(database, uploader.store_path, 'w') do |f|
|
59
|
+
::GridFS::GridStore.open(database, uploader.store_path, 'w', :content_type => file.content_type) do |f|
|
56
60
|
f.write file.read
|
57
61
|
end
|
58
62
|
CarrierWave::Storage::GridFS::File.new(uploader, database, uploader.store_path)
|
@@ -79,7 +83,11 @@ module CarrierWave
|
|
79
83
|
@connection ||= begin
|
80
84
|
host = uploader.grid_fs_host
|
81
85
|
database = uploader.grid_fs_database
|
82
|
-
|
86
|
+
username = uploader.grid_fs_username
|
87
|
+
password = uploader.grid_fs_password
|
88
|
+
db = Mongo::Connection.new(host).db(database)
|
89
|
+
db.authenticate(username, password) if username && password
|
90
|
+
db
|
83
91
|
end
|
84
92
|
end
|
85
93
|
|
@@ -73,7 +73,7 @@ module CarrierWave
|
|
73
73
|
#
|
74
74
|
def read
|
75
75
|
result = connection.get(bucket, @path)
|
76
|
-
headers
|
76
|
+
@headers = result[:headers]
|
77
77
|
result[:object]
|
78
78
|
end
|
79
79
|
|
@@ -99,47 +99,34 @@ module CarrierWave
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
-
#def about
|
103
|
-
# s3_object.about
|
104
|
-
#end
|
105
|
-
|
106
|
-
#def metadata
|
107
|
-
# s3_object.metadata
|
108
|
-
#end
|
109
|
-
|
110
102
|
def content_type
|
111
103
|
headers["content-type"]
|
112
104
|
end
|
113
105
|
|
114
|
-
def content_type=(new_content_type)
|
115
|
-
headers["content-type"] = new_content_type
|
116
|
-
end
|
117
|
-
|
118
106
|
#def content_disposition
|
119
107
|
# s3_object.content_disposition
|
120
108
|
#end
|
121
109
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
connection.put(bucket, @path, data, headers)
|
110
|
+
def store(file)
|
111
|
+
connection.put(bucket, @path, file.read,
|
112
|
+
'x-amz-acl' => @uploader.s3_access_policy,
|
113
|
+
'content-type' => file.content_type
|
114
|
+
)
|
128
115
|
end
|
129
116
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
117
|
+
private
|
118
|
+
|
119
|
+
def headers
|
120
|
+
@headers ||= {}
|
121
|
+
end
|
135
122
|
|
136
|
-
|
137
|
-
|
138
|
-
|
123
|
+
def bucket
|
124
|
+
@uploader.s3_bucket
|
125
|
+
end
|
139
126
|
|
140
|
-
|
141
|
-
|
142
|
-
|
127
|
+
def connection
|
128
|
+
@base.connection
|
129
|
+
end
|
143
130
|
|
144
131
|
end
|
145
132
|
|
@@ -156,7 +143,7 @@ module CarrierWave
|
|
156
143
|
#
|
157
144
|
def store!(file)
|
158
145
|
f = CarrierWave::Storage::RightS3::File.new(uploader, self, uploader.store_path)
|
159
|
-
f.store(file
|
146
|
+
f.store(file)
|
160
147
|
f
|
161
148
|
end
|
162
149
|
|
@@ -7,7 +7,7 @@ module CarrierWave
|
|
7
7
|
##
|
8
8
|
# Uploads things to Amazon S3 webservices. It requies the aws/s3 gem. In order for
|
9
9
|
# CarrierWave to connect to Amazon S3, you'll need to specify an access key id, secret key
|
10
|
-
# and bucket
|
10
|
+
# and bucket:
|
11
11
|
#
|
12
12
|
# CarrierWave.configure do |config|
|
13
13
|
# config.s3_access_key_id = "xxxxxx"
|
@@ -34,6 +34,20 @@ module CarrierWave
|
|
34
34
|
#
|
35
35
|
# The default is :public_read, it should work in most cases.
|
36
36
|
#
|
37
|
+
# You can assign HTTP headers to be used when S3 serves your files:
|
38
|
+
#
|
39
|
+
# CarrierWave.configure do |config|
|
40
|
+
# config.s3_headers = {"Content-Disposition" => "attachment; filename=foo.jpg;"}
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# You can also set the headers dynamically by overriding the s3_headers method:
|
44
|
+
#
|
45
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
46
|
+
# def s3_headers
|
47
|
+
# { "Expires" => 1.year.from_how.httpdate }
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
#
|
37
51
|
# You can change the generated url to a cnamed domain by setting the cnamed config:
|
38
52
|
#
|
39
53
|
# CarrierWave.configure do |config|
|
@@ -131,7 +145,7 @@ module CarrierWave
|
|
131
145
|
end
|
132
146
|
|
133
147
|
def s3_object
|
134
|
-
@s3_object ||= AWS::S3::S3Object.find(@path,
|
148
|
+
@s3_object ||= AWS::S3::S3Object.find(@path, @uploader.s3_bucket)
|
135
149
|
end
|
136
150
|
|
137
151
|
end
|
@@ -149,7 +163,9 @@ module CarrierWave
|
|
149
163
|
#
|
150
164
|
def store!(file)
|
151
165
|
connect!(uploader)
|
152
|
-
|
166
|
+
s3_options = {:access => uploader.s3_access, :content_type => file.content_type}
|
167
|
+
s3_options.merge!(uploader.s3_headers)
|
168
|
+
AWS::S3::S3Object.store(uploader.store_path, file.read, uploader.s3_bucket, s3_options)
|
153
169
|
CarrierWave::Storage::S3::File.new(uploader, uploader.store_path)
|
154
170
|
end
|
155
171
|
|
data/lib/carrierwave/uploader.rb
CHANGED
@@ -31,6 +31,7 @@ module CarrierWave
|
|
31
31
|
use CarrierWave::Uploader::Mountable
|
32
32
|
use CarrierWave::Uploader::Cache
|
33
33
|
use CarrierWave::Uploader::Store
|
34
|
+
use CarrierWave::Uploader::Download
|
34
35
|
use CarrierWave::Uploader::Remove
|
35
36
|
use CarrierWave::Uploader::ExtensionWhitelist
|
36
37
|
use CarrierWave::Uploader::Processing
|
@@ -25,6 +25,32 @@ module CarrierWave
|
|
25
25
|
depends_on CarrierWave::Uploader::Callbacks
|
26
26
|
depends_on CarrierWave::Uploader::Configuration
|
27
27
|
|
28
|
+
module ClassMethods
|
29
|
+
|
30
|
+
##
|
31
|
+
# Removes cached files which are older than one day. You could call this method
|
32
|
+
# from a rake task to clean out old cached files.
|
33
|
+
#
|
34
|
+
# You can call this method directly on the module like this:
|
35
|
+
#
|
36
|
+
# CarrierWave.clean_cached_files!
|
37
|
+
#
|
38
|
+
# === Note
|
39
|
+
#
|
40
|
+
# This only works as long as you haven't done anything funky with your cache_dir.
|
41
|
+
# It's recommended that you keen cache files in one place only.
|
42
|
+
#
|
43
|
+
def clean_cached_files!
|
44
|
+
Dir.glob(File.expand_path(File.join(cache_dir, '*'), CarrierWave.root)).each do |dir|
|
45
|
+
time = dir.scan(/(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})/).first.map { |t| t.to_i }
|
46
|
+
time = Time.utc(*time)
|
47
|
+
if time < (Time.now - (60*60*24))
|
48
|
+
FileUtils.rm_rf(dir)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
28
54
|
##
|
29
55
|
# Returns true if the uploader has been cached
|
30
56
|
#
|
@@ -116,4 +142,4 @@ module CarrierWave
|
|
116
142
|
|
117
143
|
end # Cache
|
118
144
|
end # Uploader
|
119
|
-
end # CarrierWave
|
145
|
+
end # CarrierWave
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
module CarrierWave
|
6
|
+
module Uploader
|
7
|
+
module Download
|
8
|
+
|
9
|
+
depends_on CarrierWave::Uploader::Callbacks
|
10
|
+
depends_on CarrierWave::Uploader::Configuration
|
11
|
+
depends_on CarrierWave::Uploader::Cache
|
12
|
+
|
13
|
+
class RemoteFile
|
14
|
+
def initialize(uri)
|
15
|
+
@uri = URI.parse(uri)
|
16
|
+
end
|
17
|
+
|
18
|
+
def original_filename
|
19
|
+
File.basename(@uri.path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_to?(*args)
|
23
|
+
super or file.respond_to?(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def http?
|
27
|
+
@uri.scheme =~ /^https?$/
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def file
|
33
|
+
@file ||= StringIO.new(Net::HTTP.get_response(@uri).body)
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing(*args, &block)
|
37
|
+
file.send(*args, &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Caches the file by downloading it from the given URL.
|
43
|
+
#
|
44
|
+
# === Parameters
|
45
|
+
#
|
46
|
+
# [url (String)] The URL where the remote file is stored
|
47
|
+
#
|
48
|
+
def download!(uri)
|
49
|
+
unless uri.blank?
|
50
|
+
file = RemoteFile.new(uri)
|
51
|
+
raise CarrierWave::DownloadError, "trying to download a file which is not served over HTTP" unless file.http?
|
52
|
+
cache!(file)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end # Download
|
57
|
+
end # Uploader
|
58
|
+
end # CarrierWave
|
59
|
+
|
data/spec/mount_spec.rb
CHANGED
@@ -215,6 +215,52 @@ describe CarrierWave::Mount do
|
|
215
215
|
end
|
216
216
|
end
|
217
217
|
|
218
|
+
describe '#remote_image_url' do
|
219
|
+
before do
|
220
|
+
response = mock('HTTP Response')
|
221
|
+
response.stub!(:body).and_return('Response Body')
|
222
|
+
Net::HTTP.stub!(:get_response).and_return(response)
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should return nil" do
|
226
|
+
@instance.remote_image_url.should be_nil
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should return previously cached URL" do
|
230
|
+
@instance.remote_image_url = 'http://www.example.com/funky/monkey.png'
|
231
|
+
@instance.remote_image_url.should == 'http://www.example.com/funky/monkey.png'
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe '#remote_image_url=' do
|
236
|
+
before do
|
237
|
+
response = mock('HTTP Response')
|
238
|
+
response.stub!(:body).and_return('Response Body')
|
239
|
+
Net::HTTP.stub!(:get_response).and_return(response)
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should do nothing when nil is assigned" do
|
243
|
+
@instance.remote_image_url = nil
|
244
|
+
@instance.image.should be_blank
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should do nothing when an empty string is assigned" do
|
248
|
+
@instance.remote_image_url = ''
|
249
|
+
@instance.image.should be_blank
|
250
|
+
end
|
251
|
+
|
252
|
+
it "retrieve from cache when a cache name is assigned" do
|
253
|
+
@instance.remote_image_url = 'http://www.example.com/funky/monkey.png'
|
254
|
+
@instance.image.current_path.should =~ /monkey.png$/
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should not write over a previously assigned file" do
|
258
|
+
@instance.image = stub_file('test.jpg')
|
259
|
+
@instance.remote_image_url = '19990512-1202-123-1234/monkey.jpg'
|
260
|
+
@instance.image.current_path.should =~ /test.jpg$/
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
218
264
|
describe '#store_image!' do
|
219
265
|
|
220
266
|
before do
|
@@ -489,4 +535,4 @@ describe CarrierWave::Mount do
|
|
489
535
|
end
|
490
536
|
end
|
491
537
|
|
492
|
-
end
|
538
|
+
end
|
data/spec/orm/mongoid_spec.rb
CHANGED
@@ -10,12 +10,13 @@ describe CarrierWave::Mongoid do
|
|
10
10
|
|
11
11
|
before do
|
12
12
|
uploader = Class.new(CarrierWave::Uploader::Base)
|
13
|
-
|
14
|
-
@class =
|
13
|
+
|
14
|
+
@class = Class.new
|
15
15
|
@class.class_eval do
|
16
|
+
include Mongoid::Document
|
16
17
|
mount_uploader :image, uploader
|
17
18
|
end
|
18
|
-
|
19
|
+
|
19
20
|
@uploader = uploader
|
20
21
|
end
|
21
22
|
|
@@ -17,6 +17,13 @@ describe CarrierWave::RMagick do
|
|
17
17
|
FileUtils.rm(file_path('landscape_copy.jpg'))
|
18
18
|
end
|
19
19
|
|
20
|
+
describe '#convert' do
|
21
|
+
it "should convert the image to the given format" do
|
22
|
+
# TODO: find some way to spec this
|
23
|
+
@instance.convert(:png)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
20
27
|
describe '#resize_to_fill' do
|
21
28
|
it "should resize the image to exactly the given dimensions" do
|
22
29
|
@instance.resize_to_fill(200, 200)
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,8 @@ require 'spec'
|
|
19
19
|
require 'spec/autorun'
|
20
20
|
|
21
21
|
require 'carrierwave'
|
22
|
+
require 'timecop'
|
23
|
+
require 'time'
|
22
24
|
|
23
25
|
require 'logger'
|
24
26
|
|
@@ -94,4 +96,4 @@ Spec::Runner.configure do |config|
|
|
94
96
|
config.include CarrierWave::Test::Matchers
|
95
97
|
config.include CarrierWave::Test::MockFiles
|
96
98
|
config.include CarrierWave::Test::MockStorage
|
97
|
-
end
|
99
|
+
end
|
@@ -10,9 +10,11 @@ describe CarrierWave::Storage::GridFS do
|
|
10
10
|
@uploader.stub!(:grid_fs_database).and_return("carrierwave_test")
|
11
11
|
@uploader.stub!(:grid_fs_host).and_return("localhost")
|
12
12
|
@uploader.stub!(:grid_fs_access_url).and_return(nil)
|
13
|
+
@uploader.stub!(:grid_fs_username).and_return(nil)
|
14
|
+
@uploader.stub!(:grid_fs_password).and_return(nil)
|
13
15
|
|
14
16
|
@storage = CarrierWave::Storage::GridFS.new(@uploader)
|
15
|
-
@file =
|
17
|
+
@file = stub_tempfile('test.jpg', 'application/xml')
|
16
18
|
end
|
17
19
|
|
18
20
|
after do
|
@@ -41,6 +43,10 @@ describe CarrierWave::Storage::GridFS do
|
|
41
43
|
@grid_fs_file.delete
|
42
44
|
GridFS::GridStore.read(@database, 'uploads/bar.txt').should == ''
|
43
45
|
end
|
46
|
+
|
47
|
+
it "should store the content type on GridFS" do
|
48
|
+
@grid_fs_file.content_type.should == 'application/xml'
|
49
|
+
end
|
44
50
|
end
|
45
51
|
|
46
52
|
describe '#retrieve!' do
|
data/spec/storage/s3_spec.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require File.dirname(__FILE__) + '/../spec_helper'
|
4
4
|
require 'aws/s3'
|
5
|
+
require 'net/http'
|
5
6
|
|
6
7
|
if ENV['S3_SPEC']
|
7
8
|
describe CarrierWave::Storage::S3 do
|
@@ -12,13 +13,14 @@ if ENV['S3_SPEC']
|
|
12
13
|
@uploader.stub!(:s3_bucket).and_return(ENV['CARRIERWAVE_TEST_BUCKET'])
|
13
14
|
@uploader.stub!(:s3_access).and_return(:public_read)
|
14
15
|
@uploader.stub!(:s3_cnamed).and_return(false)
|
16
|
+
@uploader.stub!(:s3_headers).and_return({'Expires' => 'Fri, 21 Jan 2021 16:51:06 GMT'})
|
15
17
|
|
16
18
|
@storage = CarrierWave::Storage::S3.new(@uploader)
|
17
|
-
@file =
|
19
|
+
@file = stub_tempfile('test.jpg', 'application/xml')
|
18
20
|
end
|
19
21
|
|
20
22
|
after do
|
21
|
-
AWS::S3::S3Object.delete('uploads/bar.txt',
|
23
|
+
AWS::S3::S3Object.delete('uploads/bar.txt', @uploader.s3_bucket)
|
22
24
|
end
|
23
25
|
|
24
26
|
describe '#store!' do
|
@@ -28,7 +30,7 @@ if ENV['S3_SPEC']
|
|
28
30
|
end
|
29
31
|
|
30
32
|
it "should upload the file to s3" do
|
31
|
-
AWS::S3::S3Object.value('uploads/bar.txt',
|
33
|
+
AWS::S3::S3Object.value('uploads/bar.txt', @uploader.s3_bucket).should == 'this is stuff'
|
32
34
|
end
|
33
35
|
|
34
36
|
it "should have a path" do
|
@@ -36,7 +38,7 @@ if ENV['S3_SPEC']
|
|
36
38
|
end
|
37
39
|
|
38
40
|
it "should have an Amazon URL" do
|
39
|
-
@s3_file.url.should ==
|
41
|
+
@s3_file.url.should == "http://s3.amazonaws.com/#{@uploader.s3_bucket}/uploads/bar.txt"
|
40
42
|
end
|
41
43
|
|
42
44
|
context "with cnamed bucket" do
|
@@ -49,13 +51,23 @@ if ENV['S3_SPEC']
|
|
49
51
|
|
50
52
|
it "should be deletable" do
|
51
53
|
@s3_file.delete
|
52
|
-
AWS::S3::S3Object.exists?('uploads/bar.txt',
|
54
|
+
AWS::S3::S3Object.exists?('uploads/bar.txt', @uploader.s3_bucket).should be_false
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should store the content type on S3" do
|
58
|
+
@s3_file.content_type.should == 'application/xml'
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should set headers" do
|
62
|
+
client = Net::HTTP.new("s3.amazonaws.com")
|
63
|
+
headers = client.request_head(URI.parse(@s3_file.url).path)
|
64
|
+
headers['Expires'].should == 'Fri, 21 Jan 2021 16:51:06 GMT'
|
53
65
|
end
|
54
66
|
end
|
55
67
|
|
56
68
|
describe '#retrieve!' do
|
57
69
|
before do
|
58
|
-
AWS::S3::S3Object.store('uploads/bar.txt', "A test, 1234",
|
70
|
+
AWS::S3::S3Object.store('uploads/bar.txt', "A test, 1234", @uploader.s3_bucket)
|
59
71
|
|
60
72
|
@uploader.stub!(:store_path).with('bar.txt').and_return('uploads/bar.txt')
|
61
73
|
@s3_file = @storage.retrieve!('bar.txt')
|
@@ -70,12 +82,12 @@ if ENV['S3_SPEC']
|
|
70
82
|
end
|
71
83
|
|
72
84
|
it "should have an Amazon URL" do
|
73
|
-
@s3_file.url.should ==
|
85
|
+
@s3_file.url.should == "http://s3.amazonaws.com/#{@uploader.s3_bucket}/uploads/bar.txt"
|
74
86
|
end
|
75
87
|
|
76
88
|
it "should be deletable" do
|
77
89
|
@s3_file.delete
|
78
|
-
AWS::S3::S3Object.exists?('uploads/bar.txt',
|
90
|
+
AWS::S3::S3Object.exists?('uploads/bar.txt', @uploader.s3_bucket).should be_false
|
79
91
|
end
|
80
92
|
end
|
81
93
|
|
data/spec/uploader/cache_spec.rb
CHANGED
@@ -13,6 +13,31 @@ describe CarrierWave::Uploader do
|
|
13
13
|
FileUtils.rm_rf(public_path)
|
14
14
|
end
|
15
15
|
|
16
|
+
describe '.clean_cached_files!' do
|
17
|
+
before do
|
18
|
+
@cache_dir = File.expand_path(@uploader_class.cache_dir, CarrierWave.root)
|
19
|
+
FileUtils.mkdir_p File.expand_path('20071201-1234-234-2213', @cache_dir)
|
20
|
+
FileUtils.mkdir_p File.expand_path('20071203-1234-234-2213', @cache_dir)
|
21
|
+
FileUtils.mkdir_p File.expand_path('20071205-1234-234-2213', @cache_dir)
|
22
|
+
end
|
23
|
+
|
24
|
+
after { FileUtils.rm_rf(@cache_dir) }
|
25
|
+
|
26
|
+
it "should clear all files older than 24 hours in the default cache directory" do
|
27
|
+
Timecop.freeze(Time.parse('2007-12-06 10:12')) do
|
28
|
+
@uploader_class.clean_cached_files!
|
29
|
+
end
|
30
|
+
Dir.glob("#{@cache_dir}/*").should have(1).element
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be aliased on the CarrierWave module" do
|
34
|
+
Timecop.freeze(Time.parse('2007-12-06 10:12')) do
|
35
|
+
CarrierWave.clean_cached_files!
|
36
|
+
end
|
37
|
+
Dir.glob("#{@cache_dir}/*").should have(1).element
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
16
41
|
describe '#cache_dir' do
|
17
42
|
it "should default to the config option" do
|
18
43
|
@uploader.cache_dir.should == 'uploads/tmp'
|
@@ -181,4 +206,4 @@ describe CarrierWave::Uploader do
|
|
181
206
|
end
|
182
207
|
end
|
183
208
|
|
184
|
-
end
|
209
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
4
|
+
|
5
|
+
describe CarrierWave::Uploader::Download do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@uploader_class = Class.new(CarrierWave::Uploader::Base)
|
9
|
+
@uploader = @uploader_class.new
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
FileUtils.rm_rf(public_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#download!' do
|
17
|
+
|
18
|
+
before do
|
19
|
+
CarrierWave.stub!(:generate_cache_id).and_return('20071201-1234-345-2255')
|
20
|
+
response = mock('HTTP Response')
|
21
|
+
response.stub!(:body).and_return('Response Body')
|
22
|
+
Net::HTTP.stub!(:get_response).and_return(response)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should cache a file" do
|
26
|
+
@uploader.download!('http://www.example.com/test/file.png')
|
27
|
+
@uploader.file.should be_an_instance_of(CarrierWave::SanitizedFile)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be cached" do
|
31
|
+
@uploader.download!('http://www.example.com/test/file.png')
|
32
|
+
@uploader.should be_cached
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should store the cache name" do
|
36
|
+
@uploader.download!('http://www.example.com/test/file.png')
|
37
|
+
@uploader.cache_name.should == '20071201-1234-345-2255/file.png'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should set the filename to the file's sanitized filename" do
|
41
|
+
@uploader.download!('http://www.example.com/test/file.png')
|
42
|
+
@uploader.filename.should == 'file.png'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should move it to the tmp dir" do
|
46
|
+
@uploader.download!('http://www.example.com/test/file.png')
|
47
|
+
@uploader.file.path.should == public_path('uploads/tmp/20071201-1234-345-2255/file.png')
|
48
|
+
@uploader.file.exists?.should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set the url" do
|
52
|
+
@uploader.download!('http://www.example.com/test/file.png')
|
53
|
+
@uploader.url.should == '/uploads/tmp/20071201-1234-345-2255/file.png'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should do nothing when trying to download an empty file" do
|
57
|
+
@uploader.download!(nil)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set permissions if options are given" do
|
61
|
+
@uploader_class.permissions = 0777
|
62
|
+
|
63
|
+
@uploader.download!('http://www.example.com/test/file.png')
|
64
|
+
@uploader.should have_permissions(0777)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should raise an error when trying to download a local file" do
|
68
|
+
running {
|
69
|
+
@uploader.download!('/etc/passwd')
|
70
|
+
}.should raise_error(CarrierWave::DownloadError)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Nicklas
|
@@ -9,9 +9,29 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-02-20 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rubyforge
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.3
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: gemcutter
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.0
|
34
|
+
version:
|
15
35
|
- !ruby/object:Gem::Dependency
|
16
36
|
name: newgem
|
17
37
|
type: :development
|
@@ -140,7 +160,7 @@ dependencies:
|
|
140
160
|
requirements:
|
141
161
|
- - ">="
|
142
162
|
- !ruby/object:Gem::Version
|
143
|
-
version: 0.
|
163
|
+
version: 0.10.4
|
144
164
|
version:
|
145
165
|
- !ruby/object:Gem::Dependency
|
146
166
|
name: aws-s3
|
@@ -152,6 +172,16 @@ dependencies:
|
|
152
172
|
- !ruby/object:Gem::Version
|
153
173
|
version: 0.6.2
|
154
174
|
version:
|
175
|
+
- !ruby/object:Gem::Dependency
|
176
|
+
name: timecop
|
177
|
+
type: :development
|
178
|
+
version_requirement:
|
179
|
+
version_requirements: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: 0.3.4
|
184
|
+
version:
|
155
185
|
- !ruby/object:Gem::Dependency
|
156
186
|
name: hoe
|
157
187
|
type: :development
|
@@ -160,13 +190,14 @@ dependencies:
|
|
160
190
|
requirements:
|
161
191
|
- - ">="
|
162
192
|
- !ruby/object:Gem::Version
|
163
|
-
version: 2.
|
193
|
+
version: 2.5.0
|
164
194
|
version:
|
165
195
|
description: |-
|
166
196
|
* RDoc Documentation {available at Rubyforge}[http://carrierwave.rubyforge.org/rdoc].
|
167
197
|
* Source code {hosted at GitHub}[http://github.com/jnicklas/carrierwave]
|
168
198
|
* Please {report any issues}[http://github.com/jnicklas/carrierwave/issues] on GitHub
|
169
199
|
* Please direct any questions at the {mailing list}[http://groups.google.com/group/carrierwave]
|
200
|
+
* Check out the {example app}[http://github.com/jnicklas/carrierwave-example-app]
|
170
201
|
email:
|
171
202
|
- jonas.nicklas@gmail.com
|
172
203
|
executables: []
|
@@ -187,6 +218,7 @@ files:
|
|
187
218
|
- Rakefile
|
188
219
|
- cucumber.yml
|
189
220
|
- features/caching.feature
|
221
|
+
- features/download.feature
|
190
222
|
- features/file_storage.feature
|
191
223
|
- features/file_storage_overridden_filename.feature
|
192
224
|
- features/file_storage_overridden_store_dir.feature
|
@@ -199,6 +231,7 @@ files:
|
|
199
231
|
- features/step_definitions/activerecord_steps.rb
|
200
232
|
- features/step_definitions/caching_steps.rb
|
201
233
|
- features/step_definitions/datamapper_steps.rb
|
234
|
+
- features/step_definitions/download_steps.rb
|
202
235
|
- features/step_definitions/file_steps.rb
|
203
236
|
- features/step_definitions/general_steps.rb
|
204
237
|
- features/step_definitions/mount_steps.rb
|
@@ -236,6 +269,7 @@ files:
|
|
236
269
|
- lib/carrierwave/uploader/callbacks.rb
|
237
270
|
- lib/carrierwave/uploader/configuration.rb
|
238
271
|
- lib/carrierwave/uploader/default_url.rb
|
272
|
+
- lib/carrierwave/uploader/download.rb
|
239
273
|
- lib/carrierwave/uploader/extension_whitelist.rb
|
240
274
|
- lib/carrierwave/uploader/mountable.rb
|
241
275
|
- lib/carrierwave/uploader/processing.rb
|
@@ -274,6 +308,7 @@ files:
|
|
274
308
|
- spec/uploader/cache_spec.rb
|
275
309
|
- spec/uploader/configuration_spec.rb
|
276
310
|
- spec/uploader/default_url_spec.rb
|
311
|
+
- spec/uploader/download_spec.rb
|
277
312
|
- spec/uploader/extension_whitelist_spec.rb
|
278
313
|
- spec/uploader/mountable_spec.rb
|
279
314
|
- spec/uploader/paths_spec.rb
|