Entries Tagged 'rubyzip' ↓

Attachment Fu and Zip Files – RubyZip and Extracting For Bulk Uploads

Today I’m going to share how you can let your app accept zip files which will then be extracted into multiple attachments. If you already use Attachment Fu to manage files, this should be super easy to add.

Before my controller had something like this:

Attachment.create(:uploaded_data => params[:Filedata])

First break that up into something more like this:

attachment = Attachment.new
attachment.uploaded_data = params[:Filedata]
attachment.save

Then put in some split logic for if it’s a zip file:

attachment = Attachment.new
attachment.uploaded_data = params[:Filedata]
      
if attachment.content_type == "application/zip"
    # Unzip this and process all the inner files
    Attachment.build_from_zip(attachment)
else
    attachment.save
end

Now we’ll need the RubyZip gem and MIME Types gem, so do:

sudo gem install rubyzip
sudo gem install mime-types

Now in the Attachment class we’ll add the build_from_zip method:

def self.build_from_zip(ss)
 zipfile = Zip::ZipFile.open(ss.temp_path)
  
 zipfile.each do |entry|
   if entry.directory?
     next
   elsif entry.name.include?("/")
     next
   else
     screen = Attachment.new
     screen.filename = entry.name
     screen.temp_data = zipfile.read(entry.name)
      
     mime = MIME::Types.type_for(entry.name)[0]
     screen.content_type = mime.content_type unless mime.blank?

     screen.save
   end
 end
  
end

The only two non-obvious things to note here are:

  • I skip the files with / in them because when I archive files on my machine, hidden files with / characters in them make it into the archive. I only want the real files.
  • I use the MIME Types gem to decide the content type from the filename.

I hope you find this helpful, enjoy!