guide
rubyzip: zip dir recurisively
def download
if params[:id] # Folder ID
folder = current_user.folders.find(params[:id])
title = folder.name
eids = [folder.id] | folder.descendants.map{|f| f.id}
docs = current_user.documents.where(folder_id: eids);
else
title = current_user.name
docs = current_user.documents;
end
title = title.downcase.gsub(/\s+/, '_');
# Tmp folder to store the download files
tmpd = "tmp/download/#{current_user.slug}"
# Create a tmp folder if not exists
FileUtils.rm_rf([tmpd,"#{tmpd}.zip"]);
FileUtils.mkdir_p(tmpd);
# Download and save documents to our tmp folder
docs.each do |doc|
file = doc.file; folder = doc.folder;
dir = folder ? "#{tmpd}/#{folder.full_path}" : tmpd
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
fname = file.filename.to_s
if File.exist?("#{dir}/#{fname}") # incase two file with same name
fname = "DUP_ID#{doc.id}_#{fname}"
end
# User should be able to download files if not yet removed from tmp folder
# if the folder is already there, we'd get an error
download_doc_to_dir(file, dir, fname)
end
#---------- Convert to .zip --------------------------------------- #
zg = ZipFileGenerator.new(tmpd,"#{tmpd}.zip")
zg.write
# Sends the *.zip file to be download to the client's browser
send_file(Rails.root.join("#{tmpd}.zip"), :type => 'application/zip', :filename => "#{title}.zip", :disposition => 'attachment')
# TODO: Remove dir but leave zip file
FileUtils.rm_rf(tmpd)
end
def download_doc_to_dir(doc, tmpd, fname)
File.open(File.join(tmpd, fname), 'wb') do |file|
doc.download { |chunk| file.write(chunk) }
end
end