diff --git a/CHANGELOG.yml b/CHANGELOG.yml index adee26d..0b6bb0a 100644 --- a/CHANGELOG.yml +++ b/CHANGELOG.yml @@ -1,3 +1,5 @@ +0.3.0: + - correct subfolders creation (and break some methods signature) 0.2.0: - move some methods to avoid to polute controller methods - `ActiveStorage::SendZip#save_files_on_server` become `ActiveStorage::SendZipHelperSendZip#save_files_on_server` diff --git a/lib/active_storage/send_zip/version.rb b/lib/active_storage/send_zip/version.rb index a59b205..e522d55 100644 --- a/lib/active_storage/send_zip/version.rb +++ b/lib/active_storage/send_zip/version.rb @@ -1,6 +1,6 @@ module ActiveStorage module SendZip # The version of this gem - VERSION = '0.2.0'.freeze + VERSION = '0.3.0'.freeze end end diff --git a/lib/active_storage/send_zip_helper.rb b/lib/active_storage/send_zip_helper.rb index 16d017c..c5702f6 100644 --- a/lib/active_storage/send_zip_helper.rb +++ b/lib/active_storage/send_zip_helper.rb @@ -10,23 +10,26 @@ module SendZipHelper # Download active storage files on server in a temporary folder # # @param files [ActiveStorage::Attached::Many] files to save - # @return [Array] files paths of saved files + # @return [String] folder path of saved files def self.save_files_on_server(files) require 'zip' # get a temporary folder and create it temp_folder = Dir.mktmpdir 'active_storage-send_zip' if files.is_a? Array - return files.map { |file| save_file_on_server(file, temp_folder) } + files.each { |file| save_file_on_server(file, temp_folder) } elsif files.is_a? Hash filepaths = [] files.each do |subfolder, filesHash| - filesHash.each { |f| filepaths << save_file_on_server(f, temp_folder, subfolder: subfolder) } + filesHash = [filesHash] unless filesHash.is_a? Array + filesHash.each do |f| + filepaths << save_file_on_server(f, temp_folder, subfolder: subfolder.to_s) + end end - - return filepaths end + + temp_folder end # Save the given file on the server @@ -59,10 +62,13 @@ def self.save_file_on_server(file, folder, subfolder: nil) # Create a temporary zip file & return the content as bytes # - # @param filepaths [Array] files paths + # @param folderpath [String] folder path # @return [String] as content of zip - def self.create_temporary_zip_file(filepaths) + def self.create_temporary_zip_file(folderpath) temp_file = Tempfile.new('user.zip') + folderpath_glob = File.join folderpath, '**', '*' + + files = Dir.glob(folderpath_glob).reject { |e| File.directory? e } begin # Initialize the temp file as a zip file @@ -70,19 +76,18 @@ def self.create_temporary_zip_file(filepaths) # 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 + files.each do |filepath| + filepath_zip = filepath.sub(folderpath, '').sub(File::SEPARATOR, '') + zip.add filepath_zip, 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) } + # temp_file.close + # temp_file.unlink + # FileUtils.rm_rf(folderpath) end end end diff --git a/test/active_storage/send_zip_helper_test.rb b/test/active_storage/send_zip_helper_test.rb index 747d1d8..2247fe7 100644 --- a/test/active_storage/send_zip_helper_test.rb +++ b/test/active_storage/send_zip_helper_test.rb @@ -51,17 +51,47 @@ def test_it_should_save_files_in_differents_folders ActiveStorageMock.new('bar.txt') ] } - files_saved = ActiveStorage::SendZipHelper.save_files_on_server(files) - assert_equal 2, files_saved.map { |f| File.dirname f }.uniq.count - assert_equal 3, files_saved.count - refute_nil ActiveStorage::SendZipHelper.create_temporary_zip_file(files_saved) + assert_produce_nested_files files, folder_count: 2, files_count: 3 + end + + def test_it_should_save_files_in_differents_folders_with_root_files + files = { + 'folder A' => [ + ActiveStorageMock.new('foo.txt'), + ActiveStorageMock.new('foo.txt') + ], + 'folder B' => [ + ActiveStorageMock.new('bar.txt') + ], + 0 => ActiveStorageMock.new('foo.txt'), + 1 => ActiveStorageMock.new('bar.txt') + } + assert_produce_nested_files files, folder_count: 4, files_count: 5 end private + def assert_produce_nested_files(files, folder_count: 1, files_count: 1) + temp_folder = ActiveStorage::SendZipHelper.save_files_on_server(files) + temp_folder_glob = File.join temp_folder, '**', '*' + + glob = Dir.glob(temp_folder_glob) + + files_paths = glob.reject { |e| File.directory? e } + folders_paths = glob.select { |e| File.directory? e } + + assert_equal folder_count, folders_paths.count + assert_equal files_count, files_paths.count + refute_nil ActiveStorage::SendZipHelper.create_temporary_zip_file(temp_folder) + end + def assert_produce_files(files, count: 1) - files_saved = ActiveStorage::SendZipHelper.save_files_on_server(files) - assert_equal count, files_saved.count - refute_nil ActiveStorage::SendZipHelper.create_temporary_zip_file(files_saved) + temp_folder = ActiveStorage::SendZipHelper.save_files_on_server(files) + + temp_folder_glob = File.join temp_folder, '**', '*' + files_path = Dir.glob(temp_folder_glob).reject { |e| File.directory? e } + + assert_equal count, files_path.count + refute_nil ActiveStorage::SendZipHelper.create_temporary_zip_file(temp_folder) end end