jnicklas-carrierwave 0.2.2 → 0.2.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.
- data/README.rdoc +35 -20
 - data/Rakefile +1 -1
 - data/lib/carrierwave/compatibility/paperclip.rb +91 -0
 - data/lib/carrierwave/core_ext/inheritable_attributes.rb +102 -0
 - data/lib/carrierwave/core_ext/module_setup.rb +49 -0
 - data/lib/carrierwave/mount.rb +119 -103
 - data/lib/carrierwave/orm/activerecord.rb +6 -1
 - data/lib/carrierwave/orm/sequel.rb +15 -2
 - data/lib/carrierwave/processing/rmagick.rb +8 -7
 - data/lib/carrierwave/storage/abstract.rb +16 -1
 - data/lib/carrierwave/storage/file.rb +20 -1
 - data/lib/carrierwave/uploader/cache.rb +114 -0
 - data/lib/carrierwave/uploader/callbacks.rb +40 -0
 - data/lib/carrierwave/uploader/default_path.rb +21 -0
 - data/lib/carrierwave/uploader/extension_whitelist.rb +35 -0
 - data/lib/carrierwave/uploader/mountable.rb +37 -0
 - data/lib/carrierwave/uploader/paths.rb +25 -0
 - data/lib/carrierwave/uploader/processing.rb +79 -0
 - data/lib/carrierwave/uploader/proxy.rb +60 -0
 - data/lib/carrierwave/uploader/remove.rb +21 -0
 - data/lib/carrierwave/uploader/store.rb +154 -0
 - data/lib/carrierwave/uploader/url.rb +22 -0
 - data/lib/carrierwave/uploader/versions.rb +145 -0
 - data/lib/carrierwave/uploader.rb +31 -593
 - data/lib/carrierwave.rb +55 -7
 - data/lib/generators/uploader_generator.rb +1 -1
 - data/rails_generators/uploader/templates/uploader.rb +12 -8
 - data/spec/compatibility/paperclip_spec.rb +41 -0
 - data/spec/mount_spec.rb +88 -25
 - data/spec/orm/activerecord_spec.rb +7 -9
 - data/spec/orm/datamapper_spec.rb +7 -9
 - data/spec/orm/sequel_spec.rb +47 -32
 - data/spec/spec_helper.rb +13 -0
 - data/spec/uploader/cache_spec.rb +194 -0
 - data/spec/uploader/default_path_spec.rb +66 -0
 - data/spec/uploader/extension_whitelist_spec.rb +42 -0
 - data/spec/uploader/mountable_spec.rb +31 -0
 - data/spec/uploader/paths_spec.rb +20 -0
 - data/spec/uploader/processing_spec.rb +60 -0
 - data/spec/uploader/proxy_spec.rb +52 -0
 - data/spec/uploader/remove_spec.rb +65 -0
 - data/spec/uploader/store_spec.rb +260 -0
 - data/spec/uploader/url_spec.rb +85 -0
 - data/spec/uploader/versions_spec.rb +275 -0
 - metadata +34 -3
 - data/spec/uploader_spec.rb +0 -887
 
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -36,9 +36,7 @@ this should give you a file in: 
     | 
|
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            Check out this file for some hints on how you can customize your uploader. It should look something like this:
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                class AvatarUploader
         
     | 
| 
       40 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 39 
     | 
    
         
            +
                class AvatarUploader < CarrierWave::Uploader::Base
         
     | 
| 
       42 
40 
     | 
    
         
             
                  storage :file
         
     | 
| 
       43 
41 
     | 
    
         
             
                end
         
     | 
| 
       44 
42 
     | 
    
         | 
| 
         @@ -97,9 +95,7 @@ Now you can cache files by assigning them to the attribute, they will automatica 
     | 
|
| 
       97 
95 
     | 
    
         | 
| 
       98 
96 
     | 
    
         
             
            In order to change where uploaded files are put, just override the +store_dir+ method:
         
     | 
| 
       99 
97 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
                class MyUploader
         
     | 
| 
       101 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
      
 98 
     | 
    
         
            +
                class MyUploader < CarrierWave::Uploader::Base
         
     | 
| 
       103 
99 
     | 
    
         
             
                  def store_dir
         
     | 
| 
       104 
100 
     | 
    
         
             
                    'public/my/upload/directory'
         
     | 
| 
       105 
101 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -111,10 +107,9 @@ This works for the file storage as well as Amazon S3. 
     | 
|
| 
       111 
107 
     | 
    
         | 
| 
       112 
108 
     | 
    
         
             
            Often you'll want to add different versions of the same file. The classic example is image thumbnails. There is built in support for this:
         
     | 
| 
       113 
109 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                class MyUploader
         
     | 
| 
       115 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
      
 110 
     | 
    
         
            +
                class MyUploader < CarrierWave::Uploader::Base
         
     | 
| 
       116 
111 
     | 
    
         
             
                  include CarrierWave::RMagick
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
       118 
113 
     | 
    
         
             
                  process :resize => [800, 800]
         
     | 
| 
       119 
114 
     | 
    
         | 
| 
       120 
115 
     | 
    
         
             
                  version :thumb do
         
     | 
| 
         @@ -135,8 +130,7 @@ One important thing to remember is that process is called *before* versions are 
     | 
|
| 
       135 
130 
     | 
    
         | 
| 
       136 
131 
     | 
    
         
             
            It is possible to nest versions within versions:
         
     | 
| 
       137 
