ZIP files in Rails

Today, I needed to make a KMZ file from my KML in Rails. This was easy thanks to RubyZIP:


gem install rubyzip

Now for the Rails action:


# In your controller
private

def zip(data, filename)
  zipfile = "/tmp/rubyzip-#{rand 32768}"
  Zip::ZipOutputStream::open(zipfile) do |io|
    io.put_next_entry(filename)
    io.write data
  end
  zippy = File.open(zipfile).read
  File.delete(zipfile)
  zippy
end

This makes a temp file, adds to it zip-style, reads it to a string, and deletes it. It leaves nothing behind on the file system. Then all you have to do is call it properly. I wanted to zip up the KML into a KMZ, so this is what I did:


# Action that makes KML when it renders
    #....
    if params[:format] = "kmz"
      filename = "my.kml"
      zipfilename = "my.kmz"
      send_data(zip(render_to_string(:layout => false), filename),
        :filename => zipfilename,
        :type => 'application/vnd.google-earth.kmz')
    #....

Then I just made a route like this:


  map.connect 'my.kmz', :controller => 'activity', :action => 'make_kml', :format => 'kml'

It works – I tested it in Google Earth on Linux, which is slick by the way.



Comments

  1. johan

    February 24, 2007 at 2:59 PM

    I encounter this error when calling the File.delete(zipfile):

    Errno::EACCES in TranscribeController#zip
    Permission denied – C:/temp/rails/myproject/public/uploads/maakfile13638.zip


  2. Jim

    February 24, 2007 at 2:59 PM

    Your sendJerksAway() script is childish. Grow up.


  3. Hank

    February 24, 2007 at 2:59 PM

    I’m sorry you didn’t appreciate it. Maybe you should grow up and support the sites you go to.


  4. Hank

    February 24, 2007 at 2:59 PM

    In Windows, permissions can be tricky. Maybe you should try to take ownership of the file or move it somewhere where you are guaranteed to have ownership. I don’t really know what to tell you since I’ve never developed in Rails on Windows.