Permalink
Browse files

Move zip code into a concern

  • Loading branch information...
madeindjs committed Nov 30, 2018
1 parent a0fab8e commit 67a8bcb8fd6124fdb7a2c8c3f2fd85fcbd704e5b
Showing with 71 additions and 54 deletions.
  1. +68 −0 app/controllers/concerns/generate_zip.rb
  2. +3 −54 app/controllers/users_controller.rb
@@ -0,0 +1,68 @@
# app/controllers/concerns/generate_zip.rb

module GenerateZip
extend ActiveSupport::Concern

protected

# Zip all given files into a zip and send it with `send_data`
#
# @param active_storages [ActiveStorage::Attached::Many] files to save
# @param filename [ActiveStorage::Attached::Many] files to save
def send_zip(active_storages, filename: 'my.zip')
files = save_files_on_server active_storages
zip_data = create_temporary_zip_file files

send_data(zip_data, type: 'application/zip', filename: filename)
end

private

# Download active storage files on server in a temporary folder
#
# @param files [ActiveStorage::Attached::Many] files to save
# @return [Array<String>] files paths of saved files
def save_files_on_server(files)
# get a temporary folder and create it
temp_folder = File.join(Dir.tmpdir, 'user')
FileUtils.mkdir_p(temp_folder) unless Dir.exist?(temp_folder)

# download all ActiveStorage into
files.map do |picture|
filename = picture.filename.to_s
filepath = File.join temp_folder, filename
File.open(filepath, 'wb') { |f| f.write(picture.download) }
filepath
end
end

# Create a temporary zip file & return the content as bytes
#
# @param filepaths [Array<String>] files paths
# @return [String] as content of zip
def create_temporary_zip_file(filepaths)
require 'zip'
temp_file = Tempfile.new('user.zip')

begin
# Initialize the temp file as a zip file
Zip::OutputStream.open(temp_file) { |zos| }

# open the zip
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zip|
filepaths.each do |filepath|
filename = File.basename filepath
# add file into the zip
zip.add filename, filepath
end
end

return File.read(temp_file.path)
ensure
# close all ressources & remove temporary files
temp_file.close
temp_file.unlink
filepaths.each { |filepath| FileUtils.rm(filepath) }
end
end
end
@@ -2,6 +2,8 @@
class UsersController < ApplicationController
before_action :set_user, only: %i[show edit update destroy]

include GenerateZip

# GET /users
# GET /users.json
def index
@@ -13,12 +15,7 @@ def index
def show
respond_to do |format|
format.html { render }
format.zip do
files = save_files_on_server @user.pictures
zip_data = create_temporary_zip_file files

send_data(zip_data, type: 'application/zip', filename: 'user.zip')
end
format.zip { send_zip @user.pictures }
end
end

@@ -72,54 +69,6 @@ def destroy

private

# Download active storage files on server in a temporary folder
#
# @param files [ActiveStorage::Attached::Many] files to save
# @return [Array<String>] files paths of saved files
def save_files_on_server(files)
# get a temporary folder and create it
temp_folder = File.join(Dir.tmpdir, 'user')
FileUtils.mkdir_p(temp_folder) unless Dir.exist?(temp_folder)

# download all ActiveStorage into
files.map do |picture|
filename = picture.filename.to_s
filepath = File.join temp_folder, filename
File.open(filepath, 'wb') { |f| f.write(picture.download) }
filepath
end
end

# Create a temporary zip file & return the content as bytes
#
# @param filepaths [Array<String>] files paths
# @return [String] as content of zip
def create_temporary_zip_file(filepaths)
require 'zip'
temp_file = Tempfile.new('user.zip')

begin
# Initialize the temp file as a zip file
Zip::OutputStream.open(temp_file) { |zos| }

# open the zip
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zip|
filepaths.each do |filepath|
filename = File.basename filepath
# add file into the zip
zip.add filename, filepath
end
end

return File.read(temp_file.path)
ensure
# close all ressources & remove temporary files
temp_file.close
temp_file.unlink
filepaths.each { |filepath| FileUtils.rm(filepath) }
end
end

# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])

0 comments on commit 67a8bcb

Please sign in to comment.