carrierwave 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of carrierwave might be problematic. Click here for more details.

data/README.rdoc CHANGED
@@ -7,14 +7,16 @@ http://carrierwave.rubyforge.org
7
7
  This gem provides a simple and extremely flexible way to upload files from Ruby applications.
8
8
  It works well with Rack based web applications, such as Ruby on Rails.
9
9
 
10
- == Description
10
+ == Information
11
11
 
12
- * RDoc Documentation {available at Rubyforge}[http://carrierwave.rubyforge.org/rdoc].
13
- * Source code {hosted at GitHub}[http://github.com/jnicklas/carrierwave]
14
- * Please {report any issues}[http://github.com/jnicklas/carrierwave/issues] on GitHub
15
- * Please direct any questions at the {mailing list}[http://groups.google.com/group/carrierwave]
16
- * Check out the {example app}[http://github.com/jnicklas/carrierwave-example-app]
17
- * Instructions for setting up a development environment are at the bottom of this file
12
+ * RDoc documentation {available on RubyDoc.info}[http://rubydoc.info/gems/carrierwave/frames]
13
+ * Source code {available on GitHub}[http://github.com/jnicklas/carrierwave]
14
+ * More information, known limitations, and how-tos {available on the wiki}[https://github.com/jnicklas/carrierwave/wiki]
15
+
16
+ == Getting Help
17
+
18
+ * Please direct any questions to the {mailing list}[http://groups.google.com/group/carrierwave]
19
+ * Please report any issues on the {issue tracker}[http://github.com/jnicklas/carrierwave/issues]
18
20
 
19
21
  == Getting Started
20
22
 
@@ -26,10 +28,10 @@ In Rails, add it to your Gemfile:
26
28
 
27
29
  gem 'carrierwave'
28
30
 
31
+ == Rails 2.3.x Compatibility
32
+
29
33
  CarrierWave is only compatible with Rails 3 and later as of version 0.5. If you want to use
30
- Rails 2, please use the latest gem in the 0.4.X series. You may also consider trying
31
- {this plugin}[http://github.com/gbuesing/carrierwave_rails23_compat] which allows CarrierWave
32
- to be used with a Rails 2.3 app.
34
+ Rails 2, please use the latest gem in the 0.4.X series.
33
35
 
34
36
  == Quick Start
35
37
 
@@ -123,6 +125,38 @@ make the record invalid instead. Otherwise, an error is raised.
123
125
  end
124
126
  end
125
127
 
128
+ === Filenames and unicode chars
129
+
130
+ Another security issue you should care for is the file names (see
131
+ {Ruby On Rails Security Guide}[http://guides.rubyonrails.org/security.html#file-uploads]).
132
+ By default, CarrierWave provides only English letters, arabic numerals and '-+_.' symbols as
133
+ white-listed characters in the file name.
134
+
135
+ If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
136
+ have to override +sanitize_regexp+ method. It should return regular expression which would match
137
+ all *non*-allowed symbols.
138
+
139
+ With Ruby 1.9 and higher you can simply write (as it has {Oniguruma}[http://oniguruma.rubyforge.org/oniguruma/]
140
+ built-in):
141
+
142
+ class MyUploader < CarrierWave::Uploader::Base
143
+ def sanitize_regexp
144
+ /[^[:word:]\.\-\+]/
145
+ end
146
+ end
147
+
148
+ With Ruby 1.8.* you have to manually specify all character ranges. For example, for files which may
149
+ contain Russian letters:
150
+
151
+ class MyUploader < CarrierWave::Uploader::Base
152
+ def sanitize_regexp
153
+ /[^a-zA-Zа-яА-ЯёЁ0-9\.\-\+_]/u
154
+ end
155
+ end
156
+
157
+ Also make sure that allowing non-latin characters won't cause a compatibily issue with a third-party
158
+ plugins or client-side software.
159
+
126
160
  == Adding versions
127
161
 
128
162
  Often you'll want to add different versions of the same file. The classic
@@ -339,12 +373,27 @@ You'll need to configure a bucket, access id and secret key like this in an init
339
373
  config.s3_bucket = 'name_of_bucket'
340
374
  end
341
375
 
376
+ You'll need to create the bucket on Amazon S3 if it doesn't already exist.
377
+
342
378
  In your uploader, set the storage to :s3
343
379
 
344
380
  class AvatarUploader < CarrierWave::Uploader::Base
345
381
  storage :s3
346
382
  end
347
383
 
384
+ You can specify a region. US Standard "us-east-1" is the default.
385
+
386
+ CarrierWave.configure do |config|
387
+ config.s3_region = 'eu-west-1'
388
+ end
389
+
390
+ Available options are defined in Fog Storage[http://github.com/geemus/fog/blob/master/lib/fog/aws/storage.rb]
391
+
392
+ 'eu-west-1' => 's3-eu-west-1.amazonaws.com'
393
+ 'us-east-1' => 's3.amazonaws.com'
394
+ 'ap-southeast-1' => 's3-ap-southeast-1.amazonaws.com'
395
+ 'us-west-1' => 's3-us-west-1.amazonaws.com'
396
+
348
397
  That's it! You can still use the <code>CarrierWave::Uploader#url</code> method to return
349
398
  the url to the file on Amazon S3.
350
399
 
@@ -530,5 +579,9 @@ You should now be able to run the tests:
530
579
 
531
580
  bundle exec rake
532
581
 
533
- Issues are reported on GitHub, pull requests are very welcome!
582
+ You can also run the remote specs for Amazon S3 and Rackspace Cloud Files like so:
583
+
584
+ S3_SPEC=true CARRIERWAVE_TEST_BUCKET= S3_ACCESS_KEY_ID= S3_SECRET_ACCESS_KEY= bundle exec rake
585
+ CLOUDFILES_SPEC=true CLOUD_FILES_USER_NAME= CLOUD_FILES_API_KEY= CARRIERWAVE_TEST_CONTAINER= bundle exec rake
534
586
 
587
+ Issues are reported on GitHub, pull requests are very welcome!
data/lib/carrierwave.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'active_support/core_ext/object/blank'
5
- require 'active_support/core_ext/class/inheritable_attributes'
5
+ require 'active_support/core_ext/class/attribute'
6
6
  require 'active_support/concern'
7
7
 
8
8
  module CarrierWave
@@ -11,7 +11,7 @@ module CarrierWave
11
11
  #
12
12
  # class MyUploader < CarrierWave::Uploader::Base
13
13
  # include CarrierWave::Compatibility::Paperclip
14
- #
14
+ #
15
15
  # def paperclip_path
16
16
  # ":rails_root/public/uploads/:id/:attachment/:style_:basename.:extension"
17
17
  # end
@@ -20,23 +20,23 @@ module CarrierWave
20
20
  # ---
21
21
  #
22
22
  # This file contains code taken from Paperclip
23
- #
23
+ #
24
24
  # LICENSE
25
- #
25
+ #
26
26
  # The MIT License
27
- #
27
+ #
28
28
  # Copyright (c) 2008 Jon Yurek and thoughtbot, inc.
29
- #
29
+ #
30
30
  # Permission is hereby granted, free of charge, to any person obtaining a copy
31
31
  # of this software and associated documentation files (the "Software"), to deal
32
32
  # in the Software without restriction, including without limitation the rights
33
33
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
34
  # copies of the Software, and to permit persons to whom the Software is
35
35
  # furnished to do so, subject to the following conditions:
36
- #
36
+ #
37
37
  # The above copyright notice and this permission notice shall be included in
38
38
  # all copies or substantial portions of the Software.
39
- #
39
+ #
40
40
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
41
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
42
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -80,7 +80,7 @@ module CarrierWave
80
80
  #
81
81
  # [image_url] Returns the url to the uploaded file
82
82
  #
83
- # [image_cache] Returns a string that identifies the cache location of the file
83
+ # [image_cache] Returns a string that identifies the cache location of the file
84
84
  # [image_cache=] Retrieves the file from the cache based on the given cache name
85
85
  #
86
86
  # [remote_image_url] Returns previously cached remote url
@@ -106,7 +106,7 @@ module CarrierWave
106
106
  # [&block (Proc)] customize anonymous uploaders
107
107
  #
108
108
  # === Options
109
- #
109
+ #
110
110
  # [:mount_on => Symbol] if the name of the column to be serialized to differs you can override it using this option
111
111
  # [:ignore_integrity_errors => Boolean] if set to true, integrity errors will result in caching failing silently
112
112
  # [:ignore_processing_errors => Boolean] if set to true, processing errors will result in caching failing silently
@@ -273,7 +273,7 @@ module CarrierWave
273
273
  record.write_uploader(serialization_column, uploader.identifier)
274
274
  end
275
275
  end
276
-
276
+
277
277
  def identifier
278
278
  record.read_uploader(serialization_column)
279
279
  end
@@ -311,7 +311,7 @@ module CarrierWave
311
311
  def remote_url=(url)
312
312
  unless uploader.cached?
313
313
  @remote_url = url
314
- uploader.download!(url)
314
+ uploader.download!(url)
315
315
  end
316
316
  end
317
317
 
@@ -342,7 +342,7 @@ module CarrierWave
342
342
  end
343
343
 
344
344
  private
345
-
345
+
346
346
  def option(name)
347
347
  record.class.uploader_option(column, name)
348
348
  end
@@ -24,7 +24,7 @@ module CarrierWave
24
24
  # for objects that are not dirty. By explicitly calling
25
25
  # attribute_set we are marking the record as dirty.
26
26
  class_eval <<-RUBY
27
- def remove_image=(value)
27
+ def remove_#{column}=(value)
28
28
  _mounter(:#{column}).remove = value
29
29
  attribute_set(:#{column}, '') if _mounter(:#{column}).remove?
30
30
  end
@@ -1,25 +1,25 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'sequel'
4
-
4
+
5
5
  module CarrierWave
6
6
  module Sequel
7
7
  include CarrierWave::Mount
8
-
8
+
9
9
  def mount_uploader(column, uploader)
10
10
  raise "You need to use Sequel 3.0 or higher. Please upgrade." unless ::Sequel::Model.respond_to?(:plugin)
11
11
  super
12
-
12
+
13
13
  alias_method :read_uploader, :[]
14
14
  alias_method :write_uploader, :[]=
15
-
15
+
16
16
  include CarrierWave::Sequel::Hooks
17
17
  include CarrierWave::Sequel::Validations
18
18
  end
19
19
 
20
20
  end # Sequel
21
21
  end # CarrierWave
22
-
22
+
23
23
  # Instance hook methods for the Sequel 3.x
24
24
  module CarrierWave::Sequel::Hooks
25
25
  def after_save
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "image_science"
3
+ require 'image_science'
4
4
 
5
5
  module CarrierWave
6
6
  module ImageScience
@@ -59,15 +59,32 @@ module CarrierWave
59
59
  width, height = extract_dimensions_for_crop(img.width, img.height, new_width, new_height)
60
60
  x_offset, y_offset = extract_placement_for_crop(width, height, new_width, new_height)
61
61
 
62
+ # check if if new dimensions are too small for the new image
63
+ if width < new_width
64
+ width = new_width
65
+ height = (new_width.to_f*(img.height.to_f/img.width.to_f)).round
66
+ elsif height < new_height
67
+ height = new_height
68
+ width = (new_height.to_f*(img.width.to_f/img.height.to_f)).round
69
+ end
70
+
62
71
  img.resize( width, height ) do |i2|
63
72
 
73
+ # check to make sure offset is not negative
74
+ if x_offset < 0
75
+ x_offset = 0
76
+ end
77
+ if y_offset < 0
78
+ y_offset = 0
79
+ end
80
+
64
81
  i2.with_crop( x_offset, y_offset, new_width + x_offset, new_height + y_offset) do |file|
65
82
  file.save( self.current_path )
66
83
  end
67
84
  end
68
85
  end
69
86
  end
70
-
87
+
71
88
  ##
72
89
  # Resize the image to fit within the specified dimensions while retaining
73
90
  # the original aspect ratio. Will only resize the image if it is larger than the
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- unless defined? Magick
3
+ unless defined? Magick
4
4
  begin
5
5
  require 'rmagick'
6
6
  rescue LoadError
@@ -269,7 +269,7 @@ module CarrierWave
269
269
  end
270
270
 
271
271
  private
272
-
272
+
273
273
  def destroy_image(image)
274
274
  image.destroy! if image.respond_to?(:destroy!)
275
275
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'pathname'
4
+ require 'active_support/core_ext/string/multibyte'
4
5
 
5
6
  module CarrierWave
6
7
 
@@ -221,6 +222,17 @@ module CarrierWave
221
222
  @file.content_type.chomp if @file.respond_to?(:content_type) and @file.content_type
222
223
  end
223
224
 
225
+ ##
226
+ # Used to sanitize the file name. Public to allow overriding for non-latin characters.
227
+ #
228
+ # === Returns
229
+ #
230
+ # [Regexp] the regexp for sanitizing the file name
231
+ #
232
+ def sanitize_regexp
233
+ /[^a-zA-Z0-9\.\-\+_]/
234
+ end
235
+
224
236
  private
225
237
 
226
238
  def file=(file)
@@ -248,10 +260,10 @@ module CarrierWave
248
260
  def sanitize(name)
249
261
  name = name.gsub("\\", "/") # work-around for IE
250
262
  name = File.basename(name)
251
- name = name.gsub(/[^a-zA-Z0-9\.\-\+_]/,"_")
263
+ name = name.gsub(sanitize_regexp,"_")
252
264
  name = "_#{name}" if name =~ /\A\.+\z/
253
265
  name = "unnamed" if name.size == 0
254
- return name.downcase
266
+ return name.mb_chars.downcase.to_s
255
267
  end
256
268
 
257
269
  def split_extension(filename)
@@ -5,7 +5,7 @@ module CarrierWave
5
5
  module Storage
6
6
 
7
7
  ##
8
- # Uploads things to Rackspace Cloud Files webservices using the Rackspace libraries (cloudfiles gem).
8
+ # Uploads things to Rackspace Cloud Files webservices using the Rackspace libraries (cloudfiles gem).
9
9
  # In order for CarrierWave to connect to Cloud Files, you'll need to specify an username, api key
10
10
  # and container
11
11
  #
@@ -33,7 +33,7 @@ module CarrierWave
33
33
  end
34
34
 
35
35
  ##
36
- # Returns the current path/filename of the file on Cloud Files.
36
+ # Returns the current path/filename of the file on Cloud Files.
37
37
  #
38
38
  # === Returns
39
39
  #
@@ -112,7 +112,7 @@ module CarrierWave
112
112
  def connection
113
113
  @base.connection
114
114
  end
115
-
115
+
116
116
  def cf_connection
117
117
  @cf_connection ||= ::CloudFiles::Connection.new(@uploader.cloud_files_username, @uploader.cloud_files_api_key)
118
118
  end
@@ -121,12 +121,16 @@ module CarrierWave
121
121
  if @cf_container
122
122
  @cf_container
123
123
  else
124
- @cf_container = cf_connection.create_container(container)
125
- @cf_container.make_public
124
+ begin
125
+ @cf_container = cf_connection.container(container)
126
+ rescue NoSuchContainerException
127
+ @cf_container = cf_connection.create_container(container)
128
+ @cf_container.make_public
129
+ end
126
130
  @cf_container
127
131
  end
128
132
  end
129
-
133
+
130
134
 
131
135
  end
132
136
 
@@ -11,7 +11,7 @@ module CarrierWave
11
11
  # connection or you reuse an existing connection.
12
12
  #
13
13
  # Creating a connection looks something like this:
14
- #
14
+ #
15
15
  # CarrierWave.configure do |config|
16
16
  # config.storage = :grid_fs
17
17
  # config.grid_fs_host = "your-host.com"
@@ -23,7 +23,7 @@ module CarrierWave
23
23
  # end
24
24
  #
25
25
  # In the above example your documents url will look like:
26
- #
26
+ #
27
27
  # http://your-app.com/images/:document-identifier-here
28
28
  #
29
29
  # When you already have a Mongo connection object (for example through Mongoid)
@@ -45,7 +45,7 @@ module CarrierWave
45
45
  end
46
46
 
47
47
  def path
48
- nil
48
+ @path
49
49
  end
50
50
 
51
51
  def url
@@ -61,7 +61,7 @@ module CarrierWave
61
61
  end
62
62
 
63
63
  def write(file)
64
- grid.open(@uploader.store_path, 'w', :content_type => file.content_type) do |f|
64
+ grid.open(@uploader.store_path, 'w', :content_type => file.content_type) do |f|
65
65
  f.write(file.read)
66
66
  end
67
67
  end
@@ -73,7 +73,7 @@ module CarrierWave
73
73
  def content_type
74
74
  grid.open(@path, 'r').content_type
75
75
  end
76
-
76
+
77
77
  def file_length
78
78
  grid.open(@path, 'r').file_length
79
79
  end
@@ -92,7 +92,7 @@ module CarrierWave
92
92
  db
93
93
  end
94
94
  end
95
-
95
+
96
96
  def grid
97
97
  @grid ||= Mongo::GridFileSystem.new(database)
98
98
  end
@@ -123,10 +123,11 @@ module CarrierWave
123
123
  end
124
124
 
125
125
  def public_url
126
+ scheme = use_ssl? ? 'https' : 'http'
126
127
  if cnamed?
127
- ["http://#{bucket}", path].compact.join('/')
128
+ ["#{scheme}://#{bucket}", path].compact.join('/')
128
129
  else
129
- ["http://#{bucket}.s3.amazonaws.com", path].compact.join('/')
130
+ ["#{scheme}://#{bucket}.s3.amazonaws.com", path].compact.join('/')
130
131
  end
131
132
  end
132
133
 
@@ -167,6 +168,10 @@ module CarrierWave
167
168
 
168
169
  private
169
170
 
171
+ def use_ssl?
172
+ @uploader.s3_use_ssl
173
+ end
174
+
170
175
  def cnamed?
171
176
  @uploader.s3_cnamed
172
177
  end
@@ -217,7 +222,8 @@ module CarrierWave
217
222
  end
218
223
 
219
224
  def connection
220
- @connection ||= Fog::AWS::Storage.new(
225
+ @connection ||= Fog::Storage.new(
226
+ :provider => 'AWS',
221
227
  :aws_access_key_id => uploader.s3_access_key_id,
222
228
  :aws_secret_access_key => uploader.s3_secret_access_key,
223
229
  :region => uploader.s3_region
@@ -7,7 +7,7 @@ module CarrierWave
7
7
  "You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed.\n\n If this is a file upload, please check that your upload form is multipart encoded."
8
8
  end
9
9
  end
10
-
10
+
11
11
  ##
12
12
  # Generates a unique cache id for use in the caching system
13
13
  #
@@ -37,7 +37,7 @@ module CarrierWave
37
37
  # CarrierWave.clean_cached_files!
38
38
  #
39
39
  # === Note
40
- #
40
+ #
41
41
  # This only works as long as you haven't done anything funky with your cache_dir.
42
42
  # It's recommended that you keep cache files in one place only.
43
43
  #
@@ -6,33 +6,27 @@ module CarrierWave
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
- class_inheritable_accessor :_before_callbacks, :_after_callbacks
9
+ class_attribute :_before_callbacks, :_after_callbacks,
10
+ :instance_writer => false
11
+ self._before_callbacks = Hash.new []
12
+ self._after_callbacks = Hash.new []
10
13
  end
11
14
 
12
15
  def with_callbacks(kind, *args)
13
- self.class._before_callbacks_for(kind).each { |callback| self.send(callback, *args) }
16
+ self.class._before_callbacks[kind].each { |c| send c, *args }
14
17
  yield
15
- self.class._after_callbacks_for(kind).each { |callback| self.send(callback, *args) }
18
+ self.class._after_callbacks[kind].each { |c| send c, *args }
16
19
  end
17
20
 
18
21
  module ClassMethods
19
-
20
- def _before_callbacks_for(kind) #:nodoc:
21
- (self._before_callbacks || { kind => [] })[kind] || []
22
- end
23
-
24
- def _after_callbacks_for(kind) #:nodoc:
25
- (self._after_callbacks || { kind => [] })[kind] || []
26
- end
27
-
28
- def before(kind, callback)
29
- self._before_callbacks ||= {}
30
- self._before_callbacks[kind] = _before_callbacks_for(kind) + [callback]
22
+ def before(kind, callback)
23
+ self._before_callbacks = self._before_callbacks.
24
+ merge kind => _before_callbacks[kind] + [callback]
31
25
  end
32
26
 
33
27
  def after(kind, callback)
34
- self._after_callbacks ||= {}
35
- self._after_callbacks[kind] = _after_callbacks_for(kind) + [callback]
28
+ self._after_callbacks = self._after_callbacks.
29
+ merge kind => _after_callbacks[kind] + [callback]
36
30
  end
37
31
  end # ClassMethods
38
32
 
@@ -15,6 +15,7 @@ module CarrierWave
15
15
  add_config :s3_cnamed
16
16
  add_config :s3_headers
17
17
  add_config :s3_region
18
+ add_config :s3_use_ssl
18
19
  add_config :cloud_files_username
19
20
  add_config :cloud_files_api_key
20
21
  add_config :cloud_files_container
@@ -52,6 +53,7 @@ module CarrierWave
52
53
  config.s3_headers = {}
53
54
  config.s3_access_policy = :public_read
54
55
  config.s3_region = 'us-east-1'
56
+ config.s3_use_ssl = false
55
57
  config.grid_fs_database = 'carrierwave'
56
58
  config.grid_fs_host = 'localhost'
57
59
  config.grid_fs_port = 27017
@@ -54,7 +54,7 @@ module CarrierWave
54
54
  unless uri.blank?
55
55
  file = RemoteFile.new(uri)
56
56
  raise CarrierWave::DownloadError, "trying to download a file which is not served over HTTP" unless file.http?
57
- cache!(file)
57
+ cache!(file)
58
58
  end
59
59
  end
60
60
 
@@ -11,11 +11,15 @@ module CarrierWave
11
11
 
12
12
  ##
13
13
  # Override this method in your uploader to provide a white list of extensions which
14
- # are allowed to be uploaded.
14
+ # are allowed to be uploaded. Compares the file's extension case insensitive.
15
+ # Furthermore, not only strings but Regexp are allowed as well.
16
+ #
17
+ # When using a Regexp in the white list, `\A` and `\z` are automatically added to
18
+ # the Regexp expression, also case insensitive.
15
19
  #
16
20
  # === Returns
17
21
  #
18
- # [NilClass, Array[String]] a white list of extensions which are allowed to be uploaded
22
+ # [NilClass, Array[String,Regexp]] a white list of extensions which are allowed to be uploaded
19
23
  #
20
24
  # === Examples
21
25
  #
@@ -23,12 +27,19 @@ module CarrierWave
23
27
  # %w(jpg jpeg gif png)
24
28
  # end
25
29
  #
30
+ # Basically the same, but using a Regexp:
31
+ #
32
+ # def extension_white_list
33
+ # [/jpe?g/, 'gif', 'png']
34
+ # end
35
+ #
26
36
  def extension_white_list; end
27
37
 
28
38
  private
29
39
 
30
40
  def check_whitelist!(new_file)
31
- if extension_white_list and not extension_white_list.include?(new_file.extension.to_s)
41
+ extension = new_file.extension.to_s
42
+ if extension_white_list and not extension_white_list.detect { |item| extension =~ /\A#{item}\z/i }
32
43
  raise CarrierWave::IntegrityError, "You are not allowed to upload #{new_file.extension.inspect} files, allowed types: #{extension_white_list.inspect}"
33
44
  end
34
45
  end
@@ -9,7 +9,6 @@ module CarrierWave
9
9
 
10
10
  included do
11
11
  after :cache, :process!
12
- after :recreate_versions, :process!
13
12
  end
14
13
 
15
14
  module ClassMethods
@@ -114,9 +114,17 @@ module CarrierWave
114
114
  # versions if their parameters somehow have changed.
115
115
  #
116
116
  def recreate_versions!
117
- with_callbacks(:recreate_versions, file) do
118
- versions.each { |name, v| v.store!(file) }
119
- end
117
+ # Some files could possibly not be stored on the local disk. This
118
+ # doesn't play nicely with processing. To fix this, we create a new
119
+ # file with the same original filename and we call file.read to get the
120
+ # data for the file and then store that.
121
+ #
122
+ # The call to store! will trigger the necessary callbacks to both
123
+ # process this version and all sub-versions
124
+ local_file = SanitizedFile.new :tempfile => StringIO.new(file.read),
125
+ :filename => File.basename(path)
126
+
127
+ store! local_file
120
128
  end
121
129
 
122
130
  private
@@ -130,9 +138,15 @@ module CarrierWave
130
138
  end
131
139
 
132
140
  def cache_versions!(new_file)
141
+ # We might have processed the new_file argument after the callbacks were
142
+ # initialized, so get the actual file based off of the current state of
143
+ # our file
144
+ processed_parent = SanitizedFile.new :tempfile => self.file,
145
+ :filename => new_file.original_filename
146
+
133
147
  versions.each do |name, v|
134
148
  v.send(:cache_id=, cache_id)
135
- v.cache!(new_file)
149
+ v.cache!(processed_parent)
136
150
  end
137
151
  end
138
152
 
@@ -1,3 +1,3 @@
1
1
  module CarrierWave
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carrierwave
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
5
- prerelease: false
4
+ hash: 15
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 1
10
- version: 0.5.1
9
+ - 2
10
+ version: 0.5.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jonas Nicklas
@@ -15,13 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-01 00:00:00 +00:00
18
+ date: 2011-02-18 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: activesupport
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
23
  none: false
26
24
  requirements:
27
25
  - - ~>
@@ -31,12 +29,12 @@ dependencies:
31
29
  - 3
32
30
  - 0
33
31
  version: "3.0"
32
+ prerelease: false
34
33
  type: :runtime
35
- version_requirements: *id001
34
+ requirement: *id001
35
+ name: activesupport
36
36
  - !ruby/object:Gem::Dependency
37
- name: rails
38
- prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
37
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
38
  none: false
41
39
  requirements:
42
40
  - - ~>
@@ -45,46 +43,43 @@ dependencies:
45
43
  segments:
46
44
  - 3
47
45
  - 0
48
- - 0
49
- version: 3.0.0
46
+ version: "3.0"
47
+ prerelease: false
50
48
  type: :development
51
- version_requirements: *id002
49
+ requirement: *id002
50
+ name: rails
52
51
  - !ruby/object:Gem::Dependency
53
- name: rspec
54
- prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
53
  none: false
57
54
  requirements:
58
55
  - - ~>
59
56
  - !ruby/object:Gem::Version
60
- hash: 27
57
+ hash: 9
61
58
  segments:
62
59
  - 1
63
60
  - 3
64
- - 0
65
- version: 1.3.0
61
+ version: "1.3"
62
+ prerelease: false
66
63
  type: :development
67
- version_requirements: *id003
64
+ requirement: *id003
65
+ name: rspec
68
66
  - !ruby/object:Gem::Dependency
69
- name: fog
70
- prerelease: false
71
- requirement: &id004 !ruby/object:Gem::Requirement
67
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
68
  none: false
73
69
  requirements:
74
70
  - - ~>
75
71
  - !ruby/object:Gem::Version
76
- hash: 29
72
+ hash: 3
77
73
  segments:
78
74
  - 0
79
- - 3
80
- - 7
81
- version: 0.3.7
75
+ - 4
76
+ version: "0.4"
77
+ prerelease: false
82
78
  type: :development
83
- version_requirements: *id004
79
+ requirement: *id004
80
+ name: fog
84
81
  - !ruby/object:Gem::Dependency
85
- name: cucumber
86
- prerelease: false
87
- requirement: &id005 !ruby/object:Gem::Requirement
82
+ version_requirements: &id005 !ruby/object:Gem::Requirement
88
83
  none: false
89
84
  requirements:
90
85
  - - ">="
@@ -93,12 +88,12 @@ dependencies:
93
88
  segments:
94
89
  - 0
95
90
  version: "0"
91
+ prerelease: false
96
92
  type: :development
97
- version_requirements: *id005
93
+ requirement: *id005
94
+ name: cucumber
98
95
  - !ruby/object:Gem::Dependency
99
- name: sqlite3-ruby
100
- prerelease: false
101
- requirement: &id006 !ruby/object:Gem::Requirement
96
+ version_requirements: &id006 !ruby/object:Gem::Requirement
102
97
  none: false
103
98
  requirements:
104
99
  - - ">="
@@ -107,12 +102,12 @@ dependencies:
107
102
  segments:
108
103
  - 0
109
104
  version: "0"
105
+ prerelease: false
110
106
  type: :development
111
- version_requirements: *id006
107
+ requirement: *id006
108
+ name: sqlite3-ruby
112
109
  - !ruby/object:Gem::Dependency
113
- name: dm-core
114
- prerelease: false
115
- requirement: &id007 !ruby/object:Gem::Requirement
110
+ version_requirements: &id007 !ruby/object:Gem::Requirement
116
111
  none: false
117
112
  requirements:
118
113
  - - ">="
@@ -121,12 +116,12 @@ dependencies:
121
116
  segments:
122
117
  - 0
123
118
  version: "0"
119
+ prerelease: false
124
120
  type: :development
125
- version_requirements: *id007
121
+ requirement: *id007
122
+ name: dm-core
126
123
  - !ruby/object:Gem::Dependency
127
- name: dm-validations
128
- prerelease: false
129
- requirement: &id008 !ruby/object:Gem::Requirement
124
+ version_requirements: &id008 !ruby/object:Gem::Requirement
130
125
  none: false
131
126
  requirements:
132
127
  - - ">="
@@ -135,12 +130,12 @@ dependencies:
135
130
  segments:
136
131
  - 0
137
132
  version: "0"
133
+ prerelease: false
138
134
  type: :development
139
- version_requirements: *id008
135
+ requirement: *id008
136
+ name: dm-validations
140
137
  - !ruby/object:Gem::Dependency
141
- name: dm-migrations
142
- prerelease: false
143
- requirement: &id009 !ruby/object:Gem::Requirement
138
+ version_requirements: &id009 !ruby/object:Gem::Requirement
144
139
  none: false
145
140
  requirements:
146
141
  - - ">="
@@ -149,12 +144,12 @@ dependencies:
149
144
  segments:
150
145
  - 0
151
146
  version: "0"
147
+ prerelease: false
152
148
  type: :development
153
- version_requirements: *id009
149
+ requirement: *id009
150
+ name: dm-migrations
154
151
  - !ruby/object:Gem::Dependency
155
- name: dm-sqlite-adapter
156
- prerelease: false
157
- requirement: &id010 !ruby/object:Gem::Requirement
152
+ version_requirements: &id010 !ruby/object:Gem::Requirement
158
153
  none: false
159
154
  requirements:
160
155
  - - ">="
@@ -163,12 +158,12 @@ dependencies:
163
158
  segments:
164
159
  - 0
165
160
  version: "0"
161
+ prerelease: false
166
162
  type: :development
167
- version_requirements: *id010
163
+ requirement: *id010
164
+ name: dm-sqlite-adapter
168
165
  - !ruby/object:Gem::Dependency
169
- name: sequel
170
- prerelease: false
171
- requirement: &id011 !ruby/object:Gem::Requirement
166
+ version_requirements: &id011 !ruby/object:Gem::Requirement
172
167
  none: false
173
168
  requirements:
174
169
  - - ">="
@@ -177,12 +172,12 @@ dependencies:
177
172
  segments:
178
173
  - 0
179
174
  version: "0"
175
+ prerelease: false
180
176
  type: :development
181
- version_requirements: *id011
177
+ requirement: *id011
178
+ name: sequel
182
179
  - !ruby/object:Gem::Dependency
183
- name: rmagick
184
- prerelease: false
185
- requirement: &id012 !ruby/object:Gem::Requirement
180
+ version_requirements: &id012 !ruby/object:Gem::Requirement
186
181
  none: false
187
182
  requirements:
188
183
  - - ">="
@@ -191,12 +186,12 @@ dependencies:
191
186
  segments:
192
187
  - 0
193
188
  version: "0"
189
+ prerelease: false
194
190
  type: :development
195
- version_requirements: *id012
191
+ requirement: *id012
192
+ name: rmagick
196
193
  - !ruby/object:Gem::Dependency
197
- name: RubyInline
198
- prerelease: false
199
- requirement: &id013 !ruby/object:Gem::Requirement
194
+ version_requirements: &id013 !ruby/object:Gem::Requirement
200
195
  none: false
201
196
  requirements:
202
197
  - - ">="
@@ -205,12 +200,12 @@ dependencies:
205
200
  segments:
206
201
  - 0
207
202
  version: "0"
203
+ prerelease: false
208
204
  type: :development
209
- version_requirements: *id013
205
+ requirement: *id013
206
+ name: RubyInline
210
207
  - !ruby/object:Gem::Dependency
211
- name: image_science
212
- prerelease: false
213
- requirement: &id014 !ruby/object:Gem::Requirement
208
+ version_requirements: &id014 !ruby/object:Gem::Requirement
214
209
  none: false
215
210
  requirements:
216
211
  - - ">="
@@ -219,12 +214,12 @@ dependencies:
219
214
  segments:
220
215
  - 0
221
216
  version: "0"
217
+ prerelease: false
222
218
  type: :development
223
- version_requirements: *id014
219
+ requirement: *id014
220
+ name: image_science
224
221
  - !ruby/object:Gem::Dependency
225
- name: mini_magick
226
- prerelease: false
227
- requirement: &id015 !ruby/object:Gem::Requirement
222
+ version_requirements: &id015 !ruby/object:Gem::Requirement
228
223
  none: false
229
224
  requirements:
230
225
  - - ~>
@@ -234,12 +229,12 @@ dependencies:
234
229
  - 2
235
230
  - 3
236
231
  version: "2.3"
232
+ prerelease: false
237
233
  type: :development
238
- version_requirements: *id015
234
+ requirement: *id015
235
+ name: mini_magick
239
236
  - !ruby/object:Gem::Dependency
240
- name: bson_ext
241
- prerelease: false
242
- requirement: &id016 !ruby/object:Gem::Requirement
237
+ version_requirements: &id016 !ruby/object:Gem::Requirement
243
238
  none: false
244
239
  requirements:
245
240
  - - "="
@@ -250,12 +245,12 @@ dependencies:
250
245
  - 1
251
246
  - 1
252
247
  version: 1.1.1
248
+ prerelease: false
253
249
  type: :development
254
- version_requirements: *id016
250
+ requirement: *id016
251
+ name: bson_ext
255
252
  - !ruby/object:Gem::Dependency
256
- name: mongoid
257
- prerelease: false
258
- requirement: &id017 !ruby/object:Gem::Requirement
253
+ version_requirements: &id017 !ruby/object:Gem::Requirement
259
254
  none: false
260
255
  requirements:
261
256
  - - "="
@@ -268,12 +263,12 @@ dependencies:
268
263
  - beta
269
264
  - 19
270
265
  version: 2.0.0.beta.19
266
+ prerelease: false
271
267
  type: :development
272
- version_requirements: *id017
268
+ requirement: *id017
269
+ name: mongoid
273
270
  - !ruby/object:Gem::Dependency
274
- name: timecop
275
- prerelease: false
276
- requirement: &id018 !ruby/object:Gem::Requirement
271
+ version_requirements: &id018 !ruby/object:Gem::Requirement
277
272
  none: false
278
273
  requirements:
279
274
  - - ">="
@@ -282,12 +277,26 @@ dependencies:
282
277
  segments:
283
278
  - 0
284
279
  version: "0"
280
+ prerelease: false
285
281
  type: :development
286
- version_requirements: *id018
282
+ requirement: *id018
283
+ name: timecop
287
284
  - !ruby/object:Gem::Dependency
288
- name: json
285
+ version_requirements: &id019 !ruby/object:Gem::Requirement
286
+ none: false
287
+ requirements:
288
+ - - ">="
289
+ - !ruby/object:Gem::Version
290
+ hash: 3
291
+ segments:
292
+ - 0
293
+ version: "0"
289
294
  prerelease: false
290
- requirement: &id019 !ruby/object:Gem::Requirement
295
+ type: :development
296
+ requirement: *id019
297
+ name: json
298
+ - !ruby/object:Gem::Dependency
299
+ version_requirements: &id020 !ruby/object:Gem::Requirement
291
300
  none: false
292
301
  requirements:
293
302
  - - ">="
@@ -296,8 +305,10 @@ dependencies:
296
305
  segments:
297
306
  - 0
298
307
  version: "0"
308
+ prerelease: false
299
309
  type: :development
300
- version_requirements: *id019
310
+ requirement: *id020
311
+ name: cloudfiles
301
312
  description: Upload files in your Ruby applications, map them to a range of ORMs, store them on different backends.
302
313
  email:
303
314
  - jonas.nicklas@gmail.com
@@ -377,7 +388,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
377
388
  requirements: []
378
389
 
379
390
  rubyforge_project: carrierwave
380
- rubygems_version: 1.3.7
391
+ rubygems_version: 1.5.0
381
392
  signing_key:
382
393
  specification_version: 3
383
394
  summary: Ruby file upload library