jnicklas-carrierwave 0.1.1 → 0.2.0

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.
@@ -0,0 +1,23 @@
1
+ require 'sequel'
2
+
3
+ module CarrierWave
4
+ module Sequel
5
+
6
+ include CarrierWave::Mount
7
+
8
+ def mount_uploader(column, uploader)
9
+ super
10
+
11
+ alias_method :read_uploader, :[]
12
+ alias_method :write_uploader, :[]=
13
+
14
+ before_save do
15
+ send("store_#{column}!")
16
+ end
17
+ end
18
+
19
+ end # Sequel
20
+ end # CarrierWave
21
+
22
+ Sequel::Model.send(:extend, CarrierWave::Sequel)
23
+
@@ -2,7 +2,7 @@ require "image_science"
2
2
 
3
3
  module CarrierWave
4
4
  module ImageScience
5
-
5
+
6
6
  # Resize the image so that it will not exceed the dimensions passed
7
7
  # via geometry, geometry should be a string, formatted like '200x100' where
8
8
  # the first number is the height and the second is the width
@@ -63,8 +63,8 @@ module CarrierWave
63
63
  end
64
64
 
65
65
  def convert_geometry(geometry)
66
- geometry.split('x').map{|i| i.to_f }
66
+ geometry.split('x').map{|i| i.to_f }
67
67
  end
68
68
 
69
69
  end # ImageScience
70
- end # CarrierWave
70
+ end # CarrierWave
@@ -1,37 +1,40 @@
1
1
  require 'rmagick'
2
2
 
3
3
  module CarrierWave
4
-
4
+
5
5
  ##
6
6
  # This module simplifies manipulation with RMagick by providing a set
7
7
  # of convenient helper methods. If you want to use them, you'll need to
8
- # require this file
8
+ # require this file:
9
9
  #
10
10
  # require 'carrierwave/processing/rmagick'
11
11
  #
12
- # And then include it in your uploader
12
+ # And then include it in your uploader:
13
13
  #
14
- # MyUploade < CarrierWave::Uploader
14
+ # class MyUploader
15
+ # include CarrierWave::Uploader
15
16
  # include CarrierWave::RMagick
16
17
  # end
17
18
  #
18
19
  # You can now use the provided helpers:
19
20
  #
20
- # MyUploade < CarrierWave::Uploader
21
+ # class MyUploader
22
+ # include CarrierWave::Uploader
21
23
  # include CarrierWave::RMagick
22
- #
23
- # process :resize_to_fit => [200, 200]
24
+ #
25
+ # process :resize_to_fit => [200, 200]
24
26
  # end
25
27
  #
26
28
  # Or create your own helpers with the powerful manipulate! method. Check
27
29
  # out the RMagick docs at http://www.imagemagick.org/RMagick/doc/ for more
28
30
  # info
29
31
  #
30
- # MyUploade < CarrierWave::Uploader
32
+ # class MyUploader
33
+ # include CarrierWave::Uploader
31
34
  # include CarrierWave::RMagick
32
- #
35
+ #
33
36
  # process :do_stuff => 10.0
34
- #
37
+ #
35
38
  # def do_stuff(blur_factor)
36
39
  # manipulate! do |img|
37
40
  # img = img.sepiatone
@@ -41,17 +44,41 @@ module CarrierWave
41
44
  # end
42
45
  # end
43
46
  #
47
+ # === Note
48
+ #
49
+ # You should be aware how RMagick handles memory. manipulate! takes care
50
+ # of freeing up memory for you, but for optimum memory usage you should
51
+ # use destructive operations as much as possible:
52
+ #
53
+ # DON'T DO THIS:
54
+ # img = img.resize_to_fit
55
+ #
56
+ # DO THIS INSTEAD:
57
+ # img.resize_to_fit!
58
+ #
59
+ # Read this for more information why:
60
+ #
61
+ # http://rubyforge.org/forum/forum.php?thread_id=1374&forum_id=1618
62
+ #
44
63
  module RMagick
45
-
64
+
46
65
  ##
47
66
  # Changes the image encoding format to the given format
48
67
  #
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
68
+ # See even http://www.imagemagick.org/RMagick/doc/magick.html#formats
69
+ #
70
+ # === Parameters
71
+ #
72
+ # [format (#to_s)] an abreviation of the format
73
+ #
74
+ # === Yields
75
+ #
76
+ # [Magick::Image] additional manipulations to perform
77
+ #
78
+ # === Examples
79
+ #
53
80
  # image.convert(:png)
54
- #
81
+ #
55
82
  def convert(format)
56
83
  manipulate! do |img|
