jnicklas-carrierwave 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Generators +4 -0
- data/LICENSE +20 -0
- data/README.md +211 -0
- data/Rakefile +96 -0
- data/TODO +0 -0
- data/lib/carrierwave/mount.rb +93 -0
- data/lib/carrierwave/orm/activerecord.rb +20 -0
- data/lib/carrierwave/orm/datamapper.rb +20 -0
- data/lib/carrierwave/processing/image_science.rb +70 -0
- data/lib/carrierwave/processing/rmagick.rb +161 -0
- data/lib/carrierwave/sanitized_file.rb +231 -0
- data/lib/carrierwave/storage/abstract.rb +80 -0
- data/lib/carrierwave/storage/file.rb +40 -0
- data/lib/carrierwave/storage/s3.rb +83 -0
- data/lib/carrierwave/uploader.rb +420 -0
- data/lib/carrierwave.rb +63 -0
- data/lib/generators/templates/uploader.rbt +32 -0
- data/lib/generators/uploader_generator.rb +20 -0
- data/spec/fixtures/bork.txt +1 -0
- data/spec/fixtures/test.jpeg +1 -0
- data/spec/fixtures/test.jpg +1 -0
- data/spec/mount_spec.rb +180 -0
- data/spec/orm/activerecord_spec.rb +168 -0
- data/spec/orm/datamapper_spec.rb +133 -0
- data/spec/sanitized_file_spec.rb +618 -0
- data/spec/spec_helper.rb +122 -0
- data/spec/uploader_spec.rb +709 -0
- metadata +89 -0
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'rmagick'
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
|
5
|
+
##
|
6
|
+
# This module simplifies manipulation with RMagick by providing a set
|
7
|
+
# of convenient helper methods. If you want to use them, you'll need to
|
8
|
+
# require this file
|
9
|
+
#
|
10
|
+
# require 'carrierwave/processing/rmagick'
|
11
|
+
#
|
12
|
+
# And then include it in your uploader
|
13
|
+
#
|
14
|
+
# MyUploade < CarrierWave::Uploader
|
15
|
+
# include CarrierWave::RMagick
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# You can now use the provided helpers:
|
19
|
+
#
|
20
|
+
# MyUploade < CarrierWave::Uploader
|
21
|
+
# include CarrierWave::RMagick
|
22
|
+
#
|
23
|
+
# process :resize_to_fit => [200, 200]
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Or create your own helpers with the powerful manipulate! method. Check
|
27
|
+
# out the RMagick docs at http://www.imagemagick.org/RMagick/doc/ for more
|
28
|
+
# info
|
29
|
+
#
|
30
|
+
# MyUploade < CarrierWave::Uploader
|
31
|
+
# include CarrierWave::RMagick
|
32
|
+
#
|
33
|
+
# process :do_stuff => 10.0
|
34
|
+
#
|
35
|
+
# def do_stuff(blur_factor)
|
36
|
+
# manipulate! do |img|
|
37
|
+
# img = img.sepiatone
|
38
|
+
# img = img.auto_orient
|
39
|
+
# img = img.radial_blur(blur_factor)
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
module RMagick
|
45
|
+
|
46
|
+
##
|
47
|
+
# Changes the image encoding format to the given format
|
48
|
+
#
|
49
|
+
# @see http://www.imagemagick.org/RMagick/doc/magick.html#formats
|
50
|
+
# @param [#to_s] format an abreviation of the format
|
51
|
+
# @yieldparam [Magick::Image] img additional manipulations to perform
|
52
|
+
# @example
|
53
|
+
# image.convert(:png)
|
54
|
+
#
|
55
|
+
def convert(format)
|
56
|
+
manipulate! do |img|
|
57
|
+
img.format = format.to_s.upcase
|
58
|
+
img = yield(img) if block_given?
|
59
|
+
img
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# From the RMagick documentation: "Resize the image to fit within the
|
65
|
+
# specified dimensions while retaining the original aspect ratio. The
|
66
|
+
# image may be shorter or narrower than specified in the smaller dimension
|
67
|
+
# but will not be larger than the specified values."
|
68
|
+
#
|
69
|
+
# @see http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fit
|
70
|
+
#
|
71
|
+
# @param [Integer] width the width to scale the image to
|
72
|
+
# @param [Integer] height the height to scale the image to
|
73
|
+
# @yieldparam [Magick::Image] img additional manipulations to perform
|
74
|
+
#
|
75
|
+
def resize_to_fit(width, height)
|
76
|
+
manipulate! do |img|
|
77
|
+
img.resize_to_fit!(width, height)
|
78
|
+
img = yield(img) if block_given?
|
79
|
+
img
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :resize, :resize_to_fit
|
84
|
+
|
85
|
+
##
|
86
|
+
# From the RMagick documentation: "Resize the image to fit within the
|
87
|
+
# specified dimensions while retaining the aspect ratio of the original
|
88
|
+
# image. If necessary, crop the image in the larger dimension."
|
89
|
+
#
|
90
|
+
# @see http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fill
|
91
|
+
#
|
92
|
+
# @param [Integer] width the width to scale the image to
|
93
|
+
# @param [Integer] height the height to scale the image to
|
94
|
+
# @yieldparam [Magick::Image] img additional manipulations to perform
|
95
|
+
#
|
96
|
+
def resize_to_fill(width, height)
|
97
|
+
manipulate! do |img|
|
98
|
+
img.resize_to_fill!(width, height)
|
99
|
+
img = yield(img) if block_given?
|
100
|
+
img
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
alias_method :crop_resized, :resize_to_fill
|
105
|
+
|
106
|
+
##
|
107
|
+
# Resize the image to fit within the specified dimensions while retaining
|
108
|
+
# the original aspect ratio. If necessary will pad the remaining area
|
109
|
+
# with the given color, which defaults to transparent (for gif and png,
|
110
|
+
# white for jpeg).
|
111
|
+
#
|
112
|
+
# @param [Integer] width the width to scale the image to
|
113
|
+
# @param [Integer] height the height to scale the image to
|
114
|
+
# @param [String, :transparent] background the color of the background as a hexcode, like "#ff45de"
|
115
|
+
# @param [Magick::GravityType] gravity how to position the image
|
116
|
+
# @yieldparam [Magick::Image] img additional manipulations to perform
|
117
|
+
#
|
118
|
+
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
|
119
|
+
manipulate! do |img|
|
120
|
+
img.resize_to_fit!(width, height)
|
121
|
+
new_img = ::Magick::Image.new(width, height)
|
122
|
+
if background == :transparent
|
123
|
+
new_img = new_img.matte_floodfill(1, 1)
|
124
|
+
else
|
125
|
+
new_img = new_img.color_floodfill(1, 1, ::Magick::Pixel.from_color(background))
|
126
|
+
end
|
127
|
+
new_img = new_img.composite(img, gravity, ::Magick::OverCompositeOp)
|
128
|
+
new_img = yield(new_img) if block_given?
|
129
|
+
new_img
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Manipulate the image with RMagick. This method will load up an image
|
135
|
+
# and then pass each of its frames to the supplied block. It will then
|
136
|
+
# save the image to disk.
|
137
|
+
#
|
138
|
+
# Note: This method assumes that the object responds to current_path
|
139
|
+
# any class that this is mixed into must have a current_path method.
|
140
|
+
#
|
141
|
+
# @yieldparam [Magick::Image] img manipulations to perform
|
142
|
+
# @raise [CarrierWave::ProcessingError] if manipulation failed.
|
143
|
+
#
|
144
|
+
def manipulate!
|
145
|
+
image = ::Magick::Image.read(current_path)
|
146
|
+
|
147
|
+
if image.size > 1
|
148
|
+
list = ::Magick::ImageList.new
|
149
|
+
image.each do |frame|
|
150
|
+
list << yield( frame )
|
151
|
+
end
|
152
|
+
list.write(current_path)
|
153
|
+
else
|
154
|
+
yield( image.first ).write(current_path)
|
155
|
+
end
|
156
|
+
rescue ::Magick::ImageMagickError => e
|
157
|
+
raise CarrierWave::ProcessingError.new("Failed to manipulate with rmagick, maybe it is not an image? Original Error: #{e}")
|
158
|
+
end
|
159
|
+
|
160
|
+
end # RMagick
|
161
|
+
end # CarrierWave
|
@@ -0,0 +1,231 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
class SanitizedFile
|
3
|
+
|
4
|
+
attr_accessor :file, :options
|
5
|
+
|
6
|
+
def initialize(file, options = {})
|
7
|
+
self.file = file
|
8
|
+
self.options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# Returns the filename as is, without sanizting it.
|
13
|
+
#
|
14
|
+
# @return [String] the unsanitized filename
|
15
|
+
#
|
16
|
+
def original_filename
|
17
|
+
return @original_filename if @original_filename
|
18
|
+
if @file and @file.respond_to?(:original_filename)
|
19
|
+
@file.original_filename
|
20
|
+
elsif path
|
21
|
+
File.basename(path)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Returns the filename, sanitized to strip out any evil characters.
|
27
|
+
#
|
28
|
+
# @return [String] the sanitized filename
|
29
|
+
#
|
30
|
+
def filename
|
31
|
+
sanitize(original_filename) if original_filename
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :identifier, :filename
|
35
|
+
|
36
|
+
##
|
37
|
+
# Returns the part of the filename before the extension. So if a file is called 'test.jpeg'
|
38
|
+
# this would return 'test'
|
39
|
+
#
|
40
|
+
# @return [String] the first part of the filename
|
41
|
+
#
|
42
|
+
def basename
|
43
|
+
split_extension(filename)[0] if filename
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Returns the file extension
|
48
|
+
#
|
49
|
+
# @return [String] the extension
|
50
|
+
#
|
51
|
+
def extension
|
52
|
+
split_extension(filename)[1] if filename
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Returns the file's size.
|
57
|
+
#
|
58
|
+
# @return [Integer] the file's size in bytes.
|
59
|
+
#
|
60
|
+
def size
|
61
|
+
if @file.respond_to?(:size)
|
62
|
+
@file.size
|
63
|
+
elsif path
|
64
|
+
File.size(path)
|
65
|
+
else
|
66
|
+
0
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Returns the full path to the file. If the file has no path, it will return nil.
|
72
|
+
#
|
73
|
+
# @return [String, nil] the path where the file is located.
|
74
|
+
#
|
75
|
+
def path
|
76
|
+
unless @file.blank?
|
77
|
+
if string?
|
78
|
+
File.expand_path(@file)
|
79
|
+
elsif @file.respond_to?(:path) and not @file.path.blank?
|
80
|
+
File.expand_path(@file.path)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Returns true if the file is supplied as a pathname or as a string.
|
87
|
+
#
|
88
|
+
# @return [Boolean]
|
89
|
+
#
|
90
|
+
def string?
|
91
|
+
!!((@file.is_a?(String) || @file.is_a?(Pathname)) && !@file.blank?)
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Checks if the file is valid and has a non-zero size
|
96
|
+
#
|
97
|
+
# @return [Boolean]
|
98
|
+
#
|
99
|
+
def empty?
|
100
|
+
(@file.nil? && @path.nil?) || self.size.nil? || self.size.zero?
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Checks if the file exists
|
105
|
+
#
|
106
|
+
# @return [Boolean]
|
107
|
+
#
|
108
|
+
def exists?
|
109
|
+
return File.exists?(self.path) if self.path
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Returns the contents of the file.
|
115
|
+
#
|
116
|
+
# @return [String] contents of the file
|
117
|
+
#
|
118
|
+
def read
|
119
|
+
if string?
|
120
|
+
File.read(@file)
|
121
|
+
else
|
122
|
+
@file.rewind if @file.respond_to?(:rewind)
|
123
|
+
@file.read
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# Moves the file to the given path
|
129
|
+
#
|
130
|
+
# @param [String] new_path The path where the file should be moved.
|
131
|
+
#
|
132
|
+
def move_to(new_path)
|
133
|
+
return if self.empty?
|
134
|
+
new_path = File.expand_path(new_path)
|
135
|
+
|
136
|
+
mkdir!(new_path)
|
137
|
+
if exists?
|
138
|
+
FileUtils.mv(path, new_path) unless new_path == path
|
139
|
+
else
|
140
|
+
File.open(new_path, "wb") { |f| f.write(read) }
|
141
|
+
end
|
142
|
+
chmod!(new_path)
|
143
|
+
self.file = new_path
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Creates a copy of this file and moves it to the given path. Returns the copy.
|
148
|
+
#
|
149
|
+
# @param [String] new_path The path where the file should be copied to.
|
150
|
+
# @return [CarrierWave::SanitizedFile] the location where the file will be stored.
|
151
|
+
#
|
152
|
+
def copy_to(new_path)
|
153
|
+
return if self.empty?
|
154
|
+
new_path = File.expand_path(new_path)
|
155
|
+
|
156
|
+
mkdir!(new_path)
|
157
|
+
if exists?
|
158
|
+
FileUtils.cp(path, new_path) unless new_path == path
|
159
|
+
else
|
160
|
+
File.open(new_path, "wb") { |f| f.write(read) }
|
161
|
+
end
|
162
|
+
chmod!(new_path)
|
163
|
+
self.class.new(new_path)
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Removes the file from the filesystem.
|
168
|
+
#
|
169
|
+
def delete
|
170
|
+
FileUtils.rm(self.path) if exists?
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# Returns the content type of the file.
|
175
|
+
#
|
176
|
+
# @return [String] the content type of the file
|
177
|
+
#
|
178
|
+
def content_type
|
179
|
+
return @content_type if @content_type
|
180
|
+
@file.content_type.chomp if @file.respond_to?(:content_type) and @file.content_type
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def file=(file)
|
186
|
+
if file.is_a?(Hash)
|
187
|
+
@file = file["tempfile"]
|
188
|
+
@original_filename = file["filename"]
|
189
|
+
@content_type = file["content_type"]
|
190
|
+
else
|
191
|
+
@file = file
|
192
|
+
@original_filename = nil
|
193
|
+
@content_type = nil
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# create the directory if it doesn't exist
|
198
|
+
def mkdir!(path)
|
199
|
+
FileUtils.mkdir_p(File.dirname(path)) unless File.exists?(File.dirname(path))
|
200
|
+
end
|
201
|
+
|
202
|
+
def chmod!(path)
|
203
|
+
File.chmod(@options[:permissions], path) if @options[:permissions]
|
204
|
+
end
|
205
|
+
|
206
|
+
# Sanitize the filename, to prevent hacking
|
207
|
+
def sanitize(name)
|
208
|
+
name = name.gsub("\\", "/") # work-around for IE
|
209
|
+
name = File.basename(name)
|
210
|
+
name = name.gsub(/[^a-zA-Z0-9\.\-\+_]/,"_")
|
211
|
+
name = "_#{name}" if name =~ /^\.+$/
|
212
|
+
name = "unnamed" if name.size == 0
|
213
|
+
return name.downcase
|
214
|
+
end
|
215
|
+
|
216
|
+
def split_extension(fn)
|
217
|
+
# regular expressions to try for identifying extensions
|
218
|
+
ext_regexps = [
|
219
|
+
/^(.+)\.([^\.]{1,3}\.[^\.]{1,4})$/, # matches "something.tar.gz"
|
220
|
+
/^(.+)\.([^\.]+)$/ # matches "something.jpg"
|
221
|
+
]
|
222
|
+
ext_regexps.each do |regexp|
|
223
|
+
if fn =~ regexp
|
224
|
+
return $1, $2
|
225
|
+
end
|
226
|
+
end
|
227
|
+
return fn, "" # In case we weren't able to split the extension
|
228
|
+
end
|
229
|
+
|
230
|
+
end # SanitizedFile
|
231
|
+
end # CarrierWave
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Storage
|
3
|
+
##
|
4
|
+
# This file serves mostly as a specification for Storage engines. There is no requirement
|
5
|
+
# that storage engines must be a subclass of this class. However, any storage engine must
|
6
|
+
# conform to the following interface:
|
7
|
+
#
|
8
|
+
# The storage engine must respond to store!, taking an uploader object and a
|
9
|
+
# CarrierWave::SanitizedFile as parameters. This method should do something to store
|
10
|
+
# the given file, and then return an object.
|
11
|
+
#
|
12
|
+
# The storage engine must respond to retrieve!, taking an uploader object and an identifier
|
13
|
+
# as parameters. This method should do retrieve and then return an object.
|
14
|
+
#
|
15
|
+
# The objects returned by store! and retrieve! both *must* respond to +identifier+, taking
|
16
|
+
# no arguments. Identifier is a string that uniquely identifies this file and can be used
|
17
|
+
# to retrieve it later.
|
18
|
+
#
|
19
|
+
class Abstract
|
20
|
+
|
21
|
+
##
|
22
|
+
# Do setup specific for this storage engine
|
23
|
+
#
|
24
|
+
def self.setup!; end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Do something to store the file
|
28
|
+
#
|
29
|
+
# @param [CarrierWave::Uploader] uploader an uploader object
|
30
|
+
# @param [CarrierWave::SanitizedFile] file the file to store
|
31
|
+
#
|
32
|
+
# @return [#identifier] an object
|
33
|
+
#
|
34
|
+
def self.store!(uploader, file)
|
35
|
+
self.new
|
36
|
+
end
|
37
|
+
|
38
|
+
# Do something to retrieve the file
|
39
|
+
#
|
40
|
+
# @param [CarrierWave::Uploader] uploader an uploader object
|
41
|
+
# @param [String] identifier uniquely identifies the file
|
42
|
+
#
|
43
|
+
# @return [#identifier] an object
|
44
|
+
#
|
45
|
+
def self.retrieve!(uploader, identifier)
|
46
|
+
self.new
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Should return a String that uniquely identifies this file and can be used to retrieve it from
|
51
|
+
# the same storage engine later on.
|
52
|
+
#
|
53
|
+
# This is OPTIONAL
|
54
|
+
#
|
55
|
+
# @return [String] path to the file
|
56
|
+
#
|
57
|
+
def identifier; end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Should return the url where the file is publically accessible. If this is not set, then
|
61
|
+
# it is assumed that the url is the path relative to the public directory.
|
62
|
+
#
|
63
|
+
# This is OPTIONAL
|
64
|
+
#
|
65
|
+
# @return [String] file's url
|
66
|
+
#
|
67
|
+
def url; end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Should return the path where the file is corrently located. This is OPTIONAL.
|
71
|
+
#
|
72
|
+
# This is OPTIONAL
|
73
|
+
#
|
74
|
+
# @return [String] path to the file
|
75
|
+
#
|
76
|
+
def path; end
|
77
|
+
|
78
|
+
end # Abstract
|
79
|
+
end # Storage
|
80
|
+
end # CarrierWave
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Storage
|
3
|
+
class File < Abstract
|
4
|
+
|
5
|
+
def initialize(uploader)
|
6
|
+
@uploader = uploader
|
7
|
+
end
|
8
|
+
|
9
|
+
##
|
10
|
+
# Move the file to the uploader's store path.
|
11
|
+
#
|
12
|
+
# @param [CarrierWave::Uploader] uploader an uploader object
|
13
|
+
# @param [CarrierWave::SanitizedFile] file the file to store
|
14
|
+
#
|
15
|
+
# @return [CarrierWave::SanitizedFile] a sanitized file
|
16
|
+
#
|
17
|
+
def self.store!(uploader, file)
|
18
|
+
path = ::File.join(uploader.store_dir, uploader.filename)
|
19
|
+
path = ::File.expand_path(path, uploader.root)
|
20
|
+
file.move_to(path)
|
21
|
+
file
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Retrieve the file from its store path
|
26
|
+
#
|
27
|
+
# @param [CarrierWave::Uploader] uploader an uploader object
|
28
|
+
# @param [String] identifier the filename of the file
|
29
|
+
#
|
30
|
+
# @return [CarrierWave::SanitizedFile] a sanitized file
|
31
|
+
#
|
32
|
+
def self.retrieve!(uploader, identifier)
|
33
|
+
path = ::File.join(uploader.store_dir, identifier)
|
34
|
+
path = ::File.expand_path(path, uploader.root)
|
35
|
+
CarrierWave::SanitizedFile.new(path)
|
36
|
+
end
|
37
|
+
|
38
|
+
end # File
|
39
|
+
end # Storage
|
40
|
+
end # CarrierWave
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Storage
|
3
|
+
##
|
4
|
+
# Uploads things to Amazon S3 webservices
|
5
|
+
#
|
6
|
+
class S3 < Abstract
|
7
|
+
|
8
|
+
def initialize(bucket, store_dir, identifier)
|
9
|
+
@bucket = bucket
|
10
|
+
@store_dir = store_dir
|
11
|
+
@identifier = identifier
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Connect to Amazon S3
|
16
|
+
#
|
17
|
+
def self.setup!
|
18
|
+
require 'aws/s3'
|
19
|
+
AWS::S3::Base.establish_connection!(
|
20
|
+
:access_key_id => CarrierWave.config[:s3][:access_key_id],
|
21
|
+
:secret_access_key => CarrierWave.config[:s3][:secret_access_key]
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# @return [String] the bucket set in the config options
|
27
|
+
#
|
28
|
+
def self.bucket
|
29
|
+
CarrierWave.config[:s3][:bucket]
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# @return [Symbol] the access priviliges the uploaded files should have
|
34
|
+
#
|
35
|
+
def self.access
|
36
|
+
CarrierWave.config[:s3][:access]
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Store the file on S3
|
41
|
+
#
|
42
|
+
# @param [CarrierWave::Uploader] uploader an uploader object
|
43
|
+
# @param [CarrierWave::SanitizedFile] file the file to store
|
44
|
+
#
|
45
|
+
# @return [#identifier] an object
|
46
|
+
#
|
47
|
+
def self.store!(uploader, file)
|
48
|
+
AWS::S3::S3Object.store(::File.join(uploader.store_dir, uploader.filename), file.read, bucket, :access => access)
|
49
|
+
self.new(bucket, uploader.store_dir, uploader.filename)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Do something to retrieve the file
|
53
|
+
#
|
54
|
+
# @param [CarrierWave::Uploader] uploader an uploader object
|
55
|
+
# @param [String] identifier uniquely identifies the file
|
56
|
+
#
|
57
|
+
# @return [#identifier] an object
|
58
|
+
#
|
59
|
+
def self.retrieve!(uploader, identifier)
|
60
|
+
self.new(bucket, uploader.store_dir, identifier)
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Returns the filename on S3
|
65
|
+
#
|
66
|
+
# @return [String] path to the file
|
67
|
+
#
|
68
|
+
def identifier
|
69
|
+
@identifier
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns the url on Amazon's S3 service
|
74
|
+
#
|
75
|
+
# @return [String] file's url
|
76
|
+
#
|
77
|
+
def url
|
78
|
+
"http://s3.amazonaws.com/#{self.class.bucket}/#{@store_dir}/#{@identifier}"
|
79
|
+
end
|
80
|
+
|
81
|
+
end # S3
|
82
|
+
end # Storage
|
83
|
+
end # CarrierWave
|