132 
     | 
    
         | 
| 
       138 
     | 
    
         
            -
                class MyUploader
         
     | 
| 
       139 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
      
 133 
     | 
    
         
            +
                class MyUploader < CarrierWave::Uploader::Base
         
     | 
| 
       140 
134 
     | 
    
         | 
| 
       141 
135 
     | 
    
         
             
                  version :animal do
         
     | 
| 
       142 
136 
     | 
    
         
             
                    version :human
         
     | 
| 
         @@ -174,6 +168,16 @@ in the case of images, a small thumbnail would be a good indicator: 
     | 
|
| 
       174 
168 
     | 
    
         | 
| 
       175 
169 
     | 
    
         
             
            NOTE: this feature currently requires write access to your filesystem. If write access is unavailable (e.g. Heroku) you will not be able to upload files. You can prevent CarrierWave from writing to the file system by setting `CarrierWave.config[:cache_to_cache_dir] = false`. This will however break redisplays of forms.
         
     | 
| 
       176 
170 
     | 
    
         | 
| 
      
 171 
     | 
    
         
            +
            == Providing a default path
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            In many cases, especially when working with images, it might be a good idea to provide a default path, a fallback in case no file has been uploaded. You can do this easily by overriding the +default_path+ method in your uploader:
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                class MyUploader < CarrierWave::Uploader::Base
         
     | 
| 
      
 176 
     | 
    
         
            +
                  def default_path
         
     | 
| 
      
 177 
     | 
    
         
            +
                    "images/fallback/" + [version_name, "default.png"].compact.join('_')
         
     | 
| 
      
 178 
     | 
    
         
            +
                  end
         
     | 
| 
      
 179 
     | 
    
         
            +
                end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
       177 
181 
     | 
    
         
             
            == Using Amazon S3
         
     | 
| 
       178 
182 
     | 
    
         | 
| 
       179 
183 
     | 
    
         
             
            You'll need to configure a bucket, access id and secret key like this:
         
     | 
| 
         @@ -186,9 +190,7 @@ Do this in an initializer in Rails, and in a +before_app_loads+ block in Merb. 
     | 
|
| 
       186 
190 
     | 
    
         | 
| 
       187 
191 
     | 
    
         
             
            And then in your uploader, set the storage to :s3
         
     | 
| 
       188 
192 
     | 
    
         | 
| 
       189 
     | 
    
         
            -
                class AvatarUploader
         
     | 
| 
       190 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
      
 193 
     | 
    
         
            +
                class AvatarUploader < 
         
     | 
| 
       192 
194 
     | 
    
         
             
                  storage :s3
         
     | 
| 
       193 
195 
     | 
    
         
             
                end
         
     | 
| 
       194 
196 
     | 
    
         | 
| 
         @@ -198,15 +200,13 @@ That's it! You can still use the +CarrierWave::Uploader#url+ method to return th 
     | 
|
| 
       198 
200 
     | 
    
         | 
| 
       199 
201 
     | 
    
         
             
            If you're uploading images, you'll probably want to manipulate them in some way, you might want to create thumbnail images for example. CarrierWave comes with a small library to make manipulating images with RMagick easier, you'll need to include it in your Uploader:
         
     | 
| 
       200 
202 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
                class AvatarUploader
         
     | 
| 
       202 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
      
 203 
     | 
    
         
            +
                class AvatarUploader < CarrierWave::Uploader::Base
         
     | 
| 
       203 
204 
     | 
    
         
             
                  include CarrierWave::RMagick
         
     | 
| 
       204 
205 
     | 
    
         
             
                end
         
     | 
| 
       205 
206 
     | 
    
         | 
| 
       206 
207 
     | 
    
         
             
            The RMagick module gives you a few methods, like +CarrierWave::RMagick#crop_resized+ which manipulate the image file in some way. You can set a +process+ callback, which will call that method any time a file is uploaded.
         
     | 
| 
       207 
208 
     | 
    
         | 
| 
       208 
     | 
    
         
            -
                class AvatarUploader
         
     | 
| 
       209 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
      
 209 
     | 
    
         
            +
                class AvatarUploader < CarrierWave::Uploader::Base
         
     | 
| 
       210 
210 
     | 
    
         
             
                  include CarrierWave::RMagick
         
     | 
| 
       211 
211 
     | 
    
         | 
| 
       212 
212 
     | 
    
         
             
                  process :crop_resized => [200, 200]
         
     | 
| 
         @@ -223,13 +223,28 @@ Check out the manipulate! method, which makes it easy for you to write your own 
     | 
|
| 
       223 
223 
     | 
    
         | 
| 
       224 
224 
     | 
    
         
             
            ImageScience works the same way as RMagick.
         
     | 
| 
       225 
225 
     | 
    
         | 
| 
       226 
     | 
    
         
            -
                class AvatarUploader
         
     | 
| 
       227 
     | 
    
         
            -
                  include CarrierWave::Uploader
         
     | 
| 
      
 226 
     | 
    
         
            +
                class AvatarUploader < CarrierWave::Uploader::Base
         
     | 
| 
       228 
227 
     | 
    
         
             
                  include CarrierWave::ImageScience
         
     | 
| 
       229 
228 
     | 
    
         | 
| 
       230 
229 
     | 
    
         
             
                  process :crop_resized => [200, 200]
         
     | 
| 
       231 
230 
     | 
    
         
             
                end
         
     | 
| 
       232 
231 
     | 
    
         | 
