How to download multiple files from S3 as Zip format in Rails 5.x.x app?

北城以北 提交于 2019-12-07 07:25:28

问题


I am implementing feature which allows user to either download single file or multiple files from S3. Single file downloading is working properly, but for multiple files I am receiving error on Heroku,

Errno::ENOENT (No such file or directory @ rb_file_s_lstat )

Controller code snippet for downloading files as zip format is as below,

def method_name
   zipfile_name = "#{Rails.root}/public/archive.zip"
   Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile |
     @transfer.transfer_attachments.each do |attachment | 
       zipfile.add(attachment.avatar.file.filename, attachment.avatar.url)
     end
   end
   send_file(File.join("#{Rails.root}/public/", 'archive.zip'), : type =>
'application/zip', : filename => "#{Time.now.to_date}.zip")
end

Gemfile

ruby '2.3.1'

gem 'rails', '~> 5.0.1'

gem 'rubyzip', '>= 1.0.0'

gem 'zip-zip'

This zipfile functionality works proper with locally stored files.


回答1:


Guess: You are adding attachments as urls, but you should be adding (local) file paths instead.




回答2:


I would like to answer to my question. Steps are as follow,

  1. Downlaod files from S3 and store them locally
  2. Add them to zip by first creating zip and then add files to it.
  3. Download zip archive

Here is controller code,

require 'open-uri'

def download_all_files
   folder_path = "#{Rails.root}/public/downloads/"
   zipfile_name = "#{Rails.root}/public/archive.zip"

   FileUtils.remove_dir(folder_path) if Dir.exist?(folder_path)
   FileUtils.remove_entry(zipfile_name) if File.exist?(zipfile_name)
   Dir.mkdir("#{Rails.root}/public/downloads")

   @model_object.each do |attachment|
      open(folder_path + "#{attachment.avatar.file.filename}", 'wb') do |file|
         file << open("#{attachment.avatar.url}").read
      end
   end

   input_filenames = Dir.entries(folder_path).select {|f| !File.directory? f}

   Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
      input_filenames.each do |attachment|
         zipfile.add(attachment,File.join(folder_path,attachment))
      end
   end

   send_file(File.join("#{Rails.root}/public/", 'archive.zip'), :type => 'application/zip', :filename => "#{Time.now.to_date}.zip")

end


来源:https://stackoverflow.com/questions/44693925/how-to-download-multiple-files-from-s3-as-zip-format-in-rails-5-x-x-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!