carrierwave-rails3 0.4.5

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 (67) hide show
  1. data/README.rdoc +527 -0
  2. data/lib/carrierwave.rb +103 -0
  3. data/lib/carrierwave/compatibility/paperclip.rb +95 -0
  4. data/lib/carrierwave/core_ext/file.rb +11 -0
  5. data/lib/carrierwave/mount.rb +359 -0
  6. data/lib/carrierwave/orm/activerecord.rb +75 -0
  7. data/lib/carrierwave/orm/datamapper.rb +27 -0
  8. data/lib/carrierwave/orm/mongoid.rb +23 -0
  9. data/lib/carrierwave/orm/mongomapper.rb +27 -0
  10. data/lib/carrierwave/orm/sequel.rb +45 -0
  11. data/lib/carrierwave/processing/image_science.rb +116 -0
  12. data/lib/carrierwave/processing/mini_magick.rb +261 -0
  13. data/lib/carrierwave/processing/rmagick.rb +278 -0
  14. data/lib/carrierwave/sanitized_file.rb +273 -0
  15. data/lib/carrierwave/storage/abstract.rb +30 -0
  16. data/lib/carrierwave/storage/cloud_files.rb +169 -0
  17. data/lib/carrierwave/storage/file.rb +48 -0
  18. data/lib/carrierwave/storage/grid_fs.rb +104 -0
  19. data/lib/carrierwave/storage/right_s3.rb +3 -0
  20. data/lib/carrierwave/storage/s3.rb +206 -0
  21. data/lib/carrierwave/test/matchers.rb +164 -0
  22. data/lib/carrierwave/uploader.rb +44 -0
  23. data/lib/carrierwave/uploader/cache.rb +146 -0
  24. data/lib/carrierwave/uploader/callbacks.rb +41 -0
  25. data/lib/carrierwave/uploader/configuration.rb +134 -0
  26. data/lib/carrierwave/uploader/default_url.rb +19 -0
  27. data/lib/carrierwave/uploader/download.rb +60 -0
  28. data/lib/carrierwave/uploader/extension_whitelist.rb +38 -0
  29. data/lib/carrierwave/uploader/mountable.rb +39 -0
  30. data/lib/carrierwave/uploader/processing.rb +84 -0
  31. data/lib/carrierwave/uploader/proxy.rb +62 -0
  32. data/lib/carrierwave/uploader/remove.rb +23 -0
  33. data/lib/carrierwave/uploader/store.rb +90 -0
  34. data/lib/carrierwave/uploader/url.rb +33 -0
  35. data/lib/carrierwave/uploader/versions.rb +147 -0
  36. data/lib/generators/templates/uploader.rb +47 -0
  37. data/lib/generators/uploader_generator.rb +13 -0
  38. data/spec/compatibility/paperclip_spec.rb +52 -0
  39. data/spec/mount_spec.rb +538 -0
  40. data/spec/orm/activerecord_spec.rb +271 -0
  41. data/spec/orm/datamapper_spec.rb +168 -0
  42. data/spec/orm/mongoid_spec.rb +202 -0
  43. data/spec/orm/mongomapper_spec.rb +202 -0
  44. data/spec/orm/sequel_spec.rb +183 -0
  45. data/spec/processing/image_science_spec.rb +56 -0
  46. data/spec/processing/mini_magick_spec.rb +76 -0
  47. data/spec/processing/rmagick_spec.rb +75 -0
  48. data/spec/sanitized_file_spec.rb +623 -0
  49. data/spec/spec_helper.rb +92 -0
  50. data/spec/storage/cloudfiles_spec.rb +78 -0
  51. data/spec/storage/grid_fs_spec.rb +86 -0
  52. data/spec/storage/s3_spec.rb +118 -0
  53. data/spec/uploader/cache_spec.rb +209 -0
  54. data/spec/uploader/callback_spec.rb +24 -0
  55. data/spec/uploader/configuration_spec.rb +105 -0
  56. data/spec/uploader/default_url_spec.rb +85 -0
  57. data/spec/uploader/download_spec.rb +75 -0
  58. data/spec/uploader/extension_whitelist_spec.rb +44 -0
  59. data/spec/uploader/mountable_spec.rb +33 -0
  60. data/spec/uploader/paths_spec.rb +22 -0
  61. data/spec/uploader/processing_spec.rb +73 -0
  62. data/spec/uploader/proxy_spec.rb +54 -0
  63. data/spec/uploader/remove_spec.rb +70 -0
  64. data/spec/uploader/store_spec.rb +264 -0
  65. data/spec/uploader/url_spec.rb +102 -0
  66. data/spec/uploader/versions_spec.rb +298 -0
  67. metadata +128 -0
