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,75 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_record'
4
+
5
+ module CarrierWave
6
+ module ActiveRecord
7
+
8
+ include CarrierWave::Mount
9
+
10
+ ##
11
+ # See +CarrierWave::Mount#mount_uploader+ for documentation
12
+ #
13
+ def mount_uploader(column, uploader, options={}, &block)
14
+ super
15
+
16
+ alias_method :read_uploader, :read_attribute
17
+ alias_method :write_uploader, :write_attribute
18
+ public :read_uploader
19
+ public :write_uploader
20
+
21
+ validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
22
+ validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
23
+
24
+ after_save "store_#{column}!"
25
+ before_save "write_#{column}_identifier"
26
+ after_destroy "remove_#{column}!"
27
+ end
28
+
29
+ ##
30
+ # Makes the record invalid if the file couldn't be uploaded due to an integrity error
31
+ #
32
+ # Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
33
+ #
34
+ # === Note
35
+ #
36
+ # Set this key in your translations file for I18n:
37
+ #
38
+ # carrierwave:
39
+ # errors:
40
+ # integrity: 'Here be an error message'
41
+ #
42
+ def validates_integrity_of(*attrs)
43
+ options = attrs.last.is_a?(Hash) ? attrs.last : {}
44
+ options[:message] ||= I18n.t('carrierwave.errors.integrity', :default => 'is not an allowed type of file.')
45
+ validates_each(*attrs) do |record, attr, value|
46
+ record.errors.add attr, options[:message] if record.send("#{attr}_integrity_error")
47
+ end
48
+ end
49
+
50
+ ##
51
+ # Makes the record invalid if the file couldn't be processed (assuming the process failed
52
+ # with a CarrierWave::ProcessingError)
53
+ #
54
+ # Accepts the usual parameters for validations in Rails (:if, :unless, etc...)
55
+ #
56
+ # === Note
57
+ #
58
+ # Set this key in your translations file for I18n:
59
+ #
60
+ # carrierwave:
61
+ # errors:
62
+ # processing: 'Here be an error message'
63
+ #
64
+ def validates_processing_of(*attrs)
65
+ options = attrs.last.is_a?(Hash) ? attrs.last : {}
66
+ options[:message] ||= I18n.t('carrierwave.errors.processing', :default => 'failed to be processed.')
67
+ validates_each(*attrs) do |record, attr, value|
68
+ record.errors.add attr, options[:message] if record.send("#{attr}_processing_error")
69
+ end
70
+ end
71
+
72
+ end # ActiveRecord
73
+ end # CarrierWave
74
+
75
+ ActiveRecord::Base.send(:extend, CarrierWave::ActiveRecord)
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'dm-core'
4
+
5
+ module CarrierWave
6
+ module DataMapper
7
+
8
+ include CarrierWave::Mount
9
+
10
+ ##
11
+ # See +CarrierWave::Mount#mount_uploader+ for documentation
12
+ #
13
+ def mount_uploader(column, uploader, options={}, &block)
14
+ super
15
+
16
+ alias_method :read_uploader, :attribute_get
17
+ alias_method :write_uploader, :attribute_set
18
+ after :save, "store_#{column}!".to_sym
19
+ pre_hook = ::DataMapper.const_defined?(:Validate) ? :valid? : :save
20
+ before pre_hook, "write_#{column}_identifier".to_sym
21
+ after :destroy, "remove_#{column}!".to_sym
22
+ end
23
+
24
+ end # DataMapper
25
+ end # CarrierWave
26
+
27
+ DataMapper::Model.send(:include, CarrierWave::DataMapper)
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ require 'mongoid'
3
+
4
+ module CarrierWave
5
+ module Mongoid
6
+ include CarrierWave::Mount
7
+ ##
8
+ # See +CarrierWave::Mount#mount_uploader+ for documentation
9
+ #
10
+ def mount_uploader(column, uploader, options={}, &block)
11
+ options[:mount_on] ||= "#{column}_filename"
12
+ field options[:mount_on]
13
+ super
14
+ alias_method :read_uploader, :read_attribute
15
+ alias_method :write_uploader, :write_attribute
16
+ after_save "store_#{column}!".to_sym
17
+ before_save "write_#{column}_identifier".to_sym
18
+ after_destroy "remove_#{column}!".to_sym
19
+ end
20
+ end # Mongoid
21
+ end # CarrierWave
22
+
23
+ Mongoid::Document::ClassMethods.send(:include, CarrierWave::Mongoid)
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require 'mongo_mapper'
3
+
4
+ module CarrierWave
5
+ module MongoMapper
6
+ include CarrierWave::Mount
7
+ ##
8
+ # See +CarrierWave::Mount#mount_uploader+ for documentation
9
+ #
10
+ def mount_uploader(column, uploader, options={}, &block)
11
+ # We need to set the mount_on column (or key in MongoMapper's case)
12
+ # since MongoMapper will attempt to set the filename on
13
+ # the uploader instead of the file on a Document's initialization.
14
+ options[:mount_on] ||= "#{column}_filename"
15
+ key options[:mount_on]
16
+
17
+ super
18
+ alias_method :read_uploader, :[]
19
+ alias_method :write_uploader, :[]=
20
+ after_save "store_#{column}!".to_sym
21
+ before_save "write_#{column}_identifier".to_sym
22
+ after_destroy "remove_#{column}!".to_sym
23
+ end
24
+ end # MongoMapper
25
+ end # CarrierWave
26
+
27
+ MongoMapper::Document::ClassMethods.send(:include, CarrierWave::MongoMapper)
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'sequel'
4
+
5
+ module CarrierWave
6
+ module Sequel
7
+ include CarrierWave::Mount
8
+
9
+ def mount_uploader(column, uploader)
10
+ raise "You need to use Sequel 3.0 or higher. Please upgrade." unless ::Sequel::Model.respond_to?(:plugin)
11
+ super
12
+
13
+ alias_method :read_uploader, :[]
14
+ alias_method :write_uploader, :[]=
15
+
16
+ include CarrierWave::Sequel::Hooks
17
+ include CarrierWave::Sequel::Validations
18
+ end
19
+
20
+ end # Sequel
21
+ end # CarrierWave
22
+
23
+ # Instance hook methods for the Sequel 3.x
24
+ module CarrierWave::Sequel::Hooks
25
+ def after_save
26
+ return false if super == false
27
+ self.class.uploaders.each_key {|column| self.send("store_#{column}!") }
28
+ end
29
+
30
+ def before_save
31
+ return false if super == false
32
+ self.class.uploaders.each_key {|column| self.send("write_#{column}_identifier") }
33
+ end
34
+
35
+ def before_destroy
36
+ return false if super == false
37
+ self.class.uploaders.each_key {|column| self.send("remove_#{column}!") }
38
+ end
39
+ end
40
+
41
+ # Instance validation methods for the Sequel 3.x
42
+ module CarrierWave::Sequel::Validations
43
+ end
44
+
45
+ Sequel::Model.send(:extend, CarrierWave::Sequel)
@@ -0,0 +1,116 @@
1
+ # encoding: utf-8
2
+
3
+ require "image_science"
4
+
5
+ module CarrierWave
6
+ module ImageScience
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def resize_to_limit(width, height)
11
+ process :resize_to_limit => [width, height]
12
+ end
13
+
14
+ def resize_to_fit(width, height)
15
+ process :resize_to_fit => [width, height]
16
+ end
17
+
18
+ def resize_to_fill(width, height)
19
+ process :resize_to_fill => [width, height]
20
+ end
21
+ end
22
+
23
+ ##
24
+ # Resize the image to fit within the specified dimensions while retaining
25
+ # the original aspect ratio. The image may be shorter or narrower than
26
+ # specified in the smaller dimension but will not be larger than the
27
+ # specified values.
28
+ #
29
+ # See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fit
30
+ #
31
+ # === Parameters
32
+ #
33
+ # [width (Integer)] the width to scale the image to
34
+ # [height (Integer)] the height to scale the image to
35
+ #
36
+ def resize_to_fit(new_width, new_height)
37
+ ::ImageScience.with_image(self.current_path) do |img|
38
+ width, height = extract_dimensions(img.width, img.height, new_width, new_height)
39
+ img.resize( width, height ) do |file|
40
+ file.save( self.current_path )
41
+ end
42
+ end
43
+ end
44
+
45
+ ##
46
+ # Resize the image to fit within the specified dimensions while retaining
47
+ # the aspect ratio of the original image. If necessary, crop the image in
48
+ # the larger dimension.
49
+ #
50
+ # See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fill
51
+ #
52
+ # === Parameters
53
+ #
54
+ # [width (Integer)] the width to scale the image to
55
+ # [height (Integer)] the height to scale the image to
56
+ #
57
+ def resize_to_fill(new_width, new_height)
58
+ ::ImageScience.with_image(self.current_path) do |img|
59
+ width, height = extract_dimensions_for_crop(img.width, img.height, new_width, new_height)
60
+ x_offset, y_offset = extract_placement_for_crop(width, height, new_width, new_height)
61
+
62
+ img.resize( width, height ) do |i2|
63
+
64
+ i2.with_crop( x_offset, y_offset, new_width + x_offset, new_height + y_offset) do |file|
65
+ file.save( self.current_path )
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ ##
72
+ # Resize the image to fit within the specified dimensions while retaining
73
+ # the original aspect ratio. Will only resize the image if it is larger than the
74
+ # specified dimensions. The resulting image may be shorter or narrower than specified
75
+ # in the smaller dimension but will not be larger than the specified values.
76
+ #
77
+ # === Parameters
78
+ #
79
+ # [width (Integer)] the width to scale the image to
80
+ # [height (Integer)] the height to scale the image to
81
+ #
82
+ def resize_to_limit(new_width, new_height)
83
+ ::ImageScience.with_image(self.current_path) do |img|
84
+ if img.width > new_width or img.height > new_height
85
+ resize_to_fit(new_width, new_height)
86
+ end
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def extract_dimensions(width, height, new_width, new_height, type = :resize)
93
+ aspect_ratio = width.to_f / height.to_f
94
+ new_aspect_ratio = new_width / new_height
95
+
96
+ if (new_aspect_ratio > aspect_ratio) ^ ( type == :crop ) # Image is too wide, the caret is the XOR operator
97
+ new_width, new_height = [ (new_height * aspect_ratio), new_height]
98
+ else #Image is too narrow
99
+ new_width, new_height = [ new_width, (new_width / aspect_ratio)]
100
+ end
101
+
102
+ [new_width, new_height].collect! { |v| v.round }
103
+ end
104
+
105
+ def extract_dimensions_for_crop(width, height, new_width, new_height)
106
+ extract_dimensions(width, height, new_width, new_height, :crop)
107
+ end
108
+
109
+ def extract_placement_for_crop(width, height, new_width, new_height)
110
+ x_offset = (width / 2.0) - (new_width / 2.0)
111
+ y_offset = (height / 2.0) - (new_height / 2.0)
112
+ [x_offset, y_offset].collect! { |v| v.round }
113
+ end
114
+
115
+ end # ImageScience
116
+ end # CarrierWave
@@ -0,0 +1,261 @@
1
+ # encoding: utf-8
2
+
3
+ require 'mini_magick'
4
+
5
+ module CarrierWave
6
+
7
+ ##
8
+ # This module simplifies manipulation with MiniMagick by providing a set
9
+ # of convenient helper methods. If you want to use them, you'll need to
10
+ # require this file:
11
+ #
12
+ # require 'carrierwave/processing/mini_magick'
13
+ #
14
+ # And then include it in your uploader:
15
+ #
16
+ # class MyUploader < CarrierWave::Uploader::Base
17
+ # include CarrierWave::MiniMagick
18
+ # end
19
+ #
20
+ # You can now use the provided helpers:
21
+ #
22
+ # class MyUploader < CarrierWave::Uploader::Base
23
+ # include CarrierWave::MiniMagick
24
+ #
25
+ # process :resize_to_fit => [200, 200]
26
+ # end
27
+ #
28
+ # Or create your own helpers with the powerful manipulate! method. Check
29
+ # out the ImageMagick docs at http://www.imagemagick.org/script/command-line-options.php for more
30
+ # info
31
+ #
32
+ # class MyUploader < CarrierWave::Uploader::Base
33
+ # include CarrierWave::MiniMagick
34
+ #
35
+ # process :do_stuff => 10.0
36
+ #
37
+ # def do_stuff(blur_factor)
38
+ # manipulate! do |img|
39
+ # img = img.sepiatone
40
+ # img = img.auto_orient
41
+ # img = img.radial_blur blur_factor
42
+ # end
43
+ # end
44
+ # end
45
+ #
46
+ # === Note
47
+ #
48
+ # MiniMagick is a mini replacement for RMagick that uses the command line
49
+ # tool "mogrify" for image manipulation.
50
+ #
51
+ # You can find more information here:
52
+ #
53
+ # http://mini_magick.rubyforge.org/
54
+ # and
55
+ # http://github.com/probablycorey/mini_magick/
56
+ #
57
+ #
58
+ module MiniMagick
59
+ extend ActiveSupport::Concern
60
+
61
+ module ClassMethods
62
+ def convert(format)
63
+ process :convert => format
64
+ end
65
+
66
+ def resize_to_limit(width, height)
67
+ process :resize_to_limit => [width, height]
68
+ end
69
+
70
+ def resize_to_fit(width, height)
71
+ process :resize_to_fit => [width, height]
72
+ end
73
+
74
+ def resize_to_fill(width, height)
75
+ process :resize_to_fill => [width, height]
76
+ end
77
+
78
+ def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
79
+ process :resize_and_pad => [width, height, background, gravity]
80
+ end
81
+ end
82
+
83
+ ##
84
+ # Changes the image encoding format to the given format
85
+ #
86
+ # See http://www.imagemagick.org/script/command-line-options.php#format
87
+ #
88
+ # === Parameters
89
+ #
90
+ # [format (#to_s)] an abreviation of the format
91
+ #
92
+ # === Yields
93
+ #
94
+ # [MiniMagick::Image] additional manipulations to perform
95
+ #
96
+ # === Examples
97
+ #
98
+ # image.convert(:png)
99
+ #
100
+ def convert(format)
101
+ manipulate! do |img|
102
+ img.format(format.to_s.upcase)
103
+ img = yield(img) if block_given?
104
+ img
105
+ end
106
+ end
107
+
108
+ ##
109
+ # Resize the image to fit within the specified dimensions while retaining
110
+ # the original aspect ratio. Will only resize the image if it is larger than the
111
+ # specified dimensions. The resulting image may be shorter or narrower than specified
112
+ # in the smaller dimension but will not be larger than the specified values.
113
+ #
114
+ # === Parameters
115
+ #
116
+ # [width (Integer)] the width to scale the image to
117
+ # [height (Integer)] the height to scale the image to
118
+ #
119
+ # === Yields
120
+ #
121
+ # [MiniMagick::Image] additional manipulations to perform
122
+ #
123
+ def resize_to_limit(width, height)
124
+ manipulate! do |img|
125
+ img.resize "#{width}x#{height}>"
126
+ img = yield(img) if block_given?
127
+ img
128
+ end
129
+ end
130
+
131
+ ##
132
+ # From the RMagick documentation: "Resize the image to fit within the
133
+ # specified dimensions while retaining the original aspect ratio. The
134
+ # image may be shorter or narrower than specified in the smaller dimension
135
+ # but will not be larger than the specified values."
136
+ #
137
+ # See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fit
138
+ #
139
+ # === Parameters
140
+ #
141
+ # [width (Integer)] the width to scale the image to
142
+ # [height (Integer)] the height to scale the image to
143
+ #
144
+ # === Yields
145
+ #
146
+ # [MiniMagick::Image] additional manipulations to perform
147
+ #
148
+ def resize_to_fit(width, height)
149
+ manipulate! do |img|
150
+ img.resize "#{width}x#{height}"
151
+ img = yield(img) if block_given?
152
+ img
153
+ end
154
+ end
155
+
156
+ ##
157
+ # From the RMagick documentation: "Resize the image to fit within the
158
+ # specified dimensions while retaining the aspect ratio of the original
159
+ # image. If necessary, crop the image in the larger dimension."
160
+ #
161
+ # See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fill
162
+ #
163
+ # and
164
+ #
165
+ # http://www.clipclip.org/clips/detail/4365/jerrett-net-»-crop_resized-in-rmagick
166
+ #
167
+ # === Parameters
168
+ #
169
+ # [width (Integer)] the width to scale the image to
170
+ # [height (Integer)] the height to scale the image to
171
+ #
172
+ # === Yields
173
+ #
174
+ # [MiniMagick::Image] additional manipulations to perform
175
+ #
176
+ def resize_to_fill(width, height, gravity = 'Center')
177
+ manipulate! do |img|
178
+ cols, rows = img[:dimensions]
179
+ img.combine_options do |cmd|
180
+ if width != cols || height != rows
181
+ scale = [width/cols.to_f, height/rows.to_f].max
182
+ cols = (scale * (cols + 0.5)).round
183
+ rows = (scale * (rows + 0.5)).round
184
+ cmd.resize "#{cols}x#{rows}"
185
+ end
186
+ cmd.gravity gravity
187
+ cmd.extent "#{width}x#{height}" if cols != width || rows != height
188
+ end
189
+ img = yield(img) if block_given?
190
+ img
191
+ end
192
+ end
193
+
194
+ ##
195
+ # Resize the image to fit within the specified dimensions while retaining
196
+ # the original aspect ratio. If necessary, will pad the remaining area
197
+ # with the given color, which defaults to transparent (for gif and png,
198
+ # white for jpeg).
199
+ #
200
+ # See http://www.imagemagick.org/script/command-line-options.php#gravity
201
+ # for gravity options.
202
+ #
203
+ # === Parameters
204
+ #
205
+ # [width (Integer)] the width to scale the image to
206
+ # [height (Integer)] the height to scale the image to
207
+ # [background (String, :transparent)] the color of the background as a hexcode, like "#ff45de"
208
+ # [gravity (String)] how to position the image
209
+ #
210
+ # === Yields
211
+ #
212
+ # [MiniMagick::Image] additional manipulations to perform
213
+ #
214
+ def resize_and_pad(width, height, background=:transparent, gravity='Center')
215
+ manipulate! do |img|
216
+ img.combine_options do |cmd|
217
+ cmd.thumbnail "#{width}x#{height}>"
218
+ if background == :transparent
219
+ cmd.background "rgba(0, 0, 0, 0.0)"
220
+ else
221
+ cmd.background background
222
+ end
223
+ cmd.gravity gravity
224
+ cmd.extent "#{width}x#{height}"
225
+ end
226
+ img = yield(img) if block_given?
227
+ img
228
+ end
229
+ end
230
+
231
+ ##
232
+ # Manipulate the image with RMagick. This method will load up an image
233
+ # and then pass each of its frames to the supplied block. It will then
234
+ # save the image to disk.
235
+ #
236
+ # === Gotcha
237
+ #
238
+ # This method assumes that the object responds to +current_path+.
239
+ # Any class that this module is mixed into must have a +current_path+ method.
240
+ # CarrierWave::Uploader does, so you won't need to worry about this in
241
+ # most cases.
242
+ #
243
+ # === Yields
244
+ #
245
+ # [MiniMagick::Image] manipulations to perform
246
+ #
247
+ # === Raises
248
+ #
249
+ # [CarrierWave::ProcessingError] if manipulation failed.
250
+ #
251
+ def manipulate!
252
+ image = ::MiniMagick::Image.from_file(current_path)
253
+ image = yield(image)
254
+ image.write(current_path)
255
+ ::MiniMagick::Image.from_file(current_path)
256
+ rescue ::MiniMagick::MiniMagickError => e
257
+ raise CarrierWave::ProcessingError.new("Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: #{e}")
258
+ end
259
+
260
+ end # MiniMagick
261
+ end # CarrierWave