57
84
  img.format = format.to_s.upcase
@@ -66,12 +93,17 @@ module CarrierWave
66
93
  # image may be shorter or narrower than specified in the smaller dimension
67
94
  # but will not be larger than the specified values."
68
95
  #
69
- # @see http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fit
96
+ # See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fit
97
+ #
98
+ # === Parameters
99
+ #
100
+ # [width (Integer)] the width to scale the image to
101
+ # [height (Integer)] the height to scale the image to
102
+ #
103
+ # === Yields
104
+ #
105
+ # [Magick::Image] additional manipulations to perform
70
106
  #
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
107
  def resize_to_fit(width, height)
76
108
  manipulate! do |img|
77
109
  img.resize_to_fit!(width, height)
@@ -79,7 +111,7 @@ module CarrierWave
79
111
  img
80
112
  end
81
113
  end
82
-
114
+
83
115
  alias_method :resize, :resize_to_fit
84
116
 
85
117
  ##
@@ -87,11 +119,16 @@ module CarrierWave
87
119
  # specified dimensions while retaining the aspect ratio of the original
88
120
  # image. If necessary, crop the image in the larger dimension."
89
121
  #
90
- # @see http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fill
122
+ # See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fill
123
+ #
124
+ # === Parameters
91
125
  #
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
126
+ # [width (Integer)] the width to scale the image to
127
+ # [height (Integer)] the height to scale the image to
128
+ #
129
+ # === Yields
130
+ #
131
+ # [Magick::Image] additional manipulations to perform
95
132
  #
96
133
  def resize_to_fill(width, height)
97
134
  manipulate! do |img|
@@ -100,33 +137,40 @@ module CarrierWave
100
137
  img
101
138
  end
102
139
  end
103
-
140
+
104
141
  alias_method :crop_resized, :resize_to_fill
105
-
142
+
106
143
  ##
107
144
  # Resize the image to fit within the specified dimensions while retaining
108
- # the original aspect ratio. If necessary will pad the remaining area
145
+ # the original aspect ratio. If necessary, will pad the remaining area
109
146
  # with the given color, which defaults to transparent (for gif and png,
110
147
  # white for jpeg).
111
148
  #
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
149
+ # === Parameters
150
+ #
151
+ # [width (Integer)] the width to scale the image to
152
+ # [height (Integer)] the height to scale the image to
153
+ # [background (String, :transparent)] the color of the background as a hexcode, like "#ff45de"
154
+ # [gravity (Magick::GravityType)] how to position the image
155
+ #
156
+ # === Yields
157
+ #
158
+ # [Magick::Image] additional manipulations to perform
117
159
  #
118
160
  def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
119
161
  manipulate! do |img|
120
162
  img.resize_to_fit!(width, height)
121
163
  new_img = ::Magick::Image.new(width, height)
122
164
  if background == :transparent
123
- new_img = new_img.matte_floodfill(1, 1)
165
+ filled = new_img.matte_floodfill(1, 1)
124
166
  else
125
- new_img = new_img.color_floodfill(1, 1, ::Magick::Pixel.from_color(background))
167
+ filled = new_img.color_floodfill(1, 1, ::Magick::Pixel.from_color(background))
126
168
  end
127
- new_img = new_img.composite(img, gravity, ::Magick::OverCompositeOp)
128
- new_img = yield(new_img) if block_given?
129
- new_img
169
+ new_img.destroy!
170
+ filled.composite!(img, gravity, ::Magick::OverCompositeOp)
171
+ img.destroy!
172
+ filled = yield(filled) if block_given?
173
+ filled
130
174
  end
131
175
  end
132
176
 
@@ -135,11 +179,20 @@ module CarrierWave
135
179
  # and then pass each of its frames to the supplied block. It will then
136
180
  # save the image to disk.
137
181
  #
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.
182
+ # === Gotcha
183
+ #
184
+ # This method assumes that the object responds to +current_path+.
185
+ # Any class that this module is mixed into must have a +current_path+ method.
186
+ # CarrierWave::Uploader does, so you won't need to worry about this in
187
+ # most cases.
188
+ #
189
+ # === Yields
140
190
  #
141
- # @yieldparam [Magick::Image] img manipulations to perform
142
- # @raise [CarrierWave::ProcessingError] if manipulation failed.
191
+ # [Magick::Image] manipulations to perform
192
+ #
193
+ # === Raises
194
+ #
195
+ # [CarrierWave::ProcessingError] if manipulation failed.
143
196
  #
144
197
  def manipulate!
145
198
  image = ::Magick::Image.read(current_path)
@@ -150,12 +203,15 @@ module CarrierWave
150
203
  list << yield( frame )
