carrierwave 0.5.0.beta2 → 0.5.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.rdoc +32 -56
- data/lib/carrierwave.rb +1 -2
- data/lib/carrierwave/locale/en.yml +5 -0
- data/lib/carrierwave/orm/activerecord.rb +4 -47
- data/lib/carrierwave/orm/mongoid.rb +10 -1
- data/lib/carrierwave/storage/right_s3.rb +1 -3
- data/lib/carrierwave/storage/s3.rb +26 -26
- data/lib/carrierwave/uploader/cache.rb +1 -1
- data/lib/carrierwave/uploader/configuration.rb +5 -7
- data/lib/carrierwave/uploader/download.rb +7 -3
- data/lib/carrierwave/validations/active_model.rb +79 -0
- data/lib/carrierwave/version.rb +3 -0
- data/lib/generators/templates/uploader.rb +31 -31
- data/lib/generators/uploader_generator.rb +4 -10
- metadata +256 -12
data/README.rdoc
CHANGED
@@ -4,8 +4,8 @@ http://carrierwave.rubyforge.org
|
|
4
4
|
|
5
5
|
== Summary
|
6
6
|
|
7
|
-
This
|
8
|
-
|
7
|
+
This gem provides a simple and extremely flexible way to upload files from Ruby applications.
|
8
|
+
It works well with Rack based web applications, such as Ruby on Rails.
|
9
9
|
|
10
10
|
== Description
|
11
11
|
|
@@ -22,23 +22,15 @@ Install the latest stable release:
|
|
22
22
|
|
23
23
|
[sudo] gem install carrierwave
|
24
24
|
|
25
|
-
In
|
25
|
+
In Rails, add it to your Gemfile:
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
In Rails, add it to your environment.rb:
|
30
|
-
|
31
|
-
config.gem "carrierwave"
|
27
|
+
gem 'carrierwave'
|
32
28
|
|
33
29
|
== Quick Start
|
34
30
|
|
35
31
|
Start off by generating an uploader:
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
or in Rails:
|
40
|
-
|
41
|
-
script/generate uploader Avatar
|
33
|
+
rails generate uploader Avatar
|
42
34
|
|
43
35
|
this should give you a file in:
|
44
36
|
|
@@ -61,7 +53,8 @@ You can use your uploader class to store and retrieve files like this:
|
|
61
53
|
|
62
54
|
CarrierWave gives you a +store+ for permanent storage, and a +cache+ for
|
63
55
|
temporary storage. You can use different stores, at the moment a filesystem
|
64
|
-
store, an Amazon S3 store, a Rackspace Cloud Files store, and a store for
|
56
|
+
store, an Amazon S3 store, a Rackspace Cloud Files store, and a store for
|
57
|
+
MongoDB's GridFS are bundled.
|
65
58
|
|
66
59
|
Most of the time you are going to want to use CarrierWave together with an ORM.
|
67
60
|
It is quite simple to mount uploaders on columns in your model, so you can
|
@@ -76,7 +69,7 @@ need to require the relevant extension manually, e.g.:
|
|
76
69
|
|
77
70
|
Add a string column to the model you want to mount the uploader on:
|
78
71
|
|
79
|
-
add_column :
|
72
|
+
add_column :users, :avatar, :string
|
80
73
|
|
81
74
|
Open your model file and mount the uploader:
|
82
75
|
|
@@ -112,9 +105,12 @@ Define +store_dir+ as +nil+ if you'd like to store files at the root level.
|
|
112
105
|
|
113
106
|
== Securing uploads
|
114
107
|
|
115
|
-
Certain file might be dangerous if uploaded to the wrong location, such as php
|
108
|
+
Certain file might be dangerous if uploaded to the wrong location, such as php
|
109
|
+
files or other script files. CarrierWave allows you to specify a white-list of
|
110
|
+
allowed extensions.
|
116
111
|
|
117
|
-
If you're mounting the uploader, uploading a file with the wrong extension will
|
112
|
+
If you're mounting the uploader, uploading a file with the wrong extension will
|
113
|
+
make the record invalid instead. Otherwise, an error is raised.
|
118
114
|
|
119
115
|
class MyUploader < CarrierWave::Uploader::Base
|
120
116
|
def extension_white_list
|
@@ -170,7 +166,7 @@ in that case. Suppose your +user+ model has an uploader mounted on +avatar+
|
|
170
166
|
file, just add a hidden field called +avatar_cache+. In Rails, this would look
|
171
167
|
like this:
|
172
168
|
|
173
|
-
|
169
|
+
<%= form_for @user, :html => {:multipart => true} do |f| %>
|
174
170
|
<p>
|
175
171
|
<label>My Avatar</label>
|
176
172
|
<%= f.file_field :avatar %>
|
@@ -181,7 +177,7 @@ like this:
|
|
181
177
|
It might be a good idea to show the user that a file has been uploaded, in the
|
182
178
|
case of images, a small thumbnail would be a good indicator:
|
183
179
|
|
184
|
-
|
180
|
+
<%= form_for @user, :html => {:multipart => true} do |f| %>
|
185
181
|
<p>
|
186
182
|
<label>My Avatar</label>
|
187
183
|
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
@@ -195,7 +191,7 @@ case of images, a small thumbnail would be a good indicator:
|
|
195
191
|
If you want to remove a previously uploaded file on a mounted uploader, you can
|
196
192
|
easily add a checkbox to the form which will remove the file when checked.
|
197
193
|
|
198
|
-
|
194
|
+
<%= form_for @user, :html => {:multipart => true} do |f| %>
|
199
195
|
<p>
|
200
196
|
<label>My Avatar</label>
|
201
197
|
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
@@ -215,10 +211,10 @@ If you want to remove the file manually, you can call <code>remove_avatar!</code
|
|
215
211
|
== Uploading files from a remote location
|
216
212
|
|
217
213
|
Your users may find it convenient to upload a file from a location on the Internet
|
218
|
-
via a URL. CarrierWave makes this simple, just add the appropriate
|
214
|
+
via a URL. CarrierWave makes this simple, just add the appropriate attribute to your
|
219
215
|
form and you're good to go:
|
220
216
|
|
221
|
-
|
217
|
+
<%= form_for @user, :html => {:multipart => true} do |f| %>
|
222
218
|
<p>
|
223
219
|
<label>My Avatar URL:</label>
|
224
220
|
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
@@ -270,6 +266,10 @@ Or alternatively:
|
|
270
266
|
permissions 0777
|
271
267
|
end
|
272
268
|
|
269
|
+
If you're using Rails, create an initializer for this:
|
270
|
+
|
271
|
+
config/initializers/carrierwave.rb
|
272
|
+
|
273
273
|
== Testing CarrierWave
|
274
274
|
|
275
275
|
It's a good idea to test you uploaders in isolation. In order to speed up your
|
@@ -291,6 +291,8 @@ CarrierWave comes with some RSpec matchers which you may find useful:
|
|
291
291
|
require 'carrierwave/test/matchers'
|
292
292
|
|
293
293
|
describe MyUploader do
|
294
|
+
include CarrierWave::Test::Matchers
|
295
|
+
|
294
296
|
before do
|
295
297
|
MyUploader.enable_processing = true
|
296
298
|
@uploader = MyUploader.new(@user, :avatar)
|
@@ -320,12 +322,12 @@ CarrierWave comes with some RSpec matchers which you may find useful:
|
|
320
322
|
|
321
323
|
== Using Amazon S3
|
322
324
|
|
323
|
-
Older versions of CarrierWave used the +aws-s3
|
324
|
-
is now used
|
325
|
+
Older versions of CarrierWave used the +aws+, +aws-s3+, and/or +right_aws+ libraries.
|
326
|
+
Now fog[http://github.com/geemus/fog] is now used instead. Ensure you have it installed:
|
325
327
|
|
326
|
-
gem install
|
328
|
+
gem install fog
|
327
329
|
|
328
|
-
You'll need to configure a bucket, access id and secret key like this:
|
330
|
+
You'll need to configure a bucket, access id and secret key like this in an initializer:
|
329
331
|
|
330
332
|
CarrierWave.configure do |config|
|
331
333
|
config.s3_access_key_id = 'xxxxxx'
|
@@ -333,9 +335,7 @@ You'll need to configure a bucket, access id and secret key like this:
|
|
333
335
|
config.s3_bucket = 'name_of_bucket'
|
334
336
|
end
|
335
337
|
|
336
|
-
|
337
|
-
|
338
|
-
And then in your uploader, set the storage to :s3
|
338
|
+
In your uploader, set the storage to :s3
|
339
339
|
|
340
340
|
class AvatarUploader < CarrierWave::Uploader::Base
|
341
341
|
storage :s3
|
@@ -344,7 +344,6 @@ And then in your uploader, set the storage to :s3
|
|
344
344
|
That's it! You can still use the <code>CarrierWave::Uploader#url</code> method to return
|
345
345
|
the url to the file on Amazon S3.
|
346
346
|
|
347
|
-
|
348
347
|
== Using Rackspace Cloud Files
|
349
348
|
|
350
349
|
Cloud Files support requires a {Rackspace Cloud}[http://rackspacecloud.com] username and API key.
|
@@ -362,9 +361,7 @@ of this information.
|
|
362
361
|
|
363
362
|
config.cloud_files_cdn_host = "c000000.cdn.rackspacecloud.com"
|
364
363
|
|
365
|
-
|
366
|
-
|
367
|
-
And then in your uploader, set the storage to :cloud_files
|
364
|
+
In your uploader, set the storage to :cloud_files
|
368
365
|
|
369
366
|
class AvatarUploader < CarrierWave::Uploader::Base
|
370
367
|
storage :cloud_files
|
@@ -470,7 +467,7 @@ If you are using Paperclip, you can use the provided compatibility module:
|
|
470
467
|
include CarrierWave::Compatibility::Paperclip
|
471
468
|
end
|
472
469
|
|
473
|
-
See the documentation for <code>
|
470
|
+
See the documentation for <code>CarrierWave::Compatibility::Paperclip</code> for more
|
474
471
|
detaills.
|
475
472
|
|
476
473
|
Be sure to use mount_on to specify the correct column:
|
@@ -491,27 +488,6 @@ your translations file:
|
|
491
488
|
integrity: 'Not an image.'
|
492
489
|
processing: 'Cannot resize image.'
|
493
490
|
|
494
|
-
== Contributors
|
495
|
-
|
496
|
-
These people have contributed their time and effort to CarrierWave:
|
497
|
-
|
498
|
-
* Jonas Nicklas
|
499
|
-
* Pavel Kunc
|
500
|
-
* Andrew Timberlake
|
501
|
-
* Durran Jordan
|
502
|
-
* Scott Motte
|
503
|
-
* Sho Fukamachi
|
504
|
-
* Sam Lown
|
505
|
-
* Dave Ott
|
506
|
-
* Quin Hoxie
|
507
|
-
* H. Wade Minter
|
508
|
-
* Trevor Turk
|
509
|
-
* Nicklas Ramhöj
|
510
|
-
* Matt Hooks
|
511
|
-
* Andreas Haller
|
512
|
-
* Lars Pind
|
513
|
-
* Ramon Soares
|
514
|
-
|
515
491
|
== License
|
516
492
|
|
517
493
|
Copyright (c) 2008 Jonas Nicklas
|
@@ -540,7 +516,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
540
516
|
In order to setup a development environment and run the specs, you'll
|
541
517
|
need to install bundler:
|
542
518
|
|
543
|
-
gem install bundler
|
519
|
+
gem install bundler
|
544
520
|
|
545
521
|
And then install the dependencies:
|
546
522
|
|
data/lib/carrierwave.rb
CHANGED
@@ -7,8 +7,6 @@ require 'active_support/concern'
|
|
7
7
|
|
8
8
|
module CarrierWave
|
9
9
|
|
10
|
-
VERSION = "0.4.5"
|
11
|
-
|
12
10
|
class << self
|
13
11
|
attr_accessor :root
|
14
12
|
|
@@ -32,6 +30,7 @@ module CarrierWave
|
|
32
30
|
autoload :RMagick, 'carrierwave/processing/rmagick'
|
33
31
|
autoload :ImageScience, 'carrierwave/processing/image_science'
|
34
32
|
autoload :MiniMagick, 'carrierwave/processing/mini_magick'
|
33
|
+
autoload :VERSION, 'carrierwave/version'
|
35
34
|
|
36
35
|
module Storage
|
37
36
|
autoload :Abstract, 'carrierwave/storage/abstract'
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'active_record'
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + "../../validations/active_model")
|
4
5
|
|
5
6
|
module CarrierWave
|
6
7
|
module ActiveRecord
|
@@ -18,62 +19,18 @@ module CarrierWave
|
|
18
19
|
public :read_uploader
|
19
20
|
public :write_uploader
|
20
21
|
|
22
|
+
include CarrierWave::Validations::ActiveModel
|
23
|
+
|
21
24
|
validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
|
22
25
|
validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
|
23
26
|
|
24
27
|
after_save "store_#{column}!"
|
25
28
|
before_save "write_#{column}_identifier"
|
26
29
|
after_destroy "remove_#{column}!"
|
27
|
-
end
|
28
|
-
|
29
|
-
##
|
30
|
-
# Makes the record invalid if the file couldn't be uploaded due to an integrity error
|
31
|
-
#
|
32
|
-
# Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
|
33
|
-
#
|
34
|
-
# === Note
|
35
|
-
#
|
36
|
-
# Set this key in your translations file for I18n:
|
37
|
-
#
|
38
|
-
# carrierwave:
|
39
|
-
# errors:
|
40
|
-
# integrity: 'Here be an error message'
|
41
|
-
#
|
42
|
-
def validates_integrity_of(*attrs)
|
43
|
-
options = attrs.last.is_a?(Hash) ? attrs.last : {}
|
44
|
-
validates_each(*attrs) do |record, attr, value|
|
45
|
-
if record.send("#{attr}_integrity_error")
|
46
|
-
message = options[:message] || I18n.t('carrierwave.errors.integrity', :default => 'is not an allowed type of file.')
|
47
|
-
record.errors.add attr, message
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
30
|
|
52
|
-
##
|
53
|
-
# Makes the record invalid if the file couldn't be processed (assuming the process failed
|
54
|
-
# with a CarrierWave::ProcessingError)
|
55
|
-
#
|
56
|
-
# Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
|
57
|
-
#
|
58
|
-
# === Note
|
59
|
-
#
|
60
|
-
# Set this key in your translations file for I18n:
|
61
|
-
#
|
62
|
-
# carrierwave:
|
63
|
-
# errors:
|
64
|
-
# processing: 'Here be an error message'
|
65
|
-
#
|
66
|
-
def validates_processing_of(*attrs)
|
67
|
-
options = attrs.last.is_a?(Hash) ? attrs.last : {}
|
68
|
-
validates_each(*attrs) do |record, attr, value|
|
69
|
-
if record.send("#{attr}_processing_error")
|
70
|
-
message = options[:message] || I18n.t('carrierwave.errors.processing', :default => 'failed to be processed.')
|
71
|
-
record.errors.add attr, message
|
72
|
-
end
|
73
|
-
end
|
74
31
|
end
|
75
32
|
|
76
33
|
end # ActiveRecord
|
77
34
|
end # CarrierWave
|
78
35
|
|
79
|
-
ActiveRecord::Base.
|
36
|
+
ActiveRecord::Base.extend CarrierWave::ActiveRecord
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'mongoid'
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "../../validations/active_model")
|
3
4
|
|
4
5
|
module CarrierWave
|
5
6
|
module Mongoid
|
@@ -10,9 +11,17 @@ module CarrierWave
|
|
10
11
|
def mount_uploader(column, uploader, options={}, &block)
|
11
12
|
options[:mount_on] ||= "#{column}_filename"
|
12
13
|
field options[:mount_on]
|
14
|
+
|
13
15
|
super
|
16
|
+
|
14
17
|
alias_method :read_uploader, :read_attribute
|
15
18
|
alias_method :write_uploader, :write_attribute
|
19
|
+
|
20
|
+
include CarrierWave::Validations::ActiveModel
|
21
|
+
|
22
|
+
validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
|
23
|
+
validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
|
24
|
+
|
16
25
|
after_save "store_#{column}!".to_sym
|
17
26
|
before_save "write_#{column}_identifier".to_sym
|
18
27
|
after_destroy "remove_#{column}!".to_sym
|
@@ -20,4 +29,4 @@ module CarrierWave
|
|
20
29
|
end # Mongoid
|
21
30
|
end # CarrierWave
|
22
31
|
|
23
|
-
Mongoid::Document::ClassMethods.send(:include, CarrierWave::Mongoid)
|
32
|
+
Mongoid::Document::ClassMethods.send(:include, CarrierWave::Mongoid)
|
@@ -1,17 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
begin
|
3
|
-
require '
|
3
|
+
require 'fog'
|
4
4
|
rescue LoadError
|
5
|
-
raise "You don't have the '
|
5
|
+
raise "You don't have the 'fog' gem installed. The 'aws', 'aws-s3' and 'right_aws' gems are no longer supported."
|
6
6
|
end
|
7
7
|
|
8
8
|
module CarrierWave
|
9
9
|
module Storage
|
10
10
|
|
11
11
|
##
|
12
|
-
# Uploads things to Amazon S3
|
13
|
-
#
|
14
|
-
# and bucket
|
12
|
+
# Uploads things to Amazon S3 using the "fog" gem.
|
13
|
+
# You'll need to specify the access_key_id, secret_access_key and bucket.
|
15
14
|
#
|
16
15
|
# CarrierWave.configure do |config|
|
17
16
|
# config.s3_access_key_id = "xxxxxx"
|
@@ -19,9 +18,6 @@ module CarrierWave
|
|
19
18
|
# config.s3_bucket = "my_bucket_name"
|
20
19
|
# end
|
21
20
|
#
|
22
|
-
# The AWS::S3Interface is used directly as opposed to the normal AWS::S3::Bucket et.al. classes.
|
23
|
-
# This gives much improved performance and avoids unnecessary requests.
|
24
|
-
#
|
25
21
|
# You can set the access policy for the uploaded files:
|
26
22
|
#
|
27
23
|
# CarrierWave.configure do |config|
|
@@ -51,7 +47,7 @@ module CarrierWave
|
|
51
47
|
# end
|
52
48
|
#
|
53
49
|
# Now the resulting url will be
|
54
|
-
#
|
50
|
+
#
|
55
51
|
# http://bucketname.domain.tld/path/to/file
|
56
52
|
#
|
57
53
|
# instead of
|
@@ -87,16 +83,16 @@ module CarrierWave
|
|
87
83
|
# [String] contents of the file
|
88
84
|
#
|
89
85
|
def read
|
90
|
-
result = connection.
|
91
|
-
@headers = result
|
92
|
-
result
|
86
|
+
result = connection.get_object(bucket, @path)
|
87
|
+
@headers = result.headers
|
88
|
+
result.body
|
93
89
|
end
|
94
90
|
|
95
91
|
##
|
96
92
|
# Remove the file from Amazon S3
|
97
93
|
#
|
98
94
|
def delete
|
99
|
-
connection.
|
95
|
+
connection.delete_object(bucket, @path)
|
100
96
|
end
|
101
97
|
|
102
98
|
##
|
@@ -116,10 +112,10 @@ module CarrierWave
|
|
116
112
|
|
117
113
|
def store(file)
|
118
114
|
content_type ||= file.content_type # this might cause problems if content type changes between read and upload (unlikely)
|
119
|
-
connection.
|
115
|
+
connection.put_object(bucket, @path, file.read,
|
120
116
|
{
|
121
117
|
'x-amz-acl' => access_policy,
|
122
|
-
'
|
118
|
+
'Content-Type' => content_type
|
123
119
|
}.merge(@uploader.s3_headers)
|
124
120
|
)
|
125
121
|
end
|
@@ -127,7 +123,7 @@ module CarrierWave
|
|
127
123
|
# The Amazon S3 Access policy ready to send in storage request headers.
|
128
124
|
def access_policy
|
129
125
|
return @access_policy unless @access_policy.blank?
|
130
|
-
if @uploader.s3_access_policy.blank?
|
126
|
+
if @uploader.s3_access_policy.blank?
|
131
127
|
if !@uploader.s3_access.blank?
|
132
128
|
@access_policy = @uploader.s3_access.to_s.gsub(/_/, '-')
|
133
129
|
else
|
@@ -139,20 +135,24 @@ module CarrierWave
|
|
139
135
|
end
|
140
136
|
|
141
137
|
def content_type
|
142
|
-
headers["
|
138
|
+
headers["Content-Type"]
|
143
139
|
end
|
144
140
|
|
145
141
|
def content_type=(type)
|
146
|
-
headers["
|
142
|
+
headers["Content-Type"] = type
|
143
|
+
end
|
144
|
+
|
145
|
+
def size
|
146
|
+
headers['content-length'].to_i
|
147
147
|
end
|
148
148
|
|
149
149
|
# Headers returned from file retrieval
|
150
150
|
def headers
|
151
|
-
@headers ||=
|
151
|
+
@headers ||= connection.head(bucket, @path)
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
private
|
155
|
-
|
155
|
+
|
156
156
|
def bucket
|
157
157
|
@uploader.s3_bucket
|
158
158
|
end
|
@@ -172,7 +172,7 @@ module CarrierWave
|
|
172
172
|
#
|
173
173
|
# === Returns
|
174
174
|
#
|
175
|
-
# [CarrierWave::Storage::
|
175
|
+
# [CarrierWave::Storage::S3::File] the stored file
|
176
176
|
#
|
177
177
|
def store!(file)
|
178
178
|
f = CarrierWave::Storage::S3::File.new(uploader, self, uploader.store_path)
|
@@ -188,16 +188,16 @@ module CarrierWave
|
|
188
188
|
#
|
189
189
|
# === Returns
|
190
190
|
#
|
191
|
-
# [CarrierWave::Storage::
|
191
|
+
# [CarrierWave::Storage::S3::File] the stored file
|
192
192
|
#
|
193
193
|
def retrieve!(identifier)
|
194
194
|
CarrierWave::Storage::S3::File.new(uploader, self, uploader.store_path(identifier))
|
195
195
|
end
|
196
196
|
|
197
197
|
def connection
|
198
|
-
@connection ||=
|
199
|
-
uploader.s3_access_key_id,
|
200
|
-
:
|
198
|
+
@connection ||= Fog::AWS::S3.new(
|
199
|
+
:aws_access_key_id => uploader.s3_access_key_id,
|
200
|
+
:aws_secret_access_key => uploader.s3_secret_access_key
|
201
201
|
)
|
202
202
|
end
|
203
203
|
|
@@ -87,7 +87,7 @@ module CarrierWave
|
|
87
87
|
#
|
88
88
|
def cache!(new_file)
|
89
89
|
new_file = CarrierWave::SanitizedFile.new(new_file)
|
90
|
-
raise CarrierWave::FormNotMultipart if new_file.is_path?
|
90
|
+
raise CarrierWave::FormNotMultipart if new_file.is_path? && ensure_multipart_form
|
91
91
|
|
92
92
|
unless new_file.empty?
|
93
93
|
with_callbacks(:cache, new_file) do
|
@@ -8,14 +8,13 @@ module CarrierWave
|
|
8
8
|
add_config :root
|
9
9
|
add_config :permissions
|
10
10
|
add_config :storage_engines
|
11
|
-
add_config :s3_access # for old
|
12
|
-
add_config :s3_access_policy # for
|
11
|
+
add_config :s3_access # for old s3 support
|
12
|
+
add_config :s3_access_policy # for new s3 support
|
13
13
|
add_config :s3_bucket
|
14
14
|
add_config :s3_access_key_id
|
15
15
|
add_config :s3_secret_access_key
|
16
16
|
add_config :s3_cnamed
|
17
17
|
add_config :s3_headers
|
18
|
-
add_config :s3_multi_thread
|
19
18
|
add_config :cloud_files_username
|
20
19
|
add_config :cloud_files_api_key
|
21
20
|
add_config :cloud_files_container
|
@@ -29,7 +28,8 @@ module CarrierWave
|
|
29
28
|
add_config :store_dir
|
30
29
|
add_config :cache_dir
|
31
30
|
add_config :enable_processing
|
32
|
-
|
31
|
+
add_config :ensure_multipart_form
|
32
|
+
|
33
33
|
# Mounting
|
34
34
|
add_config :ignore_integrity_errors
|
35
35
|
add_config :ignore_processing_errors
|
@@ -47,10 +47,7 @@ module CarrierWave
|
|
47
47
|
:cloud_files => "CarrierWave::Storage::CloudFiles"
|
48
48
|
}
|
49
49
|
config.storage = :file
|
50
|
-
#config.s3_access = :public_read
|
51
|
-
#config.s3_access_policy = 'public-read' # Now set in library
|
52
50
|
config.s3_headers = {}
|
53
|
-
config.s3_multi_thread = true
|
54
51
|
config.grid_fs_database = 'carrierwave'
|
55
52
|
config.grid_fs_host = 'localhost'
|
56
53
|
config.grid_fs_port = 27017
|
@@ -62,6 +59,7 @@ module CarrierWave
|
|
62
59
|
config.validate_processing = true
|
63
60
|
config.root = CarrierWave.root
|
64
61
|
config.enable_processing = true
|
62
|
+
config.ensure_multipart_form = true
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'open-uri'
|
4
4
|
|
5
5
|
module CarrierWave
|
6
6
|
module Uploader
|
@@ -13,7 +13,7 @@ module CarrierWave
|
|
13
13
|
|
14
14
|
class RemoteFile
|
15
15
|
def initialize(uri)
|
16
|
-
@uri = URI.parse(uri)
|
16
|
+
@uri = URI.parse(URI.escape(uri))
|
17
17
|
end
|
18
18
|
|
19
19
|
def original_filename
|
@@ -31,7 +31,11 @@ module CarrierWave
|
|
31
31
|
private
|
32
32
|
|
33
33
|
def file
|
34
|
-
@file
|
34
|
+
if @file.blank?
|
35
|
+
@file = Kernel.open(@uri.to_s)
|
36
|
+
@file = @file.is_a?(String) ? StringIO.new(@file) : @file
|
37
|
+
end
|
38
|
+
@file
|
35
39
|
end
|
36
40
|
|
37
41
|
def method_missing(*args, &block)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'active_model/validator'
|
4
|
+
require 'active_support/concern'
|
5
|
+
|
6
|
+
|
7
|
+
module CarrierWave
|
8
|
+
|
9
|
+
# == Active Model Presence Validator
|
10
|
+
module Validations
|
11
|
+
module ActiveModel
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
class ProcessingValidator < ::ActiveModel::EachValidator
|
15
|
+
|
16
|
+
def validate_each(record, attribute, value)
|
17
|
+
if record.send("#{attribute}_processing_error")
|
18
|
+
record.errors.add(attribute, :carrierwave_processing_error)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class IntegrityValidator < ::ActiveModel::EachValidator
|
24
|
+
|
25
|
+
def validate_each(record, attribute, value)
|
26
|
+
if record.send("#{attribute}_integrity_error")
|
27
|
+
record.errors.add(attribute, :carrierwave_integrity_error)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module HelperMethods
|
33
|
+
|
34
|
+
##
|
35
|
+
# Makes the record invalid if the file couldn't be uploaded due to an integrity error
|
36
|
+
#
|
37
|
+
# Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
|
38
|
+
#
|
39
|
+
# === Note
|
40
|
+
#
|
41
|
+
# Set this key in your translations file for I18n:
|
42
|
+
#
|
43
|
+
# carrierwave:
|
44
|
+
# errors:
|
45
|
+
# integrity: 'Here be an error message'
|
46
|
+
#
|
47
|
+
def validates_integrity_of(*attr_names)
|
48
|
+
validates_with IntegrityValidator, _merge_attributes(attr_names)
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Makes the record invalid if the file couldn't be processed (assuming the process failed
|
53
|
+
# with a CarrierWave::ProcessingError)
|
54
|
+
#
|
55
|
+
# Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
|
56
|
+
#
|
57
|
+
# === Note
|
58
|
+
#
|
59
|
+
# Set this key in your translations file for I18n:
|
60
|
+
#
|
61
|
+
# carrierwave:
|
62
|
+
# errors:
|
63
|
+
# processing: 'Here be an error message'
|
64
|
+
#
|
65
|
+
def validates_processing_of(*attr_names)
|
66
|
+
validates_with ProcessingValidator, _merge_attributes(attr_names)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
included do
|
71
|
+
extend HelperMethods
|
72
|
+
include HelperMethods
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
I18n.load_path << File.join(File.dirname(__FILE__), "..", "locale", 'en.yml')
|
79
|
+
|
@@ -2,46 +2,46 @@
|
|
2
2
|
|
3
3
|
class <%= class_name %>Uploader < CarrierWave::Uploader::Base
|
4
4
|
|
5
|
-
# Include RMagick or ImageScience support
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# Include RMagick or ImageScience support:
|
6
|
+
# include CarrierWave::RMagick
|
7
|
+
# include CarrierWave::ImageScience
|
8
8
|
|
9
|
-
# Choose what kind of storage to use for this uploader
|
9
|
+
# Choose what kind of storage to use for this uploader:
|
10
10
|
storage :file
|
11
|
-
#
|
11
|
+
# storage :s3
|
12
12
|
|
13
|
-
# Override the directory where uploaded files will be stored
|
13
|
+
# Override the directory where uploaded files will be stored.
|
14
14
|
# This is a sensible default for uploaders that are meant to be mounted:
|
15
15
|
def store_dir
|
16
16
|
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
17
17
|
end
|
18
18
|
|
19
|
-
# Provide a default URL as a default if there hasn't been a file uploaded
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
19
|
+
# Provide a default URL as a default if there hasn't been a file uploaded:
|
20
|
+
# def default_url
|
21
|
+
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
22
|
+
# end
|
23
23
|
|
24
|
-
# Process files as they are uploaded
|
25
|
-
#
|
24
|
+
# Process files as they are uploaded:
|
25
|
+
# process :scale => [200, 300]
|
26
26
|
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
# Create different versions of your uploaded files
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
|
36
|
-
# Add a white list of extensions which are allowed to be uploaded
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
|
42
|
-
# Override the filename of the uploaded files
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
27
|
+
# def scale(width, height)
|
28
|
+
# # do something
|
29
|
+
# end
|
30
|
+
|
31
|
+
# Create different versions of your uploaded files:
|
32
|
+
# version :thumb do
|
33
|
+
# process :scale => [50, 50]
|
34
|
+
# end
|
35
|
+
|
36
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
37
|
+
# For images you might use something like this:
|
38
|
+
# def extension_white_list
|
39
|
+
# %w(jpg jpeg gif png)
|
40
|
+
# end
|
41
|
+
|
42
|
+
# Override the filename of the uploaded files:
|
43
|
+
# def filename
|
44
|
+
# "something.jpg" if original_filename
|
45
|
+
# end
|
46
46
|
|
47
47
|
end
|
@@ -1,13 +1,7 @@
|
|
1
|
-
require 'rails/generators'
|
2
|
-
require 'rails/generators/named_base'
|
3
|
-
|
4
1
|
class UploaderGenerator < Rails::Generators::NamedBase
|
2
|
+
source_root File.expand_path("../templates", __FILE__)
|
3
|
+
|
5
4
|
def create_uploader_file
|
6
|
-
template
|
5
|
+
template "uploader.rb", "app/uploaders/#{file_name}_uploader.rb"
|
7
6
|
end
|
8
|
-
|
9
|
-
def self.source_root
|
10
|
-
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
7
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 5
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.5.0.beta2
|
9
|
+
version: 0.5.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Jonas Nicklas
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-
|
17
|
+
date: 2010-09-23 00:00:00 +02:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -24,16 +23,260 @@ dependencies:
|
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
|
-
- -
|
26
|
+
- - ~>
|
28
27
|
- !ruby/object:Gem::Version
|
29
28
|
segments:
|
30
29
|
- 3
|
31
30
|
- 0
|
32
31
|
- 0
|
33
|
-
|
34
|
-
version: 3.0.0.beta4
|
32
|
+
version: 3.0.0
|
35
33
|
type: :runtime
|
36
34
|
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rails
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 3
|
45
|
+
- 0
|
46
|
+
- 0
|
47
|
+
version: 3.0.0
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rspec
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 3
|
61
|
+
- 0
|
62
|
+
version: 1.3.0
|
63
|
+
type: :development
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: fog
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
- 2
|
76
|
+
- 30
|
77
|
+
version: 0.2.30
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: cucumber
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id005
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: sqlite3-ruby
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
104
|
+
type: :development
|
105
|
+
version_requirements: *id006
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: dm-core
|
108
|
+
prerelease: false
|
109
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
type: :development
|
118
|
+
version_requirements: *id007
|
119
|
+
- !ruby/object:Gem::Dependency
|
120
|
+
name: dm-validations
|
121
|
+
prerelease: false
|
122
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
version: "0"
|
130
|
+
type: :development
|
131
|
+
version_requirements: *id008
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
name: dm-migrations
|
134
|
+
prerelease: false
|
135
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
version: "0"
|
143
|
+
type: :development
|
144
|
+
version_requirements: *id009
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: dm-sqlite-adapter
|
147
|
+
prerelease: false
|
148
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
segments:
|
154
|
+
- 0
|
155
|
+
version: "0"
|
156
|
+
type: :development
|
157
|
+
version_requirements: *id010
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: sequel
|
160
|
+
prerelease: false
|
161
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
162
|
+
none: false
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
segments:
|
167
|
+
- 0
|
168
|
+
version: "0"
|
169
|
+
type: :development
|
170
|
+
version_requirements: *id011
|
171
|
+
- !ruby/object:Gem::Dependency
|
172
|
+
name: rmagick
|
173
|
+
prerelease: false
|
174
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
175
|
+
none: false
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
segments:
|
180
|
+
- 0
|
181
|
+
version: "0"
|
182
|
+
type: :development
|
183
|
+
version_requirements: *id012
|
184
|
+
- !ruby/object:Gem::Dependency
|
185
|
+
name: RubyInline
|
186
|
+
prerelease: false
|
187
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
188
|
+
none: false
|
189
|
+
requirements:
|
190
|
+
- - ">="
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
segments:
|
193
|
+
- 0
|
194
|
+
version: "0"
|
195
|
+
type: :development
|
196
|
+
version_requirements: *id013
|
197
|
+
- !ruby/object:Gem::Dependency
|
198
|
+
name: image_science
|
199
|
+
prerelease: false
|
200
|
+
requirement: &id014 !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ">="
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
segments:
|
206
|
+
- 0
|
207
|
+
version: "0"
|
208
|
+
type: :development
|
209
|
+
version_requirements: *id014
|
210
|
+
- !ruby/object:Gem::Dependency
|
211
|
+
name: mini_magick
|
212
|
+
prerelease: false
|
213
|
+
requirement: &id015 !ruby/object:Gem::Requirement
|
214
|
+
none: false
|
215
|
+
requirements:
|
216
|
+
- - ~>
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
segments:
|
219
|
+
- 2
|
220
|
+
- 1
|
221
|
+
version: "2.1"
|
222
|
+
type: :development
|
223
|
+
version_requirements: *id015
|
224
|
+
- !ruby/object:Gem::Dependency
|
225
|
+
name: mongoid
|
226
|
+
prerelease: false
|
227
|
+
requirement: &id016 !ruby/object:Gem::Requirement
|
228
|
+
none: false
|
229
|
+
requirements:
|
230
|
+
- - "="
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
segments:
|
233
|
+
- 2
|
234
|
+
- 0
|
235
|
+
- 0
|
236
|
+
- beta
|
237
|
+
- 17
|
238
|
+
version: 2.0.0.beta.17
|
239
|
+
type: :development
|
240
|
+
version_requirements: *id016
|
241
|
+
- !ruby/object:Gem::Dependency
|
242
|
+
name: bson_ext
|
243
|
+
prerelease: false
|
244
|
+
requirement: &id017 !ruby/object:Gem::Requirement
|
245
|
+
none: false
|
246
|
+
requirements:
|
247
|
+
- - ">="
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
segments:
|
250
|
+
- 0
|
251
|
+
version: "0"
|
252
|
+
type: :development
|
253
|
+
version_requirements: *id017
|
254
|
+
- !ruby/object:Gem::Dependency
|
255
|
+
name: timecop
|
256
|
+
prerelease: false
|
257
|
+
requirement: &id018 !ruby/object:Gem::Requirement
|
258
|
+
none: false
|
259
|
+
requirements:
|
260
|
+
- - ">="
|
261
|
+
- !ruby/object:Gem::Version
|
262
|
+
segments:
|
263
|
+
- 0
|
264
|
+
version: "0"
|
265
|
+
type: :development
|
266
|
+
version_requirements: *id018
|
267
|
+
- !ruby/object:Gem::Dependency
|
268
|
+
name: json
|
269
|
+
prerelease: false
|
270
|
+
requirement: &id019 !ruby/object:Gem::Requirement
|
271
|
+
none: false
|
272
|
+
requirements:
|
273
|
+
- - ">="
|
274
|
+
- !ruby/object:Gem::Version
|
275
|
+
segments:
|
276
|
+
- 0
|
277
|
+
version: "0"
|
278
|
+
type: :development
|
279
|
+
version_requirements: *id019
|
37
280
|
description: Upload files in your Ruby applications, map them to a range of ORMs, store them on different backends.
|
38
281
|
email:
|
39
282
|
- jonas.nicklas@gmail.com
|
@@ -45,6 +288,7 @@ extra_rdoc_files:
|
|
45
288
|
- README.rdoc
|
46
289
|
files:
|
47
290
|
- lib/carrierwave/compatibility/paperclip.rb
|
291
|
+
- lib/carrierwave/locale/en.yml
|
48
292
|
- lib/carrierwave/mount.rb
|
49
293
|
- lib/carrierwave/orm/activerecord.rb
|
50
294
|
- lib/carrierwave/orm/datamapper.rb
|
@@ -75,6 +319,8 @@ files:
|
|
75
319
|
- lib/carrierwave/uploader/url.rb
|
76
320
|
- lib/carrierwave/uploader/versions.rb
|
77
321
|
- lib/carrierwave/uploader.rb
|
322
|
+
- lib/carrierwave/validations/active_model.rb
|
323
|
+
- lib/carrierwave/version.rb
|
78
324
|
- lib/carrierwave.rb
|
79
325
|
- lib/generators/templates/uploader.rb
|
80
326
|
- lib/generators/uploader_generator.rb
|
@@ -100,13 +346,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
100
346
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
347
|
none: false
|
102
348
|
requirements:
|
103
|
-
- - "
|
349
|
+
- - ">="
|
104
350
|
- !ruby/object:Gem::Version
|
105
351
|
segments:
|
106
|
-
-
|
107
|
-
|
108
|
-
- 1
|
109
|
-
version: 1.3.1
|
352
|
+
- 0
|
353
|
+
version: "0"
|
110
354
|
requirements: []
|
111
355
|
|
112
356
|
rubyforge_project: carrierwave
|