carrierwave-pressplane 0.5.8.3

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.
Files changed (36) hide show
  1. data/README.md +748 -0
  2. data/lib/carrierwave.rb +116 -0
  3. data/lib/carrierwave/compatibility/paperclip.rb +95 -0
  4. data/lib/carrierwave/locale/en.yml +9 -0
  5. data/lib/carrierwave/mount.rb +382 -0
  6. data/lib/carrierwave/orm/activerecord.rb +46 -0
  7. data/lib/carrierwave/processing/mime_types.rb +58 -0
  8. data/lib/carrierwave/processing/mini_magick.rb +252 -0
  9. data/lib/carrierwave/processing/rmagick.rb +279 -0
  10. data/lib/carrierwave/sanitized_file.rb +315 -0
  11. data/lib/carrierwave/storage/abstract.rb +30 -0
  12. data/lib/carrierwave/storage/cloud_files.rb +188 -0
  13. data/lib/carrierwave/storage/file.rb +56 -0
  14. data/lib/carrierwave/storage/fog.rb +333 -0
  15. data/lib/carrierwave/storage/right_s3.rb +1 -0
  16. data/lib/carrierwave/storage/s3.rb +240 -0
  17. data/lib/carrierwave/test/matchers.rb +241 -0
  18. data/lib/carrierwave/uploader.rb +44 -0
  19. data/lib/carrierwave/uploader/cache.rb +178 -0
  20. data/lib/carrierwave/uploader/callbacks.rb +35 -0
  21. data/lib/carrierwave/uploader/configuration.rb +168 -0
  22. data/lib/carrierwave/uploader/default_url.rb +19 -0
  23. data/lib/carrierwave/uploader/download.rb +75 -0
  24. data/lib/carrierwave/uploader/extension_whitelist.rb +49 -0
  25. data/lib/carrierwave/uploader/mountable.rb +39 -0
  26. data/lib/carrierwave/uploader/processing.rb +90 -0
  27. data/lib/carrierwave/uploader/proxy.rb +77 -0
  28. data/lib/carrierwave/uploader/remove.rb +23 -0
  29. data/lib/carrierwave/uploader/store.rb +113 -0
  30. data/lib/carrierwave/uploader/url.rb +47 -0
  31. data/lib/carrierwave/uploader/versions.rb +237 -0
  32. data/lib/carrierwave/validations/active_model.rb +64 -0
  33. data/lib/carrierwave/version.rb +3 -0
  34. data/lib/generators/templates/uploader.rb +48 -0
  35. data/lib/generators/uploader_generator.rb +7 -0
  36. metadata +215 -0
