Monday, July 15, 2013

Copying between two uploaders in CarrierWave

To copy between two cloud providers using CarrierWave and Fog is a bit tricky.  Copying from one provider to a temporary file and then storing it in the other seems to work but the problem is that the file name is not preserved.  If you wrap the temporary file in a SanitizedFile then Carrierwave will update the content without changing the name of the file.

The following code preserves the file name between providers (where "obj" is the model, "source" is one uploader and "destination" is the other):

def copy_between_clouds(obj, src, dest)
  tmp = File.new("/tmp/tmp", "wb")
  begin
    filename = src.file.url
    File.open(tmp, "wb") do |file| 
      file << open(filename).read
    end
    t = File.new(tmp)
    sf = CarrierWave::SanitizedFile.new(t)
    dest.file.store(sf)
  ensure
    File.delete(tmp)
  end
end
To use it:
copy_between_clouds(o, o.old_jpg, o.new_jpg)
You might need to change "src.file.url" to "src.file.public_url" for some cloud providers.