durran-carrierwave 0.3.2.3 → 0.4.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 (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