durran-carrierwave 0.3.2.3 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/Generators +1 -1
  2. data/History.txt +39 -2
  3. data/Manifest.txt +19 -5
  4. data/README.rdoc +180 -55
  5. data/Rakefile +11 -4
  6. data/features/grid_fs_storage.feature +32 -0
  7. data/features/step_definitions/general_steps.rb +6 -1
  8. data/features/support/activerecord.rb +1 -1
  9. data/features/support/env.rb +3 -16
  10. data/lib/carrierwave.rb +19 -74
  11. data/lib/carrierwave/compatibility/paperclip.rb +2 -2
  12. data/lib/carrierwave/core_ext/inheritable_attributes.rb +3 -3
  13. data/lib/carrierwave/mount.rb +36 -27
  14. data/lib/carrierwave/orm/activerecord.rb +3 -3
  15. data/lib/carrierwave/orm/datamapper.rb +2 -2
  16. data/lib/carrierwave/orm/mongoid.rb +23 -0
  17. data/lib/carrierwave/orm/mongomapper.rb +1 -1
  18. data/lib/carrierwave/orm/sequel.rb +4 -16
  19. data/lib/carrierwave/processing/image_science.rb +54 -25
  20. data/lib/carrierwave/processing/mini_magick.rb +269 -0
  21. data/lib/carrierwave/processing/rmagick.rb +4 -6
  22. data/lib/carrierwave/sanitized_file.rb +7 -6
  23. data/lib/carrierwave/storage/abstract.rb +0 -2
  24. data/lib/carrierwave/storage/file.rb +3 -5
  25. data/lib/carrierwave/storage/grid_fs.rb +92 -0
  26. data/lib/carrierwave/storage/right_s3.rb +183 -0
  27. data/lib/carrierwave/storage/s3.rb +37 -69
  28. data/lib/carrierwave/test/matchers.rb +22 -8
  29. data/lib/carrierwave/uploader.rb +2 -2
  30. data/lib/carrierwave/uploader/cache.rb +21 -18
  31. data/lib/carrierwave/uploader/configuration.rb +122 -0
  32. data/lib/carrierwave/uploader/default_url.rb +19 -0
  33. data/lib/carrierwave/uploader/processing.rb +4 -2
  34. data/lib/carrierwave/uploader/remove.rb +0 -1
  35. data/lib/carrierwave/uploader/store.rb +1 -68
  36. data/lib/carrierwave/uploader/url.rb +1 -1
  37. data/lib/carrierwave/uploader/versions.rb +3 -4
  38. data/{lib/generators → merb_generators}/uploader_generator.rb +0 -0
  39. data/rails_generators/uploader/templates/uploader.rb +4 -4
  40. data/spec/compatibility/paperclip_spec.rb +11 -2
  41. data/spec/fixtures/landscape.jpg +0 -0
  42. data/spec/fixtures/portrait.jpg +0 -0
  43. data/spec/mount_spec.rb +0 -25
  44. data/spec/orm/datamapper_spec.rb +55 -48
  45. data/spec/orm/mongoid_spec.rb +206 -0
  46. data/spec/orm/mongomapper_spec.rb +19 -1
  47. data/spec/orm/sequel_spec.rb +3 -12
  48. data/spec/processing/image_science_spec.rb +56 -0
  49. data/spec/processing/mini_magick_spec.rb +76 -0
  50. data/spec/processing/rmagick_spec.rb +68 -0
  51. data/spec/sanitized_file_spec.rb +84 -74
  52. data/spec/spec_helper.rb +1 -3
  53. data/spec/storage/grid_fs_spec.rb +78 -0
  54. data/spec/storage/right_s3_spec.rb +75 -0
  55. data/spec/storage/s3_spec.rb +83 -0
  56. data/spec/uploader/cache_spec.rb +1 -13
  57. data/spec/uploader/configuration_spec.rb +105 -0
  58. data/spec/uploader/{default_path_spec.rb → default_url_spec.rb} +22 -5
  59. data/spec/uploader/paths_spec.rb +1 -1
  60. data/spec/uploader/processing_spec.rb +11 -0
  61. data/spec/uploader/store_spec.rb +21 -47
  62. data/spec/uploader/versions_spec.rb +0 -8
  63. metadata +105 -17
  64. data/LICENSE +0 -8
  65. data/carrierwave.gemspec +0 -57
  66. data/lib/carrierwave/uploader/default_path.rb +0 -23
  67. data/lib/carrierwave/uploader/paths.rb +0 -27