151
204
  end
152
205
  list.write(current_path)
206
+ list.destroy!
153
207
  else
154
- yield( image.first ).write(current_path)
208
+ frame = image.first
209
+ yield( frame ).write(current_path)
210
+ frame.destroy!
155
211
  end
156
212
  rescue ::Magick::ImageMagickError => e
157
213
  raise CarrierWave::ProcessingError.new("Failed to manipulate with rmagick, maybe it is not an image? Original Error: #{e}")
158
- end
159
-
214
+ end
215
+
160
216
  end # RMagick
161
- end # CarrierWave
217
+ end # CarrierWave
@@ -10,17 +10,18 @@ module CarrierWave
10
10
  #
11
11
  class SanitizedFile
12
12
 
13
- attr_accessor :file, :options
13
+ attr_accessor :file
14
14
 
15
- def initialize(file, options = {})
15
+ def initialize(file)
16
16
  self.file = file
17
- self.options = options
18
17
  end
19
18
 
20
19
  ##
21
20
  # Returns the filename as is, without sanizting it.
22
21
  #
23
- # @return [String] the unsanitized filename
22
+ # === Returns
23
+ #
24
+ # [String] the unsanitized filename
24
25
  #
25
26
  def original_filename
26
27
  return @original_filename if @original_filename
@@ -30,32 +31,38 @@ module CarrierWave
30
31
  File.basename(path)
31
32
  end
32
33
  end
33
-
34
+
34
35
  ##
35
36
  # Returns the filename, sanitized to strip out any evil characters.
36
37
  #
37
- # @return [String] the sanitized filename
38
+ # === Returns
39
+ #
40
+ # [String] the sanitized filename
38
41
  #
39
42
  def filename
40
43
  sanitize(original_filename) if original_filename
41
44
  end
42
-
45
+
43
46
  alias_method :identifier, :filename
44
-
47
+
45
48
  ##
46
49
  # Returns the part of the filename before the extension. So if a file is called 'test.jpeg'
47
50
  # this would return 'test'
48
51
  #
49
- # @return [String] the first part of the filename
52
+ # === Returns
53
+ #
54
+ # [String] the first part of the filename
50
55
  #
51
56
  def basename
52
57
  split_extension(filename)[0] if filename
53
58
  end
54
-
59
+
55
60
  ##
56
61
  # Returns the file extension
57
62
  #
58
- # @return [String] the extension
63
+ # === Returns
64
+ #
65
+ # [String] the extension
59
66
  #
60
67
  def extension
61
68
  split_extension(filename)[1] if filename
@@ -64,16 +71,18 @@ module CarrierWave
64
71
  ##
65
72
  # Returns the file's size.
66
73
  #
67
- # @return [Integer] the file's size in bytes.
74
+ # === Returns
75
+ #
76
+ # [Integer] the file's size in bytes.
68
77
  #
69
78
  def size
70
- if string?
79
+ if is_path?
71
80
  exists? ? File.size(path) : 0
72
81
  elsif @file.respond_to?(:size)
73
- @file.size
82
+ @file.size
74
83
  elsif path
75
84
  exists? ? File.size(path) : 0
76
- else
85
+ else
77
86
  0
78
87
  end
79
88
  end
@@ -81,53 +90,59 @@ module CarrierWave
81
90
  ##
82
91
  # Returns the full path to the file. If the file has no path, it will return nil.
83
92
  #
84
- # @return [String, nil] the path where the file is located.
93
+ # === Returns
94
+ #
95
+ # [String, nil] the path where the file is located.
85
96
  #
86
97
  def path
87
98
  unless @file.blank?
88
- if string?
99
+ if is_path?
89
100
  File.expand_path(@file)
90
101
  elsif @file.respond_to?(:path) and not @file.path.blank?
91
102
  File.expand_path(@file.path)
92
103
  end
93
104
  end
94
105
  end
95
-
106
+
96
107
  ##
97
- # Returns true if the file is supplied as a pathname or as a string.
108
+ # === Returns
98
109
  #
99
- # @return [Boolean]
110
+ # [Boolean] whether the file is supplied as a pathname or string.
100
111
  #
101
- def string?
112
+ def is_path?
102
113
  !!((@file.is_a?(String) || @file.is_a?(Pathname)) && !@file.blank?)
103
114
  end
104
115
 
105
116
  ##
106
- # Checks if the file is valid and has a non-zero size
117
+ # === Returns
107
118
  #
108
- # @return [Boolean]
119
+ # [Boolean] whether the file is valid and has a non-zero size
109
120
  #
110
121
  def empty?