@@ -0,0 +1,315 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pathname'
4
+ require 'active_support/core_ext/string/multibyte'
5
+
6
+ module CarrierWave
7
+
8
+ ##
9
+ # SanitizedFile is a base class which provides a common API around all
10
+ # the different quirky Ruby File libraries. It has support for Tempfile,
11
+ # File, StringIO, Merb-style upload Hashes, as well as paths given as
12
+ # Strings and Pathnames.
13
+ #
14
+ # It's probably needlessly comprehensive and complex. Help is appreciated.
15
+ #
16
+ class SanitizedFile
17
+
18
+ attr_accessor :file
19
+
20
+ class << self
21
+ attr_writer :sanitize_regexp
22
+
23
+ def sanitize_regexp
24
+ @sanitize_regexp ||= /[^a-zA-Z0-9\.\-\+_]/
25
+ end
26
+ end
27
+
28
+ def initialize(file)
29
+ self.file = file
30
+ end
31
+
32
+ ##
33
+ # Returns the filename as is, without sanizting it.
34
+ #
35
+ # === Returns
36
+ #
37
+ # [String] the unsanitized filename
38
+ #
39
+ def original_filename
40
+ return @original_filename if @original_filename
41
+ if @file and @file.respond_to?(:original_filename)
42
+ @file.original_filename
43
+ elsif path
44
+ File.basename(path)
45
+ end
46
+ end
47
+
48
+ ##
49
+ # Returns the filename, sanitized to strip out any evil characters.
50
+ #
51
+ # === Returns
52
+ #
53
+ # [String] the sanitized filename
54
+ #
55
+ def filename
56
+ sanitize(original_filename) if original_filename
57
+ end
58
+
59
+ alias_method :identifier, :filename
60
+
61
+ ##
62
+ # Returns the part of the filename before the extension. So if a file is called 'test.jpeg'
63
+ # this would return 'test'
64
+ #
65
+ # === Returns
66
+ #
67
+ # [String] the first part of the filename
68
+ #
69
+ def basename
70
+ split_extension(filename)[0] if filename
71
+ end
72
+
73
+ ##
74
+ # Returns the file extension
75
+ #
76
+ # === Returns
77
+ #
78
+ # [String] the extension
79
+ #
80
+ def extension
81
+ split_extension(filename)[1] if filename
82
+ end
83
+
84
+ ##
85
+ # Returns the file's size.
86
+ #
87
+ # === Returns
88
+ #
89
+ # [Integer] the file's size in bytes.
90
+ #
91
+ def size
92
+ if is_path?
93
+ exists? ? File.size(path) : 0
94
+ elsif @file.respond_to?(:size)
95
+ @file.size
96
+ elsif path
97
+ exists? ? File.size(path) : 0
98
+ else
99
+ 0
100
+ end
101
+ end
102
+
103
+ ##
104
+ # Returns the full path to the file. If the file has no path, it will return nil.
105
+ #
106
+ # === Returns
107
+ #
108
+ # [String, nil] the path where the file is located.
109
+ #
110
+ def path
111
+ unless @file.blank?
112
+ if is_path?
113
+ File.expand_path(@file)
114
+ elsif @file.respond_to?(:path) and not @file.path.blank?
115
+ File.expand_path(@file.path)
116
+ end
117
+ end
118
+ end
119
+
120
+ ##
121
+ # === Returns
122
+ #
123
+ # [Boolean] whether the file is supplied as a pathname or string.
124
+ #
125
+ def is_path?
126
+ !!((@file.is_a?(String) || @file.is_a?(Pathname)) && !@file.blank?)
127
+ end
128
+
129
+ ##
130
+ # === Returns
131
+ #
132
+ # [Boolean] whether the file is valid and has a non-zero size
133
+ #
134
+ def empty?
135
+ @file.nil? || self.size.nil? || self.size.zero?
136
+ end
137
+
138
+ ##
139
+ # === Returns
140
+ #
141
+ # [Boolean] Whether the file exists
142
+ #
143
+ def exists?
144
+ return File.exists?(self.path) if self.path
145
+ return false
146
+ end
147
+
148
+ ##
149
+ # Returns the contents of the file.
150
+ #
151
+ # === Returns
152
+ #
153
+ # [String] contents of the file
154
+ #
155
+ def read
156
+ if is_path?
157
+ File.open(@file, "rb") {|file| file.read}
158
+ else
159
+ @file.rewind if @file.respond_to?(:rewind)
160
+ @file.read
161
+ end
162
+ end
163
+
164
+ ##
165
+ # Moves the file to the given path
166
+ #
167
+ # === Parameters
168
+ #
169
+ # [new_path (String)] The path where the file should be moved.
170
+ # [permissions (Integer)] permissions to set on the file in its new location.
171
+ #
172
+ def move_to(new_path, permissions=nil)
173
+ return if self.empty?
174
+ new_path = File.expand_path(new_path)
175
+
176
+ mkdir!(new_path)
177
+ if exists?
178
+ FileUtils.mv(path, new_path) unless new_path == path
179
+ else
180
+ File.open(new_path, "wb") { |f| f.write(read) }
181
+ end
182
+ chmod!(new_path, permissions)
183
+ self.file = new_path
184
+ self
185
+ end
186
+
187
+ ##
188
+ # Creates a copy of this file and moves it to the given path. Returns the copy.
189
+ #
190
+ # === Parameters
191
+ #
192
+ # [new_path (String)] The path where the file should be copied to.
193
+ # [permissions (Integer)] permissions to set on the copy
194
+ #
195
+ # === Returns
196
+ #
197
+ # @return [CarrierWave::SanitizedFile] the location where the file will be stored.
198
+ #
199
+ def copy_to(new_path, permissions=nil)
200
+ return if self.empty?
201
+ new_path = File.expand_path(new_path)
202
+
203
+ mkdir!(new_path)
204
+ if exists?
205
+ FileUtils.cp(path, new_path) unless new_path == path
206
+ else
207
+ File.open(new_path, "wb") { |f| f.write(read) }
208
+ end
209
+ chmod!(new_path, permissions)
210
+ self.class.new({:tempfile => new_path, :content_type => content_type})
211
+ end
212
+
213
+ ##
214
+ # Removes the file from the filesystem.
215
+ #
216
+ def delete
217
+ FileUtils.rm(self.path) if exists?
218
+ end
219
+
220
+ ##
221
+ # Returns a File object, or nil if it does not exist.
222
+ #
223
+ # === Returns
224
+ #
225
+ # [File] a File object representing the SanitizedFile
226
+ #
227
+ def to_file
228
+ return @file if @file.is_a?(File)
229
+ File.open(path) if exists?
230
+ end
231
+
232
+ ##
233
+ # Returns the content type of the file.
234
+ #
235
+ # === Returns
236
+ #
237
+ # [String] the content type of the file
238
+ #
239
+ def content_type
240
+ return @content_type if @content_type
241
+ @file.content_type.chomp if @file.respond_to?(:content_type) and @file.content_type
242
+ end
243
+
244
+ ##
245
+ # Sets the content type of the file.
246
+ #
247
+ # === Returns
248
+ #
249
+ # [String] the content type of the file
250
+ #
251
+ def content_type=(type)
252
+ @content_type = type
253
+ end
254
+
255
+ ##
256
+ # Used to sanitize the file name. Public to allow overriding for non-latin characters.
257
+ #
258
+ # === Returns
259
+ #
260
+ # [Regexp] the regexp for sanitizing the file name
261
+ #
262
+ def sanitize_regexp
263
+ CarrierWave::SanitizedFile.sanitize_regexp
264
+ end
265
+
266
+ private
267
+
268
+ def file=(file)
269
+ if file.is_a?(Hash)
270
+ @file = file["tempfile"] || file[:tempfile]
271
+ @original_filename = file["filename"] || file[:filename]
272
+ @content_type = file["content_type"] || file[:content_type]
273
+ else
274
+ @file = file
275
+ @original_filename = nil
276
+ @content_type = nil
277
+ end
278
+ end
279
+
280
+ # create the directory if it doesn't exist
281
+ def mkdir!(path)
282
+ FileUtils.mkdir_p(File.dirname(path)) unless File.exists?(File.dirname(path))
283
+ end
284
+
285
+ def chmod!(path, permissions)
286
+ File.chmod(permissions, path) if permissions
287
+ end
288
+
289
+ # Sanitize the filename, to prevent hacking
290
+ def sanitize(name)
291
+ name = name.gsub("\\", "/") # work-around for IE
292
+ name = File.basename(name)
293
+ name = name.gsub(sanitize_regexp,"_")
294
+ name = "_#{name}" if name =~ /\A\.+\z/
295
+ name = "unnamed" if name.size == 0
296
+ return name.mb_chars.to_s
297
+ end
298
+
299
+ def split_extension(filename)
300
+ # regular expressions to try for identifying extensions
301
+ extension_matchers = [
302
+ /\A(.+)\.(tar\.gz)\z/, # matches "something.tar.gz"
303
+ /\A(.+)\.([^\.]+)\z/ # matches "something.jpg"
304
+ ]
305
+
306
+ extension_matchers.each do |regexp|
307
+ if filename =~ regexp
308
+ return $1, $2
309
+ end
310
+ end
311
+ return filename, "" # In case we weren't able to split the extension
312
+ end
313
+
314
+ end # SanitizedFile
315
+ end # CarrierWave
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+ module Storage
5
+
6
+ ##
7
+ # This file serves mostly as a specification for Storage engines. There is no requirement
8
+ # that storage engines must be a subclass of this class.
9
+ #
10
+ class Abstract
11
+
12
+ attr_reader :uploader
13
+
14
+ def initialize(uploader)
15
+ @uploader = uploader
16
+ end
17
+
18
+ def identifier
19
+ uploader.filename
20
+ end
21
+
22
+ def store!(file)
23
+ end
24
+
25
+ def retrieve!(identifier)
26
+ end
27
+
28
+ end # Abstract
29
+ end # Storage
30
+ end # CarrierWave
@@ -0,0 +1,188 @@
1
+ # encoding: utf-8
2
+ require 'cloudfiles'
3
+
4
+ module CarrierWave
5
+ module Storage
6
+
7
+ ##
8
+ # Uploads things to Rackspace Cloud Files webservices using the Rackspace libraries (cloudfiles gem).
9
+ # In order for CarrierWave to connect to Cloud Files, you'll need to specify an username, api key
10
+ # and container. Optional arguments are config.cloud_files_snet (using the private internal
11
+ # Rackspace network for communication) and config.cloud_files_auth_url (for connecting to Rackspace's
12
+ # UK infrastructure or an OpenStack Swift installation)
13
+ #
14
+ # CarrierWave.configure do |config|
15
+ # config.cloud_files_username = "xxxxxx"
16
+ # config.cloud_files_api_key = "xxxxxx"
17
+ # config.cloud_files_container = "my_container"
18
+ # config.cloud_files_auth_url = "https://lon.auth.api.rackspacecloud.com/v1.0"
19
+ # config.cloud_files_snet = true
20
+ # end
21
+ #
22
+ # You can optionally include your CDN host name in the configuration.
23
+ # This is *highly* recommended, as without it every request requires a lookup
24
+ # of this information.
25
+ #
26
+ # config.cloud_files_cdn_host = "c000000.cdn.rackspacecloud.com"
27
+ #
28
+ #
29
+ class CloudFiles < Abstract
30
+
31
+ class File
32
+
33
+ def initialize(uploader, base, path)
34
+ @uploader = uploader
35
+ @path = path
36
+ @base = base
37
+ end
38
+
39
+ ##
40
+ # Returns the current path/filename of the file on Cloud Files.
41
+ #
42
+ # === Returns
43
+ #
44
+ # [String] A path
45
+ #
46
+ def path
47
+ @path
48
+ end
49
+
50
+ ##
51
+ # Reads the contents of the file from Cloud Files
52
+ #
53
+ # === Returns
54
+ #
55
+ # [String] contents of the file
56
+ #
57
+ def read
58
+ object = cf_container.object(@path)
59
+ @content_type = object.content_type
60
+ object.data
61
+ end
62
+
63
+ ##
64
+ # Remove the file from Cloud Files
65
+ #
66
+ def delete
67
+ begin
68
+ cf_container.delete_object(@path)
69
+ rescue ::CloudFiles::Exception::NoSuchObject
70
+ # If the file's not there, don't panic
71
+ nil
72
+ end
73
+ end
74
+
75
+ ##
76
+ # Returns the url on the Cloud Files CDN. Note that the parent container must be marked as
77
+ # public for this to work.
78
+ #
79
+ # === Returns
80
+ #
81
+ # [String] file's url
82
+ #
83
+ def url
84
+ if @uploader.cloud_files_cdn_host
85
+ "http://" + @uploader.cloud_files_cdn_host + "/" + @path
86
+ else
87
+ begin
88
+ cf_container.object(@path).public_url
89
+ rescue ::CloudFiles::Exception::NoSuchObject
90
+ nil
91
+ end
92
+ end
93
+ end
94
+
95
+ def content_type
96
+ cf_container.object(@path).content_type
97
+ end
98
+
99
+ def content_type=(new_content_type)
100
+ headers["content-type"] = new_content_type
101
+ end
102
+
103
+ ##
104
+ # Writes the supplied data into the object on Cloud Files.
105
+ #
106
+ # === Returns
107
+ #
108
+ # boolean
109
+ #
110
+ def store(data,headers={})
111
+ object = cf_container.create_object(@path)
112
+ object.write(data,headers)
113
+ end
114
+
115
+ private
116
+
117
+ def headers
118
+ @headers ||= { }
119
+ end
120
+
121
+ def container
122
+ @uploader.cloud_files_container
123
+ end
124
+
125
+ def connection
126
+ @base.connection
127
+ end
128
+
129
+ def cf_connection
130
+ config = {:username => @uploader.cloud_files_username, :api_key => @uploader.cloud_files_api_key}
131
+ config[:auth_url] = @uploader.cloud_files_auth_url if @uploader.respond_to?(:cloud_files_auth_url)
132
+ config[:snet] = @uploader.cloud_files_snet if @uploader.respond_to?(:cloud_files_snet)
133
+ @cf_connection ||= ::CloudFiles::Connection.new(config)
134
+ end
135
+
136
+ def cf_container
137
+ if @cf_container
138
+ @cf_container
139
+ else
140
+ begin
141
+ @cf_container = cf_connection.container(container)
142
+ rescue NoSuchContainerException
143
+ @cf_container = cf_connection.create_container(container)
144
+ @cf_container.make_public
145
+ end
146
+ @cf_container
147
+ end
148
+ end
149
+
150
+
151
+ end
152
+
153
+ ##
154
+ # Store the file on Cloud Files
155
+ #
156
+ # === Parameters
157
+ #
158
+ # [file (CarrierWave::SanitizedFile)] the file to store
159
+ #
160
+ # === Returns
161
+ #
162
+ # [CarrierWave::Storage::CloudFiles::File] the stored file
163
+ #
164
+ def store!(file)
165
+ cloud_files_options = {'Content-Type' => file.content_type}
166
+ f = CarrierWave::Storage::CloudFiles::File.new(uploader, self, uploader.store_path)
167
+ f.store(file.read,cloud_files_options)
168
+ f
169
+ end
170
+
171
+ # Do something to retrieve the file
172
+ #
173
+ # @param [String] identifier uniquely identifies the file
174
+ #
175
+ # [identifier (String)] uniquely identifies the file
176
+ #
177
+ # === Returns
178
+ #
179
+ # [CarrierWave::Storage::CloudFiles::File] the stored file
180
+ #
181
+ def retrieve!(identifier)
182
+ CarrierWave::Storage::CloudFiles::File.new(uploader, self, uploader.store_path(identifier))
183
+ end
184
+
185
+
186
+ end # CloudFiles
187
+ end # Storage
188
+ end # CarrierWave