@@ -1,10 +1,12 @@
1
1
  # encoding: utf-8
2
2
 
3
- unless Module.const_defined?('Magick')
3
+ unless defined? Magick
4
4
  begin
5
5
  require 'rmagick'
6
6
  rescue LoadError
7
7
  require 'RMagick'
8
+ rescue LoadError
9
+ puts "WARNING: Failed to require rmagick, image processing may fail!"
8
10
  end
9
11
  end
10
12
 
@@ -175,8 +177,6 @@ module CarrierWave
175
177
  end
176
178
  end
177
179
 
178
- alias_method :resize, :resize_to_fit
179
-
180
180
  ##
181
181
  # From the RMagick documentation: "Resize the image to fit within the
182
182
  # specified dimensions while retaining the aspect ratio of the original
@@ -195,14 +195,12 @@ module CarrierWave
195
195
  #
196
196
  def resize_to_fill(width, height)
197
197
  manipulate! do |img|
198
- img.resize_to_fill!(width, height)
198
+ img.crop_resized!(width, height)
199
199
  img = yield(img) if block_given?
200
200
  img
201
201
  end
202
202
  end
203
203
 
204
- alias_method :crop_resized, :resize_to_fill
205
-
206
204
  ##
207
205
  # Resize the image to fit within the specified dimensions while retaining
208
206
  # the original aspect ratio. If necessary, will pad the remaining area
@@ -254,18 +254,19 @@ module CarrierWave
254
254
  return name.downcase
255
255
  end
256
256
 
257
- def split_extension(fn)
257
+ def split_extension(filename)
258
258
  # regular expressions to try for identifying extensions