111
122
  @file.nil? || self.size.nil? || self.size.zero?
112
123
  end
113
124
 
125
+ alias_method :blank?, :empty?
126
+
114
127
  ##
115
- # Checks if the file exists
128
+ # === Returns
116
129
  #
117
- # @return [Boolean]
130
+ # [Boolean] Whether the file exists
118
131
  #
119
132
  def exists?
120
133
  return File.exists?(self.path) if self.path
121
134
  return false
122
135
  end
123
-
136
+
124
137
  ##
125
138
  # Returns the contents of the file.
126
139
  #
127
- # @return [String] contents of the file
140
+ # === Returns
141
+ #
142
+ # [String] contents of the file
128
143
  #
129
144
  def read
130
- if string?
145
+ if is_path?
131
146
  File.read(@file)
132
147
  else
133
148
  @file.rewind if @file.respond_to?(:rewind)
@@ -138,9 +153,12 @@ module CarrierWave
138
153
  ##
139
154
  # Moves the file to the given path
140
155
  #
141
- # @param [String] new_path The path where the file should be moved.
156
+ # === Parameters
142
157
  #
143
- def move_to(new_path)
158
+ # [new_path (String)] The path where the file should be moved.
159
+ # [permissions (Integer)] permissions to set on the file in its new location.
160
+ #
161
+ def move_to(new_path, permissions=nil)
144
162
  return if self.empty?
145
163
  new_path = File.expand_path(new_path)
146
164
 
@@ -150,17 +168,23 @@ module CarrierWave
150
168
  else
151
169
  File.open(new_path, "wb") { |f| f.write(read) }
152
170
  end
153
- chmod!(new_path)
171
+ chmod!(new_path, permissions)
154
172
  self.file = new_path
155
173
  end
156
174
 
157
175
  ##
158
176
  # Creates a copy of this file and moves it to the given path. Returns the copy.
159
177
  #
160
- # @param [String] new_path The path where the file should be copied to.
178
+ # === Parameters
179
+ #
180
+ # [new_path (String)] The path where the file should be copied to.
181
+ # [permissions (Integer)] permissions to set on the copy
182
+ #
183
+ # === Returns
184
+ #
161
185
  # @return [CarrierWave::SanitizedFile] the location where the file will be stored.
162
186
  #
163
- def copy_to(new_path)
187
+ def copy_to(new_path, permissions=nil)
164
188
  return if self.empty?
165
189
  new_path = File.expand_path(new_path)
166
190
 
@@ -170,7 +194,7 @@ module CarrierWave
170
194
  else
171
195
  File.open(new_path, "wb") { |f| f.write(read) }
172
196
  end
173
- chmod!(new_path)
197
+ chmod!(new_path, permissions)
174
198
  self.class.new(new_path)
175
199
  end
176
200
 
@@ -184,7 +208,9 @@ module CarrierWave
184
208
  ##
185
209
  # Returns the content type of the file.
186
210
  #
187
- # @return [String] the content type of the file
211
+ # === Returns
212
+ #
213
+ # [String] the content type of the file
188
214
  #
189
215
  def content_type
190
216
  return @content_type if @content_type
@@ -192,26 +218,26 @@ module CarrierWave
192
218
  end
193
219
 
194
220
  private
195
-
221
+
196
222
  def file=(file)
197
223
  if file.is_a?(Hash)
198
- @file = file["tempfile"]
199
- @original_filename = file["filename"]
200
- @content_type = file["content_type"]
224
+ @file = file["tempfile"] || file[:tempfile]
225
+ @original_filename = file["filename"] || file[:filename]
226
+ @content_type = file["content_type"] || file[:content_type]
201
227
  else
202
228
  @file = file
203
229
  @original_filename = nil
204
230
  @content_type = nil
205
231
  end
206
232
  end
207
-
233
+
208
234
  # create the directory if it doesn't exist
209
235
  def mkdir!(path)
210
236
  FileUtils.mkdir_p(File.dirname(path)) unless File.exists?(File.dirname(path))
211
237
  end
212
-
213
- def chmod!(path)
214
- File.chmod(@options[:permissions], path) if @options[:permissions]
238
+
239
+ def chmod!(path, permissions)
240
+ File.chmod(permissions, path) if permissions
215
241
  end
216
242
 
217
243
  # Sanitize the filename, to prevent hacking
@@ -226,7 +252,7 @@ module CarrierWave
226
252
 
227
253
  def split_extension(fn)
228
254
  # regular expressions to try for identifying extensions
