Wednesday, March 16, 2011

Zip multiple files and download as attachment using rubyzip gem.

rubyzip is a lib for creating / working with zip archives in ruby.

» gem install rubyzip


Sample code

require 'zip/zip'
require 'zip/zipfilesystem'


def download_all
attachments = Upload.find(:all, :conditions => ["source_id = ?", params[:id]])

zip_file_path = "#{RAILS_ROOT}/uploads/download_all.zip"


# see if the file exists already, and if it does, delete it.
if File.file?(zip_file_path)
File.delete(zip_file_path)
end


# open or create the zip file
Zip::ZipFile.open(zip_file_path, Zip::ZipFile::CREATE) { |zipfile|

attachments.each do |attachment|
#document_file_name shd contain filename with extension(.jpg, .csv etc) and url is the path of the document.
zipfile.add( attachment.document_file_name, attachment.document.url)

end

}
#send the file as an attachment to the user.
send_file zip_file_path, :type => 'application/zip', :disposition => 'attachment', :filename => "download_all.zip"

end

5 comments:

  1. its great. I have one small issue:

    I am trying to zip content from server. Content is something like this

    http://myApplication.s3.amazonaws.com/xxxxxxxx/image/image1.jpeg, http://myApplication.s3.amazonaws.com/xxxxxxxx/image/image2.jpeg, http://myApplication.s3.amazonaws.com/xxxxxxxx/image/image3.jpeg

    So in "zipfile.add( attachment.document_file_name, attachment.document.url)", i assigned following values:

    document_file_name = image1.jpeg/image2.jpeg/image3.jpeg
    document.url = http://myApplication.s3.amazonaws.com/xxxxxxxx/image

    Now here I am getting following error:

    No such file or directory - http://myApplication.s3.amazonaws.com/xxxxxxxx/image

    Is I am doing something wrong? Can someone help me out?

    Thanks

    ReplyDelete
  2. So am I - anyone knows hot to solve it?

    ReplyDelete
  3. Hi,
    I've a solution for this
    just use temporary path on your local system.
    ex:
    attachments = 'attachments.zip'
    temp_file = Tempfile.new(attachments)
    and use temp_file.path in place of zip_file_path


    Thanks,

    ReplyDelete