259
- ext_regexps = [
260
- /\A(.+)\.([^\.]{1,3}\.[^\.]{1,4})\z/, # matches "something.tar.gz"
259
+ extension_matchers = [
260
+ /\A(.+)\.(tar\.gz)\z/, # matches "something.tar.gz"
261
261
  /\A(.+)\.([^\.]+)\z/ # matches "something.jpg"
262
262
  ]
263
- ext_regexps.each do |regexp|
264
- if fn =~ regexp
263
+
264
+ extension_matchers.each do |regexp|
265
+ if filename =~ regexp
265
266
  return $1, $2
266
267
  end
267
268
  end
268
- return fn, "" # In case we weren't able to split the extension
269
+ return filename, "" # In case we weren't able to split the extension
269
270
  end
270
271
 
271
272
  end # SanitizedFile
@@ -15,8 +15,6 @@ module CarrierWave
15
15
  @uploader = uploader
16
16
  end
17
17
 
18
- def self.setup!; end
19
-
20
18
  def identifier
21
19
  uploader.filename
22
20
  end
@@ -22,9 +22,8 @@ module CarrierWave
22
22
  # [CarrierWave::SanitizedFile] a sanitized file
23
23
  #
24
24
  def store!(file)
25
- path = ::File.join(uploader.store_path)
26
- path = ::File.expand_path(path, uploader.public)
27
- file.move_to(path, CarrierWave.config[:permissions])
25
+ path = ::File.expand_path(uploader.store_path, uploader.root)
26
+ file.move_to(path, uploader.permissions)
28
27
  file
29
28
  end
30
29
 
@@ -40,8 +39,7 @@ module CarrierWave
40
39
  # [CarrierWave::SanitizedFile] a sanitized file
41
40
  #
42
41
  def retrieve!(identifier)
43
- path = ::File.join(uploader.store_path(identifier))
44
- path = ::File.expand_path(path, uploader.public)
42
+ path = ::File.expand_path(uploader.store_path(identifier), uploader.root)
45
43
  CarrierWave::SanitizedFile.new(path)
46
44
  end
47
45
 
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+ require 'mongo'
3
+ require 'mongo/gridfs'
4
+
5
+ module CarrierWave
6
+ module Storage
7
+
8
+ ##
9
+ # The GridFS store uses MongoDB's GridStore file storage system to store files
10
+ #
11
+ class GridFS < Abstract
12
+
13
+ class File
14
+
15
+ def initialize(uploader, database, path)
16
+ @database = database
17
+ @path = path
18
+ @uploader = uploader
19
+ end
20
+
21
+ def path
22
+ nil
23
+ end
24
+
25
+ def url
26
+ unless @uploader.grid_fs_access_url
27
+ nil
28
+ else
29
+ [@uploader.grid_fs_access_url, @path].join("/")
30
+ end
31
+ end
32
+
33
+ def read
34
+ ::GridFS::GridStore.read(@database, @path)
35
+ end
36
+
37
+ def delete
38
+ ::GridFS::GridStore.unlink(@database, @path)
39
+ end
40
+
41
+ end
42
+
43
+ ##
44
+ # Store the file in MongoDB's GridFS GridStore
45
+ #
46
+ # === Parameters
47
+ #
48
+ # [file (CarrierWave::SanitizedFile)] the file to store
49
+ #
50
+ # === Returns
51
+ #
52
+ # [CarrierWave::SanitizedFile] a sanitized file
53
+ #
54
+ def store!(file)
55
+ ::GridFS::GridStore.open(database, uploader.store_path, 'w') do |f|
56
+ f.write file.read
57
+ end
58
+ CarrierWave::Storage::GridFS::File.new(uploader, database, uploader.store_path)
59
+ end
60
+
61
+ ##
62
+ # Retrieve the file from MongoDB's GridFS GridStore
63
+ #
64
+ # === Parameters
65
+ #
66
+ # [identifier (String)] the filename of the file
67
+ #
68
+ # === Returns
69
+ #
70
+ # [CarrierWave::Storage::GridFS::File] a sanitized file
71
+ #
72
+ def retrieve!(identifier)
73
+ CarrierWave::Storage::GridFS::File.new(uploader, database, uploader.store_path(identifier))
74
+ end
75
+
76
+ private
77
+
78
+ def database
79
+ @connection ||= begin
80
+ host = uploader.grid_fs_host
81
+ database = uploader.grid_fs_database
82
+ username = uploader.grid_fs_username
83
+ password = uploader.grid_fs_password
84
+ db = Mongo::Connection.new(host).db(database)
85
+ db.authenticate(username, password) if username && password
86
+ db
87
+ end
88
+ end
89
+
90
+ end # File
91
+ end # Storage
92
+ end # CarrierWave
@@ -0,0 +1,183 @@
1
+ # encoding: utf-8
2
+ require 'right_aws'
3
+
4
+ module CarrierWave
5
+ module Storage
6
+
7
+ ##
8
+ # Uploads things to Amazon S3 webservices using the RightAWS libraries (right_aws gem).
9
+ # In order for CarrierWave to connect to Amazon S3, you'll need to specify an access key id, secret key
10
+ # and bucket
11
+ #
12
+ # CarrierWave.configure do |config|
13
+ # config.s3_access_key_id = "xxxxxx"
14
+ # config.s3_secret_access_key = "xxxxxx"
15
+ # config.s3_bucket = "my_bucket_name"
16
+ # end
17
+ #
18
+ # The RightAWS::S3Interface is used directly as opposed to the normal RightAWS::S3::Bucket et.al. classes.
19
+ # This gives much improved performance and avoids unnecessary requests.
20
+ #
21
+ # You can set the access policy for the uploaded files:
22
+ #
23
+ # CarrierWave.configure do |config|
24
+ # config.s3_access_policy = 'public-read'
25
+ # end
26
+ #
27
+ # The default is 'public-read'. For more options see:
28
+ #
29
+ # http://docs.amazonwebservices.com/AmazonS3/latest/RESTAccessPolicy.html#RESTCannedAccessPolicies
30
+ #
31
+ # You can change the generated url to a cnamed domain by setting the cnamed config:
32
+ #
33
+ # CarrierWave.configure do |config|
34
+ # config.s3_cnamed = true
35
+ # config.s3_bucket = 'bucketname.domain.tld'
36
+ # end
37
+ #
38
+ # Now the resulting url will be
39
+ #
40
+ # http://bucketname.domain.tld/path/to/file
41
+ #
42
+ # instead of
43
+ #
44
+ # http://bucketname.domain.tld.s3.amazonaws.com/path/to/file
45
+ #
46
+ class RightS3 < Abstract
47
+
48
+ class File
49
+
50
+ def initialize(uploader, base, path)
51
+ @uploader = uploader
52
+ @path = path
53
+ @base = base
54
+ end
55
+
56
+ ##
57
+ # Returns the current path of the file on S3
58
+ #
59
+ # === Returns
60
+ #
61
+ # [String] A path
62
+ #
63
+ def path
64
+ @path
65
+ end
66
+
67
+ ##
68
+ # Reads the contents of the file from S3
69
+ #
70
+ # === Returns
71
+ #
72
+ # [String] contents of the file
73
+ #
74
+ def read
75
+ result = connection.get(bucket, @path)
76
+ headers["content-type"] = result[:headers]["content-type"]
77
+ result[:object]
78
+ end
79
+
80
+ ##
81
+ # Remove the file from Amazon S3
82
+ #
83
+ def delete
84
+ connection.delete(bucket, @path)
85
+ end
86
+
87
+ ##
88
+ # Returns the url on Amazon's S3 service
89
+ #
90
+ # === Returns
91
+ #
92
+ # [String] file's url
93
+ #
94
+ def url
95
+ if @uploader.s3_cnamed
96
+ ["http://", @uploader.s3_bucket, @path].compact.join('/')
97
+ else
98
+ ["http://#{@uploader.s3_bucket}.s3.amazonaws.com", @path].compact.join('/')
99
+ end
100
+ end
101
+
102
+ #def about
103
+ # s3_object.about
104
+ #end
105
+
106
+ #def metadata
107
+ # s3_object.metadata
108
+ #end
109
+
110
+ def content_type
111
+ headers["content-type"]
112
+ end
113
+
114
+ def content_type=(new_content_type)
115
+ headers["content-type"] = new_content_type
116
+ end
117
+
118
+ #def content_disposition
119
+ # s3_object.content_disposition
120
+ #end
121
+
122
+ #def content_disposition=(new_disposition)
123
+ # s3_object.content_disposition = new_disposition
124
+ #end
125
+
126
+ def store(data)
127
+ connection.put(bucket, @path, data, headers)
128
+ end
129
+
130
+ private
131
+
132
+ def headers
133
+ @headers ||= { 'x-amz-acl' => @uploader.s3_access_policy }
134
+ end
135
+
136
+ def bucket
137
+ @uploader.s3_bucket
138
+ end
139
+
140
+ def connection
141
+ @base.connection
142
+ end
143
+
144
+ end
145
+
146
+ ##
147
+ # Store the file on S3
148
+ #
149
+ # === Parameters
150
+ #
151
+ # [file (CarrierWave::SanitizedFile)] the file to store
152
+ #
153
+ # === Returns
154
+ #
155
+ # [CarrierWave::Storage::RightS3::File] the stored file
156
+ #
157
+ def store!(file)
158
+ f = CarrierWave::Storage::RightS3::File.new(uploader, self, uploader.store_path)
159
+ f.store(file.read)
160
+ f
161
+ end
162
+
163
+ # Do something to retrieve the file
164
+ #
165
+ # @param [String] identifier uniquely identifies the file
166
+ #
167
+ # [identifier (String)] uniquely identifies the file
168
+ #
169
+ # === Returns
170
+ #
171
+ # [CarrierWave::Storage::RightS3::File] the stored file
172
+ #
173
+ def retrieve!(identifier)
174
+ CarrierWave::Storage::RightS3::File.new(uploader, self, uploader.store_path(identifier))
175
+ end
176
+
177
+ def connection
178
+ @connection ||= RightAws::S3Interface.new(uploader.s3_access_key_id, uploader.s3_secret_access_key)
179
+ end
180
+
181
+ end # RightS3
182
+ end # Storage
183
+ end # CarrierWave
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ require 'aws/s3'
2
3
 
3
4
  module CarrierWave
4
5
  module Storage
@@ -8,13 +9,17 @@ module CarrierWave
8
9
  # CarrierWave to connect to Amazon S3, you'll need to specify an access key id, secret key
9
10
  # and bucket
10
11
  #
11
- # CarrierWave.config[:s3][:access_key_id] = "xxxxxx"
12
- # CarrierWave.config[:s3][:secret_access_key] = "xxxxxx"
13
- # CarrierWave.config[:s3][:bucket] = "my_bucket_name"
12
+ # CarrierWave.configure do |config|
13
+ # config.s3_access_key_id = "xxxxxx"
14
+ # config.s3_secret_access_key = "xxxxxx"
15
+ # config.s3_bucket = "my_bucket_name"
16
+ # end
14
17
  #
15
18
  # You can also set the access policy for the uploaded files:
16
19
  #
17
- # CarrierWave.config[:s3][:access] = :public_read
20
+ # CarrierWave.configure do |config|
21
+ # config.s3_access = :public
22
+ # end
18
23
  #
19
24
  # Possible values are the 'canned access control policies' provided in the aws/s3 gem,
20
25
  # they are:
@@ -31,23 +36,26 @@ module CarrierWave
31
36
  #
32
37
  # You can change the generated url to a cnamed domain by setting the cnamed config:
33
38
  #
34
- # CarrierWave.config[:s3][:cnamed] = true
39
+ # CarrierWave.configure do |config|
40
+ # config.s3_cnamed = true
41
+ # config.s3_bucket = 'bucketname.domain.tld'
42
+ # end
35
43
  #
36
- # No the resulting url will be
44
+ # Now the resulting url will be
37
45
  #
38
- # http://bucket_name.domain.tld/path/to/file
46
+ # http://bucketname.domain.tld/path/to/file
39
47
  #
40
48
  # instead of
41
49
  #
42
- # http://s3.amazonaws.com/bucket_name.domain.tld/path/to/file
50
+ # http://s3.amazonaws.com/bucketname.domain.tld/path/to/file
43
51
  #
44
52
  class S3 < Abstract
45
53
 
46
54
  class File
47
55
 
48
- def initialize(path, identifier)
56
+ def initialize(uploader, path)
57
+ @uploader = uploader
49
58
  @path = path
50
- @identifier = identifier
51
59
  end
52
60
 
53
61
  ##
@@ -61,17 +69,6 @@ module CarrierWave
61
69
  @path
62
70
  end
63
71
 
64
- ##
65
- # Returns the filename on S3
66
- #
67
- # === Returns
68
- #
69
- # [String] path to the file
70
- #
71
- def identifier
72
- @identifier
73
- end
74
-
75
72
  ##
76
73
  # Reads the contents of the file from S3
77
74
  #
@@ -80,14 +77,14 @@ module CarrierWave
80
77
  # [String] contents of the file
81
78
  #
82
79
  def read
83
- AWS::S3::S3Object.value @path, bucket
80
+ AWS::S3::S3Object.value @path, @uploader.s3_bucket
84
81
  end
85
82
 
86
83
  ##
87
84
  # Remove the file from Amazon S3
88
85
  #
89
86
  def delete
90
- AWS::S3::S3Object.delete @path, bucket
87
+ AWS::S3::S3Object.delete @path, @uploader.s3_bucket
91
88
  end
92
89
 
93
90
  ##
@@ -98,10 +95,10 @@ module CarrierWave
98
95
  # [String] file's url
99
96
  #
100
97
  def url
101
- if CarrierWave::config[:s3][:cnamed]
102
- ["http://", bucket, @path].compact.join('/')
98
+ if @uploader.s3_cnamed
99
+ ["http://", @uploader.s3_bucket, "/", @path].compact.join
103
100
  else
104
- ["http://s3.amazonaws.com", bucket, @path].compact.join('/')
101
+ ["http://s3.amazonaws.com", @uploader.s3_bucket, @path].compact.join('/')
105
102
  end
106
103
  end
107
104
 
@@ -137,46 +134,6 @@ module CarrierWave
137
134
  @s3_object ||= AWS::S3::S3Object.find(@path, bucket)
138
135
  end
139
136
 
140
-
141
- private
142
-
143
- def bucket
144
- CarrierWave::Storage::S3.bucket
145
- end
146
-
147
- def access
148
- CarrierWave::Storage::S3.access
149
- end
150
-
151
- end
152
-
153
- ##
154
- # === Returns
155
- #
156
- # [String] the bucket set in the config options
157
- #
158
- def self.bucket
159
- CarrierWave.config[:s3][:bucket]
160
- end
161
-
162
- ##
163
- # === Returns
164
- #
165
- # [Symbol] the access priviliges the uploaded files should have
166
- #
167
- def self.access
168
- CarrierWave.config[:s3][:access]
169
- end
170
-
171
- ##
172
- # Connect to Amazon S3
173
- #
174
- def self.setup!
175
- require 'aws/s3'
176
- AWS::S3::Base.establish_connection!(
177
- :access_key_id => CarrierWave.config[:s3][:access_key_id],
178
- :secret_access_key => CarrierWave.config[:s3][:secret_access_key]
179
- )
180
137
  end
181
138
 
182
139
  ##
@@ -191,8 +148,9 @@ module CarrierWave
191
148
  # [CarrierWave::Storage::S3] the stored file
192
149
  #
193
150
  def store!(file)
194
- AWS::S3::S3Object.store(::File.join(uploader.store_path), file.read, self.class.bucket, :access => self.class.access)
195
- CarrierWave::Storage::S3::File.new(uploader.store_path, uploader.filename)
151
+ connect!(uploader)
152
+ AWS::S3::S3Object.store(uploader.store_path, file.read, uploader.s3_bucket, :access => uploader.s3_access)
153
+ CarrierWave::Storage::S3::File.new(uploader, uploader.store_path)
196
154
  end
197
155
 
198
156
  # Do something to retrieve the file
@@ -207,7 +165,17 @@ module CarrierWave
207
165
  # [CarrierWave::Storage::S3::File] the stored file
208
166
  #
209
167
  def retrieve!(identifier)
210
- CarrierWave::Storage::S3::File.new(uploader.store_path(identifier), identifier)
168
+ connect!(uploader)
169
+ CarrierWave::Storage::S3::File.new(uploader, uploader.store_path(identifier))
170
+ end
171
+
172
+ private
173
+
174
+ def connect!(uploader)
175
+ AWS::S3::Base.establish_connection!(
176
+ :access_key_id => uploader.s3_access_key_id,
177
+ :secret_access_key => uploader.s3_secret_access_key
178
+ )
211
179
  end
212
180
 
213
181
  end # S3