229
- ext_regexps = [
255
+ ext_regexps = [
230
256
  /\A(.+)\.([^\.]{1,3}\.[^\.]{1,4})\z/, # matches "something.tar.gz"
231
257
  /\A(.+)\.([^\.]+)\z/ # matches "something.jpg"
232
258
  ]
@@ -239,4 +265,4 @@ module CarrierWave
239
265
  end
240
266
 
241
267
  end # SanitizedFile
242
- end # CarrierWave
268
+ end # CarrierWave
@@ -27,10 +27,14 @@ module CarrierWave
27
27
  ##
28
28
  # Do something to store the file
29
29
  #
30
- # @param [CarrierWave::Uploader] uploader an uploader object
31
- # @param [CarrierWave::SanitizedFile] file the file to store
30
+ # === Parameters
32
31
  #
33
- # @return [#identifier] an object
32
+ # [uploader (CarrierWave::Uploader)] an uploader object
33
+ # [file (CarrierWave::SanitizedFile)] the file to store
34
+ #
35
+ # === Returns
36
+ #
37
+ # [#identifier] an object
34
38
  #
35
39
  def self.store!(uploader, file)
36
40
  self.new
@@ -38,10 +42,14 @@ module CarrierWave
38
42
 
39
43
  # Do something to retrieve the file
40
44
  #
41
- # @param [CarrierWave::Uploader] uploader an uploader object
42
- # @param [String] identifier uniquely identifies the file
45
+ # === Parameters
46
+ #
47
+ # [uploader (CarrierWave::Uploader)] an uploader object
48
+ # [identifier (String)] uniquely identifies the file
49
+ #
50
+ # === Returns
43
51
  #
44
- # @return [#identifier] an object
52
+ # [#identifier] an object
45
53
  #
46
54
  def self.retrieve!(uploader, identifier)
47
55
  self.new
@@ -53,7 +61,9 @@ module CarrierWave
53
61
  #
54
62
  # This is OPTIONAL
55
63
  #
56
- # @return [String] path to the file
64
+ # === Returns
65
+ #
66
+ # [String] path to the file
57
67
  #
58
68
  def identifier; end
59
69
 
@@ -63,7 +73,9 @@ module CarrierWave
63
73
  #
64
74
  # This is OPTIONAL
65
75
  #
66
- # @return [String] file's url
76
+ # === Returns
77
+ #
78
+ # [String] file's url
67
79
  #
68
80
  def url; end
69
81
 
@@ -72,7 +84,9 @@ module CarrierWave
72
84
  #
73
85
  # This is OPTIONAL
74
86
  #
75
- # @return [String] path to the file
87
+ # === Returns
88
+ #
89
+ # [String] path to the file
76
90
  #
77
91
  def path; end
78
92
 
@@ -15,28 +15,36 @@ module CarrierWave
15
15
  ##
16
16
  # Move the file to the uploader's store path.
17
17
  #
18
- # @param [CarrierWave::Uploader] uploader an uploader object
19
- # @param [CarrierWave::SanitizedFile] file the file to store
18
+ # === Parameters
20
19
  #
21
- # @return [CarrierWave::SanitizedFile] a sanitized file
20
+ # [uploader (CarrierWave::Uploader)] an uploader object
21
+ # [file (CarrierWave::SanitizedFile)] the file to store
22
+ #
23
+ # === Returns
24
+ #
25
+ # [CarrierWave::SanitizedFile] a sanitized file
22
26
  #
23
27
  def self.store!(uploader, file)
24
- path = ::File.join(uploader.store_dir, uploader.filename)
28
+ path = ::File.join(uploader.store_path)
25
29
  path = ::File.expand_path(path, uploader.public)
26
- file.move_to(path)
30
+ file.move_to(path, CarrierWave.config[:permissions])
27
31
  file
28
32
  end
29
33
 
30
34
  ##
31
35
  # Retrieve the file from its store path
32
36
  #
33
- # @param [CarrierWave::Uploader] uploader an uploader object
34
- # @param [String] identifier the filename of the file
37
+ # === Parameters
38
+ #
39
+ # [uploader (CarrierWave::Uploader)] an uploader object
40
+ # [identifier (String)] the filename of the file
41
+ #
42
+ # === Returns
35
43
  #
36
- # @return [CarrierWave::SanitizedFile] a sanitized file
44
+ # [CarrierWave::SanitizedFile] a sanitized file
37
45
  #
38
46
  def self.retrieve!(uploader, identifier)
39
- path = ::File.join(uploader.store_dir, identifier)
47
+ path = ::File.join(uploader.store_path(identifier))
40
48
  path = ::File.expand_path(path, uploader.public)
41
49
  CarrierWave::SanitizedFile.new(path)
42
50
  end