| 
      
 232 
     | 
    
         
            +
            == Migrating
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
            If you are using Paperclip, you can use the provided compatibility module:
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                class AvatarUploader < CarrierWave::Uploader::Base
         
     | 
| 
      
 237 
     | 
    
         
            +
                  include CarrierWave::Compatibility::Paperclip
         
     | 
| 
      
 238 
     | 
    
         
            +
                end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
            See the documentation for +Paperclip::Compatibility::Paperclip+ for more detaills.
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
            Be sure to use mount_on to specify the correct column:
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                mount_uploader :avatar, AvatarUploader, :mount_on => :avatar_file_name
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
            Unfortunately AttachmentFoo differs too much in philosophy for there to be a sensible compatibility mode. Patches for migrating from other solutions will be happily accepted.
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
       233 
248 
     | 
    
         
             
            == Documentation
         
     | 
| 
       234 
249 
     | 
    
         | 
| 
       235 
250 
     | 
    
         
             
            Full rdoc documentation is {available at Rubyforge}[http://carrierwave.rubyforge.org/].
         
     | 
    
        data/Rakefile
    CHANGED
    
    
| 
         @@ -0,0 +1,91 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # This file contains code taken from Paperclip
         
     | 
| 
      
 2 
     | 
    
         
            +
            # 
         
     | 
| 
      
 3 
     | 
    
         
            +
            # LICENSE
         
     | 
| 
      
 4 
     | 
    
         
            +
            # 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # The MIT License
         
     | 
| 
      
 6 
     | 
    
         
            +
            # 
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Copyright (c) 2008 Jon Yurek and thoughtbot, inc.
         
     | 
| 
      
 8 
     | 
    
         
            +
            # 
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 10 
     | 
    
         
            +
            # of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 11 
     | 
    
         
            +
            # in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 12 
     | 
    
         
            +
            # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 13 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 14 
     | 
    
         
            +
            # furnished to do so, subject to the following conditions:
         
     | 
| 
      
 15 
     | 
    
         
            +
            # 
         
     | 
| 
      
 16 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 17 
     | 
    
         
            +
            # all copies or substantial portions of the Software.
         
     | 
| 
      
 18 
     | 
    
         
            +
            # 
         
     | 
| 
      
 19 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 20 
     | 
    
         
            +
            # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 21 
     | 
    
         
            +
            # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 22 
     | 
    
         
            +
            # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 23 
     | 
    
         
            +
            # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 24 
     | 
    
         
            +
            # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 25 
     | 
    
         
            +
            # THE SOFTWARE.
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            module CarrierWave
         
     | 
| 
      
 28 
     | 
    
         
            +
              module Compatibility
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                ##
         
     | 
| 
      
 31 
     | 
    
         
            +
                # Mix this module into an Uploader to make it mimic Paperclip's storage paths
         
     | 
| 
      
 32 
     | 
    
         
            +
                # This will make your Uploader use the same default storage path as paperclip
         
     | 
| 
      
 33 
     | 
    
         
            +
                # does. If you need to override it, you can override the +paperclip_path+ method
         
     | 
| 
      
 34 
     | 
    
         
            +
                # and provide a Paperclip style path:
         
     | 
| 
      
 35 
     | 
    
         
            +
                #
         
     | 
| 
      
 36 
     | 
    
         
            +
                #     class MyUploader < CarrierWave::Uploader::Base
         
     | 
| 
      
 37 
     | 
    
         
            +
                #       include CarrierWave::Compatibility::Paperclip
         
     | 
| 
      
 38 
     | 
    
         
            +
                #       
         
     | 
| 
      
 39 
     | 
    
         
            +
                #       def paperclip_path
         
     | 
| 
      
 40 
     | 
    
         
            +
                #         ":rails_root/public/uploads/:id/:attachment/:style_:basename.:extension"
         
     | 
| 
      
 41 
     | 
    
         
            +
                #       end
         
     | 
| 
      
 42 
     | 
    
         
            +
                #     end
         
     | 
| 
      
 43 
     | 
    
         
            +
                #
         
     | 
| 
      
 44 
     | 
    
         
            +
                module Paperclip
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def store_path(for_file=filename)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    path = paperclip_path
         
     | 
| 
      
 48 
     | 
    
         
            +
                    path ||= File.join(*[store_dir, paperclip_style.to_s, for_file].compact)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    interpolate_paperclip_path(path, for_file)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def store_dir
         
     | 
| 
      
 53 
     | 
    
         
            +
                    ":rails_root/public/system/:attachment/:id"
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def paperclip_default_style
         
     | 
| 
      
 57 
     | 
    
         
            +
                    :original
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  def paperclip_path
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  def paperclip_style
         
     | 
| 
      
 64 
     | 
    
         
            +
                    version_name || paperclip_default_style
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                private
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  def interpolate_paperclip_path(path, filename)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    mappings.inject(path) do |agg, pair|
         
     | 
| 
      
 71 
     | 
    
         
            +
                      agg.gsub(":#{pair[0]}", pair[1].call(self, filename).to_s)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    end
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  def mappings
         
     | 
| 
      
 76 
     | 
    
         
            +
                    {
         
     | 
| 
      
 77 
     | 
    
         
            +
                      :rails_root   => lambda{|u, f| CarrierWave.config[:root] },
         
     | 
| 
      
 78 
     | 
    
         
            +
                      :rails_env    => lambda{|u, f| CarrierWave.config[:env] },
         
     | 
| 
      
 79 
     | 
    
         
            +
                      :class        => lambda{|u, f| u.model.class.name.underscore.pluralize},
         
     | 
| 
      
 80 
     | 
    
         
            +
                      :id           => lambda{|u, f| u.model.id },
         
     | 
| 
      
 81 
     | 
    
         
            +
                      :id_partition => lambda{|u, f| ("%09d" % u.model.id).scan(/\d{3}/).join("/")},
         
     | 
| 
      
 82 
     | 
    
         
            +
                      :attachment   => lambda{|u, f| u.mounted_as.to_s.downcase.pluralize },
         
     | 
| 
      
 83 
     | 
    
         
            +
                      :style        => lambda{|u, f| u.paperclip_style },
         
     | 
| 
      
 84 
     | 
    
         
            +
                      :basename     => lambda{|u, f| f.gsub(/#{File.extname(f)}$/, "") },
         
     | 
| 
      
 85 
     | 
    
         
            +
                      :extension    => lambda{|u, f| File.extname(f).gsub(/^\.+/, "")}
         
     | 
| 
      
 86 
     | 
    
         
            +
                    }
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                end # Paperclip
         
     | 
| 
      
 90 
     | 
    
         
            +
              end # Compatibility
         
     | 
| 
      
 91 
     | 
    
         
            +
            end # CarrierWave
         
     | 
| 
         @@ -0,0 +1,102 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Stolen from Rails 3
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Copyright (c) 2005-2009 David Heinemeier Hansson
         
     | 
| 
      
 4 
     | 
    
         
            +
            # 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 6 
     | 
    
         
            +
            # a copy of this software and associated documentation files (the
         
     | 
| 
      
 7 
     | 
    
         
            +
            # "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 8 
     | 
    
         
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 9 
     | 
    
         
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 10 
     | 
    
         
            +
            # permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 11 
     | 
    
         
            +
            # the following conditions:
         
     | 
| 
      
 12 
     | 
    
         
            +
            # 
         
     | 
| 
      
 13 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 14 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 15 
     | 
    
         
            +
            # 
         
     | 
| 
      
 16 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 17 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 18 
     | 
    
         
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 20 
     | 
    
         
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 21 
     | 
    
         
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 22 
     | 
    
         
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            # Retain for backward compatibility.  Methods are now included in Class.
         
     | 
| 
      
 25 
     | 
    
         
            +
            class Class
         
     | 
| 
      
 26 
     | 
    
         
            +
              # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
         
     | 
| 
      
 27 
     | 
    
         
            +
              # each subclass has a copy of parent's attribute.
         
     | 
| 
      
 28 
     | 
    
         
            +
              #
         
     | 
| 
      
 29 
     | 
    
         
            +
              # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
         
     | 
| 
      
 30 
     | 
    
         
            +
              # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
         
     | 
| 
      
 31 
     | 
    
         
            +
              #
         
     | 
| 
      
 32 
     | 
    
         
            +
              # @api public
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              # @todo Do we want to block instance_reader via :instance_reader => false
         
     | 
| 
      
 35 
     | 
    
         
            +
              # @todo It would be preferable that we do something with a Hash passed in
         
     | 
| 
      
 36 
     | 
    
         
            +
              #   (error out or do the same as other methods above) instead of silently
         
     | 
| 
      
 37 
     | 
    
         
            +
              #   moving on). In particular, this makes the return value of this function
         
     | 
| 
      
 38 
     | 
    
         
            +
              #   less useful.
         
     | 
| 
      
 39 
     | 
    
         
            +
              def extlib_inheritable_reader(*ivars)
         
     | 
| 
      
 40 
     | 
    
         
            +
                instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                ivars.each do |ivar|
         
     | 
| 
      
 43 
     | 
    
         
            +
                  self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
      
 44 
     | 
    
         
            +
                    def self.#{ivar}
         
     | 
| 
      
 45 
     | 
    
         
            +
                      return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
         
     | 
| 
      
 46 
     | 
    
         
            +
                      ivar = superclass.#{ivar}
         
     | 
| 
      
 47 
     | 
    
         
            +
                      return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
         
     | 
| 
      
 48 
     | 
    
         
            +
                      @#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) && !ivar.is_a?(TrueClass) && !ivar.is_a?(FalseClass) ? ivar.dup : ivar
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  RUBY
         
     | 
| 
      
 51 
     | 
    
         
            +
                  unless instance_reader == false
         
     | 
| 
      
 52 
     | 
    
         
            +
                    self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
      
 53 
     | 
    
         
            +
                      def #{ivar}
         
     | 
| 
      
 54 
     | 
    
         
            +
                        self.class.#{ivar}
         
     | 
| 
      
 55 
     | 
    
         
            +
                      end
         
     | 
| 
      
 56 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
         
     | 
| 
      
 62 
     | 
    
         
            +
              # each subclass has a copy of parent's attribute.
         
     | 
| 
      
 63 
     | 
    
         
            +
              #
         
     | 
| 
      
 64 
     | 
    
         
            +
              # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
         
     | 
| 
      
 65 
     | 
    
         
            +
              #   define inheritable writer for.
         
     | 
| 
      
 66 
     | 
    
         
            +
              # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
         
     | 
| 
      
 67 
     | 
    
         
            +
              # @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
         
     | 
| 
      
 68 
     | 
    
         
            +
              #
         
     | 
| 
      
 69 
     | 
    
         
            +
              # @api public
         
     | 
| 
      
 70 
     | 
    
         
            +
              #
         
     | 
| 
      
 71 
     | 
    
         
            +
              # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
         
     | 
| 
      
 72 
     | 
    
         
            +
              #   class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
         
     | 
| 
      
 73 
     | 
    
         
            +
              def extlib_inheritable_writer(*ivars)
         
     | 
| 
      
 74 
     | 
    
         
            +
                instance_writer = ivars.pop[:writer] if ivars.last.is_a?(Hash)
         
     | 
| 
      
 75 
     | 
    
         
            +
                ivars.each do |ivar|
         
     | 
| 
      
 76 
     | 
    
         
            +
                  self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
      
 77 
     | 
    
         
            +
                    def self.#{ivar}=(obj)
         
     | 
| 
      
 78 
     | 
    
         
            +
                      @#{ivar} = obj
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                  RUBY
         
     | 
| 
      
 81 
     | 
    
         
            +
                  unless instance_writer == false
         
     | 
| 
      
 82 
     | 
    
         
            +
                    self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
      
 83 
     | 
    
         
            +
                      def #{ivar}=(obj) self.class.#{ivar} = obj end
         
     | 
| 
      
 84 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
              # Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
         
     | 
| 
      
 90 
     | 
    
         
            +
              # each subclass has a copy of parent's attribute.
         
     | 
| 
      
 91 
     | 
    
         
            +
              #
         
     | 
| 
      
 92 
     | 
    
         
            +
              # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
         
     | 
| 
      
 93 
     | 
    
         
            +
              #   define inheritable accessor for.
         
     | 
| 
      
 94 
     | 
    
         
            +
              # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
         
     | 
| 
      
 95 
     | 
    
         
            +
              # @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
         
     | 
| 
      
 96 
     | 
    
         
            +
              #
         
     | 
| 
      
 97 
     | 
    
         
            +
              # @api public
         
     | 
| 
      
 98 
     | 
    
         
            +
              def extlib_inheritable_accessor(*syms)
         
     | 
| 
      
 99 
     | 
    
         
            +
                extlib_inheritable_reader(*syms)
         
     | 
| 
      
 100 
     | 
    
         
            +
                extlib_inheritable_writer(*syms)
         
     | 
| 
      
 101 
     | 
    
         
            +
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Stolen from Rails 3
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Copyright (c) 2005-2009 David Heinemeier Hansson
         
     | 
| 
      
 4 
     | 
    
         
            +
            # 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 6 
     | 
    
         
            +
            # a copy of this software and associated documentation files (the
         
     | 
| 
      
 7 
     | 
    
         
            +
            # "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 8 
     | 
    
         
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 9 
     | 
    
         
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 10 
     | 
    
         
            +
            # permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 11 
     | 
    
         
            +
            # the following conditions:
         
     | 
| 
      
 12 
     | 
    
         
            +
            # 
         
     | 
| 
      
 13 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 14 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 15 
     | 
    
         
            +
            # 
         
     | 
| 
      
 16 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 17 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 18 
     | 
    
         
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 20 
     | 
    
         
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 21 
     | 
    
         
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 22 
     | 
    
         
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            class Module
         
     | 
| 
      
 25 
     | 
    
         
            +
              attr_accessor :_setup_block
         
     | 
| 
      
 26 
     | 
    
         
            +
              attr_accessor :_dependencies
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
              def setup(&blk)
         
     | 
| 
      
 29 
     | 
    
         
            +
                @_setup_block = blk
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              def use(mod)
         
     | 
| 
      
 33 
     | 
    
         
            +
                return if self < mod
         
     | 
| 
      
 34 
     | 
    
         
            +
                
         
     | 
| 
      
 35 
     | 
    
         
            +
                (mod._dependencies || []).each do |dep|
         
     | 
| 
      
 36 
     | 
    
         
            +
                  use dep
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
                # raise "Circular dependencies" if self < mod
         
     | 
| 
      
 39 
     | 
    
         
            +
                include mod
         
     | 
| 
      
 40 
     | 
    
         
            +
                extend mod.const_get("ClassMethods") if mod.const_defined?("ClassMethods")
         
     | 
| 
      
 41 
     | 
    
         
            +
                class_eval(&mod._setup_block) if mod._setup_block
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
              
         
     | 
| 
      
 44 
     | 
    
         
            +
              def depends_on(mod)
         
     | 
| 
      
 45 
     | 
    
         
            +
                return if self < mod
         
     | 
| 
      
 46 
     | 
    
         
            +
                @_dependencies ||= []
         
     | 
| 
      
 47 
     | 
    
         
            +
                @_dependencies << mod
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/carrierwave/mount.rb
    CHANGED
    
    | 
         @@ -70,6 +70,7 @@ module CarrierWave 
     | 
|
| 
       70 
70 
     | 
    
         
             
                # [remove_image?]           Whether the file should be removed when store_image! is called.
         
     | 
| 
       71 
71 
     | 
    
         
             
                #
         
     | 
| 
       72 
72 
     | 
    
         
             
                # [store_image!]            Stores a file that has been assigned with +image=+
         
     | 
| 
      
 73 
     | 
    
         
            +
                # [remove_image!]           Removes the uploaded file from the filesystem.
         
     | 
| 
       73 
74 
     | 
    
         
             
                #
         
     | 
| 
       74 
75 
     | 
    
         
             
                # [image_integrity_error]   Returns an error object if the last file to be assigned caused an integrty error
         
     | 
| 
       75 
76 
     | 
    
         
             
                # [image_processing_error]  Returns an error object if the last file to be assigned caused a processing error
         
     | 
| 
         @@ -115,9 +116,7 @@ module CarrierWave 
     | 
|
| 
       115 
116 
     | 
    
         
             
                #
         
     | 
| 
       116 
117 
     | 
    
         
             
                def mount_uploader(column, uploader=nil, options={}, &block)
         
     | 
| 
       117 
118 
     | 
    
         
             
                  unless uploader
         
     | 
| 
       118 
     | 
    
         
            -
                    uploader = Class.new 
     | 
| 
       119 
     | 
    
         
            -
                      include CarrierWave::Uploader
         
     | 
| 
       120 
     | 
    
         
            -
                    end
         
     | 
| 
      
 119 
     | 
    
         
            +
                    uploader = Class.new(CarrierWave::Uploader::Base)
         
     | 
| 
       121 
120 
     | 
    
         
             
                    uploader.class_eval(&block)
         
     | 
| 
       122 
121 
     | 
    
         
             
                  end
         
     | 
| 
       123 
122 
     | 
    
         | 
| 
         @@ -127,58 +126,68 @@ module CarrierWave 
     | 
|
| 
       127 
126 
     | 
    
         
             
                  include CarrierWave::Mount::Extension
         
     | 
| 
       128 
127 
     | 
    
         | 
| 
       129 
128 
     | 
    
         
             
                  class_eval <<-RUBY, __FILE__, __LINE__+1
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                    def #{column}
         
     | 
| 
      
 131 
     | 
    
         
            +
                      _mounter(:#{column}).uploader
         
     | 
| 
      
 132 
     | 
    
         
            +
                    end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                    def #{column}=(new_file)
         
     | 
| 
      
 135 
     | 
    
         
            +
                      _mounter(:#{column}).cache(new_file)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                    def #{column}?
         
     | 
| 
      
 139 
     | 
    
         
            +
                      !_mounter(:#{column}).blank?
         
     | 
| 
      
 140 
     | 
    
         
            +
                    end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                    def #{column}_url(*args)
         
     | 
| 
      
 143 
     | 
    
         
            +
                      _mounter(:#{column}).url(*args)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                    def #{column}_uploader
         
     | 
| 
      
 147 
     | 
    
         
            +
                      _mounter(:#{column}).uploader
         
     | 
| 
      
 148 
     | 
    
         
            +
                    end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                    def #{column}_uploader=(uploader)
         
     | 
| 
      
 151 
     | 
    
         
            +
                      _mounter(:#{column}).uploader = uploader
         
     | 
| 
      
 152 
     | 
    
         
            +
                    end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                    def #{column}_cache
         
     | 
| 
      
 155 
     | 
    
         
            +
                      _mounter(:#{column}).cache_name
         
     | 
| 
      
 156 
     | 
    
         
            +
                    end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                    def #{column}_cache=(cache_name)
         
     | 
| 
      
 159 
     | 
    
         
            +
                      _mounter(:#{column}).cache_name = cache_name
         
     | 
| 
      
 160 
     | 
    
         
            +
                    end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                    def remove_#{column}
         
     | 
| 
      
 163 
     | 
    
         
            +
                      _mounter(:#{column}).remove
         
     | 
| 
      
 164 
     | 
    
         
            +
                    end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                    def remove_#{column}!
         
     | 
| 
      
 167 
     | 
    
         
            +
                      _mounter(:#{column}).remove!
         
     | 
| 
      
 168 
     | 
    
         
            +
                    end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                    def remove_#{column}=(value)
         
     | 
| 
      
 171 
     | 
    
         
            +
                      _mounter(:#{column}).remove = value
         
     | 
| 
      
 172 
     | 
    
         
            +
                    end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                    def remove_#{column}?
         
     | 
| 
      
 175 
     | 
    
         
            +
                      _mounter(:#{column}).remove?
         
     | 
| 
      
 176 
     | 
    
         
            +
                    end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                    def store_#{column}!
         
     | 
| 
      
 179 
     | 
    
         
            +
                      _mounter(:#{column}).store!
         
     | 
| 
      
 180 
     | 
    
         
            +
                    end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                    def #{column}_integrity_error
         
     | 
| 
      
 183 
     | 
    
         
            +
                      _mounter(:#{column}).integrity_error
         
     | 
| 
      
 184 
     | 
    
         
            +
                    end
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                    def #{column}_processing_error
         
     | 
| 
      
 187 
     | 
    
         
            +
                      _mounter(:#{column}).processing_error
         
     | 
| 
      
 188 
     | 
    
         
            +
                    end
         
     | 
| 
       181 
189 
     | 
    
         
             
                  RUBY
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
       182 
191 
     | 
    
         
             
                end
         
     | 
| 
       183 
192 
     | 
    
         | 
| 
       184 
193 
     | 
    
         
             
                module Extension
         
     | 
| 
         @@ -195,85 +204,92 @@ module CarrierWave 
     | 
|
| 
       195 
204 
     | 
    
         | 
| 
       196 
205 
     | 
    
         
             
                private
         
     | 
| 
       197 
206 
     | 
    
         | 
| 
       198 
     | 
    
         
            -
                  def  
     | 
| 
       199 
     | 
    
         
            -
                    @ 
     | 
| 
       200 
     | 
    
         
            -
                    @ 
     | 
| 
      
 207 
     | 
    
         
            +
                  def _mounter(column)
         
     | 
| 
      
 208 
     | 
    
         
            +
                    @_mounters ||= {}
         
     | 
| 
      
 209 
     | 
    
         
            +
                    @_mounters[column] ||= Mounter.new(self, column)
         
     | 
| 
       201 
210 
     | 
    
         
             
                  end
         
     | 
| 
       202 
211 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
                    @_uploaders ||= {}
         
     | 
| 
       205 
     | 
    
         
            -
                    @_uploaders[column] = uploader
         
     | 
| 
       206 
     | 
    
         
            -
                  end
         
     | 
| 
      
 212 
     | 
    
         
            +
                end # Extension
         
     | 
| 
       207 
213 
     | 
    
         | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
      
 214 
     | 
    
         
            +
                # this is an internal class, used by CarrierWave::Mount so that
         
     | 
| 
      
 215 
     | 
    
         
            +
                # we don't pollute the model with a lot of methods.
         
     | 
| 
      
 216 
     | 
    
         
            +
                class Mounter #:nodoc:
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                  attr_reader :column, :record, :options
         
     | 
| 
       211 
219 
     | 
    
         | 
| 
       212 
     | 
    
         
            -
                   
     | 
| 
       213 
     | 
    
         
            -
                    return _uploader_get(column) unless _uploader_get(column).blank?
         
     | 
| 
      
 220 
     | 
    
         
            +
                  attr_accessor :uploader, :integrity_error, :processing_error, :remove
         
     | 
| 
       214 
221 
     | 
    
         | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
      
 222 
     | 
    
         
            +
                  def initialize(record, column, options={})
         
     | 
| 
      
 223 
     | 
    
         
            +
                    @record = record
         
     | 
| 
      
 224 
     | 
    
         
            +
                    @column = column
         
     | 
| 
      
 225 
     | 
    
         
            +
                    @options = record.class.uploader_options[column]
         
     | 
| 
      
 226 
     | 
    
         
            +
                  end
         
     | 
| 
       216 
227 
     | 
    
         | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
             
     | 
| 
      
 228 
     | 
    
         
            +
                  def uploader
         
     | 
| 
      
 229 
     | 
    
         
            +
                    @uploader ||= record.class.uploaders[column].new(record, column)
         
     | 
| 
      
 230 
     | 
    
         
            +
                    if @uploader.blank?
         
     | 
| 
      
 231 
     | 
    
         
            +
                      identifier = record.read_uploader(serialization_column)
         
     | 
| 
      
 232 
     | 
    
         
            +
                      @uploader.retrieve_from_store!(identifier) unless identifier.blank?
         
     | 
| 
       220 
233 
     | 
    
         
             
                    end
         
     | 
| 
      
 234 
     | 
    
         
            +
                    return @uploader
         
     | 
| 
       221 
235 
     | 
    
         
             
                  end
         
     | 
| 
       222 
236 
     | 
    
         | 
| 
       223 
     | 
    
         
            -
                  def  
     | 
| 
       224 
     | 
    
         
            -
                     
     | 
| 
       225 
     | 
    
         
            -
                     
     | 
| 
       226 
     | 
    
         
            -
                     
     | 
| 
      
 237 
     | 
    
         
            +
                  def cache(new_file)
         
     | 
| 
      
 238 
     | 
    
         
            +
                    uploader.cache!(new_file)
         
     | 
| 
      
 239 
     | 
    
         
            +
                    self.integrity_error = nil
         
     | 
| 
      
 240 
     | 
    
         
            +
                    self.processing_error = nil
         
     | 
| 
       227 
241 
     | 
    
         
             
                  rescue CarrierWave::IntegrityError => e
         
     | 
| 
       228 
     | 
    
         
            -
                     
     | 
| 
       229 
     | 
    
         
            -
                    raise e unless  
     | 
| 
      
 242 
     | 
    
         
            +
                    self.integrity_error = e
         
     | 
| 
      
 243 
     | 
    
         
            +
                    raise e unless options[:ignore_integrity_errors]
         
     | 
| 
       230 
244 
     | 
    
         
             
                  rescue CarrierWave::ProcessingError => e
         
     | 
| 
       231 
     | 
    
         
            -
                     
     | 
| 
       232 
     | 
    
         
            -
                    raise e unless  
     | 
| 
       233 
     | 
    
         
            -
                  end
         
     | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
       235 
     | 
    
         
            -
                  def _uploader_get_url(column, *args)
         
     | 
| 
       236 
     | 
    
         
            -
                    _uploader_get_column(column)
         
     | 
| 
       237 
     | 
    
         
            -
                    _uploader_get(column).url(*args)
         
     | 
| 
      
 245 
     | 
    
         
            +
                    self.processing_error = e
         
     | 
| 
      
 246 
     | 
    
         
            +
                    raise e unless options[:ignore_processing_errors]
         
     | 
| 
       238 
247 
     | 
    
         
             
                  end
         
     | 
| 
       239 
248 
     | 
    
         | 
| 
       240 
     | 
    
         
            -
                  def  
     | 
| 
       241 
     | 
    
         
            -
                     
     | 
| 
      
 249 
     | 
    
         
            +
                  def cache_name
         
     | 
| 
      
 250 
     | 
    
         
            +
                    uploader.cache_name
         
     | 
| 
       242 
251 
     | 
    
         
             
                  end
         
     | 
| 
       243 
252 
     | 
    
         | 
| 
       244 
     | 
    
         
            -
                  def  
     | 
| 
       245 
     | 
    
         
            -
                     
     | 
| 
      
 253 
     | 
    
         
            +
                  def cache_name=(cache_name)
         
     | 
| 
      
 254 
     | 
    
         
            +
                    uploader.retrieve_from_cache!(cache_name) unless uploader.cached?
         
     | 
| 
      
 255 
     | 
    
         
            +
                  rescue CarrierWave::InvalidParameter
         
     | 
| 
       246 
256 
     | 
    
         
             
                  end
         
     | 
| 
       247 
257 
     | 
    
         | 
| 
       248 
     | 
    
         
            -
                  def  
     | 
| 
       249 
     | 
    
         
            -
                    unless  
     | 
| 
       250 
     | 
    
         
            -
                      if  
     | 
| 
       251 
     | 
    
         
            -
                         
     | 
| 
       252 
     | 
    
         
            -
                        write_uploader( 
     | 
| 
      
 258 
     | 
    
         
            +
                  def store!
         
     | 
| 
      
 259 
     | 
    
         
            +
                    unless uploader.blank?
         
     | 
| 
      
 260 
     | 
    
         
            +
                      if remove?
         
     | 
| 
      
 261 
     | 
    
         
            +
                        uploader.remove!
         
     | 
| 
      
 262 
     | 
    
         
            +
                        record.write_uploader(serialization_column, '')
         
     | 
| 
       253 
263 
     | 
    
         
             
                      else
         
     | 
| 
       254 
     | 
    
         
            -
                         
     | 
| 
       255 
     | 
    
         
            -
                        write_uploader( 
     | 
| 
      
 264 
     | 
    
         
            +
                        uploader.store!
         
     | 
| 
      
 265 
     | 
    
         
            +
                        record.write_uploader(serialization_column, uploader.identifier)
         
     | 
| 
       256 
266 
     | 
    
         
             
                      end
         
     | 
| 
       257 
267 
     | 
    
         
             
                    end
         
     | 
| 
       258 
268 
     | 
    
         
             
                  end
         
     | 
| 
       259 
269 
     | 
    
         | 
| 
       260 
     | 
    
         
            -
                  def  
     | 
| 
       261 
     | 
    
         
            -
                     
     | 
| 
      
 270 
     | 
    
         
            +
                  def url(*args)
         
     | 
| 
      
 271 
     | 
    
         
            +
                    uploader.url(*args)
         
     | 
| 
       262 
272 
     | 
    
         
             
                  end
         
     | 
| 
       263 
273 
     | 
    
         | 
| 
       264 
     | 
    
         
            -
                  def  
     | 
| 
       265 
     | 
    
         
            -
                     
     | 
| 
      
 274 
     | 
    
         
            +
                  def blank?
         
     | 
| 
      
 275 
     | 
    
         
            +
                    uploader.blank?
         
     | 
| 
       266 
276 
     | 
    
         
             
                  end
         
     | 
| 
       267 
277 
     | 
    
         | 
| 
       268 
     | 
    
         
            -
                  def  
     | 
| 
       269 
     | 
    
         
            -
                     
     | 
| 
      
 278 
     | 
    
         
            +
                  def remove?
         
     | 
| 
      
 279 
     | 
    
         
            +
                    !remove.blank? and remove !~ /\A0|false$\z/
         
     | 
| 
       270 
280 
     | 
    
         
             
                  end
         
     | 
| 
       271 
281 
     | 
    
         | 
| 
       272 
     | 
    
         
            -
                  def  
     | 
| 
       273 
     | 
    
         
            -
                     
     | 
| 
      
 282 
     | 
    
         
            +
                  def remove!
         
     | 
| 
      
 283 
     | 
    
         
            +
                    uploader.remove!
         
     | 
| 
       274 
284 
     | 
    
         
             
                  end
         
     | 
| 
       275 
285 
     | 
    
         | 
| 
       276 
     | 
    
         
            -
                 
     | 
| 
      
 286 
     | 
    
         
            +
                private
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
                  def serialization_column
         
     | 
| 
      
 289 
     | 
    
         
            +
                    options[:mount_on] || column
         
     | 
| 
      
 290 
     | 
    
         
            +
                  end
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
                end # Mounter
         
     | 
| 
       277 
293 
     | 
    
         | 
| 
       278 
294 
     | 
    
         
             
              end # Mount
         
     | 
| 
       279 
295 
     | 
    
         
             
            end # CarrierWave
         
     | 
| 
         @@ -17,7 +17,12 @@ module CarrierWave 
     | 
|
| 
       17 
17 
     | 
    
         
             
                  validates_integrity_of column if uploader_options[column.to_sym][:validate_integrity]
         
     | 
| 
       18 
18 
     | 
    
         
             
                  validates_processing_of column if uploader_options[column.to_sym][:validate_processing]
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
      
 20 
     | 
    
         
            +
                  after_create do |record|
         
     | 
| 
      
 21 
     | 
    
         
            +
                    record.send("store_#{column}!")
         
     | 
| 
      
 22 
     | 
    
         
            +
                    record.save
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  before_update do |record|
         
     | 
| 
       21 
26 
     | 
    
         
             
                    record.send("store_#{column}!")
         
     | 
| 
       22 
27 
     | 
    
         
             
                  end
         
     | 
| 
       23 
28 
     | 
    
         
             
                end
         
     |