@@ -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,169 @@
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
11
+ #
12
+ # CarrierWave.configure do |config|
13
+ # config.cloud_files_username = "xxxxxx"
14
+ # config.cloud_files_api_key = "xxxxxx"
15
+ # config.cloud_files_container = "my_container"
16
+ # end
17
+ #
18
+ #
19
+ # You can set the access policy for the uploaded files:
20
+ #
21
+ # CarrierWave.configure do |config|
22
+ # config.s3_access_policy = 'public-read'
23
+ # end
24
+ #
25
+ #
26
+ class CloudFiles < Abstract
27
+
28
+ class File
29
+
30
+ def initialize(uploader, base, path)
31
+ @uploader = uploader
32
+ @path = path
33
+ @base = base
34
+ end
35
+
36
+ ##
37
+ # Returns the current path/filename of the file on Cloud Files.
38
+ #
39
+ # === Returns
40
+ #
41
+ # [String] A path
42
+ #
43
+ def path
44
+ @path
45
+ end
46
+
47
+ ##
48
+ # Reads the contents of the file from Cloud Files
49
+ #
50
+ # === Returns
51
+ #
52
+ # [String] contents of the file
53
+ #
54
+ def read
55
+ object = cf_container.object(@path)
56
+ @content_type = object.content_type
57
+ object.data
58
+ end
59
+
60
+ ##
61
+ # Remove the file from Cloud Files
62
+ #
63
+ def delete
64
+ cf_container.delete_object(@path)
65
+ end
66
+
67
+ ##
68
+ # Returns the url on the Cloud Files CDN. Note that the parent container must be marked as
69
+ # public for this to work.
70
+ #
71
+ # === Returns
72
+ #
73
+ # [String] file's url
74
+ #
75
+ def url
76
+ cf_container.object(@path).public_url
77
+ end
78
+
79
+ #def metadata
80
+ # s3_object.metadata
81
+ #end
82
+
83
+ def content_type
84
+ cf_container.object(@path).content_type
85
+ end
86
+
87
+ def content_type=(new_content_type)
88
+ headers["content-type"] = new_content_type
89
+ end
90
+
91
+ ##
92
+ # Writes the supplied data into the object on Cloud Files.
93
+ #
94
+ # === Returns
95
+ #
96
+ # boolean
97
+ #
98
+ def store(data,headers={})
99
+ object = cf_container.create_object(@path)
100
+ object.write(data,headers)
101
+ end
102
+
103
+ private
104
+
105
+ def headers
106
+ @headers ||= { }
107
+ end
108
+
109
+ def container
110
+ @uploader.cloud_files_container
111
+ end
112
+
113
+ def connection
114
+ @base.connection
115
+ end
116
+
117
+ def cf_connection
118
+ @cf_connection ||= ::CloudFiles::Connection.new(@uploader.cloud_files_username, @uploader.cloud_files_api_key)
119
+ end
120
+
121
+ def cf_container
122
+ if @cf_container
123
+ @cf_container
124
+ else
125
+ @cf_container = cf_connection.create_container(container)
126
+ @cf_container.make_public
127
+ @cf_container
128
+ end
129
+ end
130
+
131
+
132
+ end
133
+
134
+ ##
135
+ # Store the file on Cloud Files
136
+ #
137
+ # === Parameters
138
+ #
139
+ # [file (CarrierWave::SanitizedFile)] the file to store
140
+ #
141
+ # === Returns
142
+ #
143
+ # [CarrierWave::Storage::RightS3::File] the stored file
144
+ #
145
+ def store!(file)
146
+ cloud_files_options = {'Content-Type' => file.content_type}
147
+ f = CarrierWave::Storage::CloudFiles::File.new(uploader, self, uploader.store_path)
148
+ f.store(file.read,cloud_files_options)
149
+ f
150
+ end
151
+
152
+ # Do something to retrieve the file
153
+ #
154
+ # @param [String] identifier uniquely identifies the file
155
+ #
156
+ # [identifier (String)] uniquely identifies the file
157
+ #
158
+ # === Returns
159
+ #
160
+ # [CarrierWave::Storage::RightS3::File] the stored file
161
+ #
162
+ def retrieve!(identifier)
163
+ CarrierWave::Storage::CloudFiles::File.new(uploader, self, uploader.store_path(identifier))
164
+ end
165
+
166
+
167
+ end # CloudFiles
168
+ end # Storage
169
+ end # CarrierWave
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+ module Storage
5
+
6
+ ##
7
+ # File storage stores file to the Filesystem (surprising, no?). There's really not much
8
+ # to it, it uses the store_dir defined on the uploader as the storage location. That's
9
+ # pretty much it.
10
+ #
11
+ class File < Abstract
12
+
13
+ ##
14
+ # Move the file to the uploader's store path.
15
+ #
16
+ # === Parameters
17
+ #
18
+ # [file (CarrierWave::SanitizedFile)] the file to store
19
+ #
20
+ # === Returns
21
+ #
22
+ # [CarrierWave::SanitizedFile] a sanitized file
23
+ #
24
+ def store!(file)
25
+ path = ::File.expand_path(uploader.store_path, uploader.root)
26
+ file.move_to(path, uploader.permissions)
27
+ file
28
+ end
29
+
30
+ ##
31
+ # Retrieve the file from its store path
32
+ #
33
+ # === Parameters
34
+ #
35
+ # [identifier (String)] the filename of the file
36
+ #
37
+ # === Returns
38
+ #
39
+ # [CarrierWave::SanitizedFile] a sanitized file
40
+ #
41
+ def retrieve!(identifier)
42
+ path = ::File.expand_path(uploader.store_path(identifier), uploader.root)
43
+ CarrierWave::SanitizedFile.new(path)
44
+ end
45
+
46
+ end # File
47
+ end # Storage
48
+ end # CarrierWave
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+ require 'mongo'
3
+
4
+ module CarrierWave
5
+ module Storage
6
+
7
+ ##
8
+ # The GridFS store uses MongoDB's GridStore file storage system to store files
9
+ #
10
+ class GridFS < Abstract
11
+
12
+ class File
13
+
14
+ def initialize(uploader, path)
15
+ @path = path
16
+ @uploader = uploader
17
+ end
18
+
19
+ def path
20
+ nil
21
+ end
22
+
23
+ def url
24
+ unless @uploader.grid_fs_access_url
25
+ nil
26
+ else
27
+ [@uploader.grid_fs_access_url, @path].join("/")
28
+ end
29
+ end
30
+
31
+ def read
32
+ grid.open(@path, 'r').data
33
+ end
34
+
35
+ def write(file)
36
+ grid.open(@uploader.store_path, 'w', :content_type => file.content_type) do |f|
37
+ f.write(file.read)
38
+ end
39
+ end
40
+
41
+ def delete
42
+ grid.delete(@path)
43
+ end
44
+
45
+ def content_type
46
+ grid.open(@path, 'r').content_type
47
+ end
48
+
49
+ protected
50
+
51
+ def database
52
+ @connection ||= begin
53
+ host = @uploader.grid_fs_host
54
+ port = @uploader.grid_fs_port
55
+ database = @uploader.grid_fs_database
56
+ username = @uploader.grid_fs_username
57
+ password = @uploader.grid_fs_password
58
+ db = Mongo::Connection.new(host, port).db(database)
59
+ db.authenticate(username, password) if username && password
60
+ db
61
+ end
62
+ end
63
+
64
+ def grid
65
+ @grid ||= Mongo::GridFileSystem.new(database)
66
+ end
67
+
68
+ end
69
+
70
+ ##
71
+ # Store the file in MongoDB's GridFS GridStore
72
+ #
73
+ # === Parameters
74
+ #
75
+ # [file (CarrierWave::SanitizedFile)] the file to store
76
+ #
77
+ # === Returns
78
+ #
79
+ # [CarrierWave::SanitizedFile] a sanitized file
80
+ #
81
+ def store!(file)
82
+ stored = CarrierWave::Storage::GridFS::File.new(uploader, uploader.store_path)
83
+ stored.write(file)
84
+ stored
85
+ end
86
+
87
+ ##
88
+ # Retrieve the file from MongoDB's GridFS GridStore
89
+ #
90
+ # === Parameters
91
+ #
92
+ # [identifier (String)] the filename of the file
93
+ #
94
+ # === Returns
95
+ #
96
+ # [CarrierWave::Storage::GridFS::File] a sanitized file
97
+ #
98
+ def retrieve!(identifier)
99
+ CarrierWave::Storage::GridFS::File.new(uploader, uploader.store_path(identifier))
100
+ end
101
+
102
+ end # File
103
+ end # Storage
104
+ end # CarrierWave
@@ -0,0 +1,3 @@
1
+
2
+ raise "The right_aws library is no longer supported. Please install the updated 'aws' library with support for Ruby 1.9 and euro buckets"
3
+
@@ -0,0 +1,206 @@
1
+ # encoding: utf-8
2
+ begin
3
+ require 'aws'
4
+ rescue LoadError
5
+ raise "You don't have the 'aws' gem installed. 'aws-s3' and 'right_aws' are no longer supported."
6
+ end
7
+
8
+ module CarrierWave
9
+ module Storage
10
+
11
+ ##
12
+ # Uploads things to Amazon S3 webservices using the RightAWS libraries (right_aws gem).
13
+ # In order for CarrierWave to connect to Amazon S3, you'll need to specify an access key id, secret key
14
+ # and bucket
15
+ #
16
+ # CarrierWave.configure do |config|
17
+ # config.s3_access_key_id = "xxxxxx"
18
+ # config.s3_secret_access_key = "xxxxxx"
19
+ # config.s3_bucket = "my_bucket_name"
20
+ # end
21
+ #
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
+ # You can set the access policy for the uploaded files:
26
+ #
27
+ # CarrierWave.configure do |config|
28
+ # config.s3_access_policy = 'public-read'
29
+ # end
30
+ #
31
+ # The default is 'public-read'. For more options see:
32
+ #
33
+ # http://docs.amazonwebservices.com/AmazonS3/latest/RESTAccessPolicy.html#RESTCannedAccessPolicies
34
+ #
35
+ # For backwards compatability with the original aws-s3 library, if the old +config.s3_access+ is set it
36
+ # will be converted to the appropriate access policy:
37
+ #
38
+ # [:private] No one else has any access rights.
39
+ # [:public_read] The anonymous principal is granted READ access.
40
+ # If this policy is used on an object, it can be read from a
41
+ # browser with no authentication.
42
+ # [:public_read_write] The anonymous principal is granted READ and WRITE access.
43
+ # [:authenticated_read] Any principal authenticated as a registered Amazon S3 user
44
+ # is granted READ access.
45
+ #
46
+ # You can change the generated url to a cnamed domain by setting the cnamed config:
47
+ #
48
+ # CarrierWave.configure do |config|
49
+ # config.s3_cnamed = true
50
+ # config.s3_bucket = 'bucketname.domain.tld'
51
+ # end
52
+ #
53
+ # Now the resulting url will be
54
+ #
55
+ # http://bucketname.domain.tld/path/to/file
56
+ #
57
+ # instead of
58
+ #
59
+ # http://bucketname.domain.tld.s3.amazonaws.com/path/to/file
60
+ #
61
+ class S3 < Abstract
62
+
63
+ class File
64
+
65
+ def initialize(uploader, base, path)
66
+ @uploader = uploader
67
+ @path = path
68
+ @base = base
69
+ end
70
+
71
+ ##
72
+ # Returns the current path of the file on S3
73
+ #
74
+ # === Returns
75
+ #
76
+ # [String] A path
77
+ #
78
+ def path
79
+ @path
80
+ end
81
+
82
+ ##
83
+ # Reads the contents of the file from S3
84
+ #
85
+ # === Returns
86
+ #
87
+ # [String] contents of the file
88
+ #
89
+ def read
90
+ result = connection.get(bucket, @path)
91
+ @headers = result[:headers]
92
+ result[:object]
93
+ end
94
+
95
+ ##
96
+ # Remove the file from Amazon S3
97
+ #
98
+ def delete
99
+ connection.delete(bucket, @path)
100
+ end
101
+
102
+ ##
103
+ # Returns the url on Amazon's S3 service
104
+ #
105
+ # === Returns
106
+ #
107
+ # [String] file's url
108
+ #
109
+ def url
110
+ if @uploader.s3_cnamed
111
+ ["http://#{@uploader.s3_bucket}", @path].compact.join('/')
112
+ else
113
+ ["http://#{@uploader.s3_bucket}.s3.amazonaws.com", @path].compact.join('/')
114
+ end
115
+ end
116
+
117
+ def store(file)
118
+ content_type ||= file.content_type # this might cause problems if content type changes between read and upload (unlikely)
119
+ connection.put(bucket, @path, file.read,
120
+ {
121
+ 'x-amz-acl' => access_policy,
122
+ 'content-type' => content_type
123
+ }.merge(@uploader.s3_headers)
124
+ )
125
+ end
126
+
127
+ # The Amazon S3 Access policy ready to send in storage request headers.
128
+ def access_policy
129
+ return @access_policy unless @access_policy.blank?
130
+ if @uploader.s3_access_policy.blank?
131
+ if !@uploader.s3_access.blank?
132
+ @access_policy = @uploader.s3_access.to_s.gsub(/_/, '-')
133
+ else
134
+ @access_policy = 'public-read'
135
+ end
136
+ else
137
+ @access_policy = @uploader.s3_access_policy
138
+ end
139
+ end
140
+
141
+ def content_type
142
+ headers["content-type"]
143
+ end
144
+
145
+ def content_type=(type)
146
+ headers["content-type"] = type
147
+ end
148
+
149
+ # Headers returned from file retrieval
150
+ def headers
151
+ @headers ||= {}
152
+ end
153
+
154
+ private
155
+
156
+ def bucket
157
+ @uploader.s3_bucket
158
+ end
159
+
160
+ def connection
161
+ @base.connection
162
+ end
163
+
164
+ end
165
+
166
+ ##
167
+ # Store the file on S3
168
+ #
169
+ # === Parameters
170
+ #
171
+ # [file (CarrierWave::SanitizedFile)] the file to store
172
+ #
173
+ # === Returns
174
+ #
175
+ # [CarrierWave::Storage::RightS3::File] the stored file
176
+ #
177
+ def store!(file)
178
+ f = CarrierWave::Storage::S3::File.new(uploader, self, uploader.store_path)
179
+ f.store(file)
180
+ f
181
+ end
182
+
183
+ # Do something to retrieve the file
184
+ #
185
+ # @param [String] identifier uniquely identifies the file
186
+ #
187
+ # [identifier (String)] uniquely identifies the file
188
+ #
189
+ # === Returns
190
+ #
191
+ # [CarrierWave::Storage::RightS3::File] the stored file
192
+ #
193
+ def retrieve!(identifier)
194
+ CarrierWave::Storage::S3::File.new(uploader, self, uploader.store_path(identifier))
195
+ end
196
+
197
+ def connection
198
+ @connection ||= Aws::S3Interface.new(
199
+ uploader.s3_access_key_id, uploader.s3_secret_access_key,
200
+ :multi_thread => uploader.s3_multi_thread
201
+ )
202
+ end
203
+
204
+ end # S3
205
+ end # Storage
206
+ end # CarrierWave