From f1b1cd97ec308e9bda91b5b6c6e930af4d5c9ff5 Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Wed, 15 Jul 2020 17:04:24 -0400 Subject: [PATCH] Improvements for leaf data zipping --- Core/Entities/LeafInput.cs | 89 +++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/Core/Entities/LeafInput.cs b/Core/Entities/LeafInput.cs index 47b59d1..163f099 100644 --- a/Core/Entities/LeafInput.cs +++ b/Core/Entities/LeafInput.cs @@ -139,77 +139,92 @@ namespace LeafWeb.Core.Entities return $"{Id}_{Identifier}"; } + #region Zip + /// - /// Contains all output files in a zip - /// - public byte[] GetOutputFileZip(LeafOutputFileType? fileType) + /// Contains all output files in a zip + /// + public byte[] GetOutputFileZip(LeafOutputFileType? fileType) { return NewMemoryZipArchive((archive, stream) => - CompressOutputFiles( - OutputFiles.Where(f => !fileType.HasValue || f.FileType == fileType.Value), - archive)); + CompressOutputFiles(archive, OutputFiles.Where(f => !fileType.HasValue || f.FileType == fileType.Value))); } /// /// Contains all input files in a zip /// public byte[] GetInputFileZip() => - NewMemoryZipArchive((archive, stream) => CompressInputFiles(InputFiles, archive)); + NewMemoryZipArchive((archive, stream) => CompressInputFiles(archive, InputFiles)); /// - /// Contains all input files in a zip, ordered into directories + /// Contains all input files files in a zip, ordered into directories /// public static byte[] GetInputFilesZip(IEnumerable leafInputs) => - NewMemoryZipArchive((archive, stream) => - { - var inputs = leafInputs.ToList(); - - foreach (var leafInput in inputs) - { - if (stream.Length > 2560000L) - continue; - var directory = $"{leafInput.Added:yyyy-dd-MM--HH-mm}_{leafInput.Identifier.FilterValidFilename()}"; - CompressInputFiles(leafInput.InputFiles, - archive, directory); - } - }); + GetLeafFilesZip( + leafInputs, + (archive, input, directory) => + CompressInputFiles(archive, input.InputFiles, directory)); /// - /// Contains all input files in a zip, ordered into directories + /// Contains all output files files in a zip, ordered into directories /// public static byte[] GetOutputFilesZip_ToUser(IEnumerable leafInputs) => + GetLeafFilesZip( + leafInputs, + (archive, input, directory) => + CompressOutputFiles(archive, input.OutputFiles + .Where(f => f.FileType == LeafOutputFileType.ToUser), + directory)); + + private static byte[] GetLeafFilesZip(IEnumerable leafInputs, + Action compressAction) => NewMemoryZipArchive((archive, stream) => { var inputs = leafInputs.ToList(); + var leftBehindFiles = new List(); + foreach (var leafInput in inputs) { if (stream.Length > 2560000L) + { + leftBehindFiles.Add(leafInput.Identifier.FilterValidFilename()); continue; + } + var directory = $"{leafInput.Added:yyyy-dd-MM--HH-mm}_{leafInput.Identifier.FilterValidFilename()}"; - CompressOutputFiles(leafInput.OutputFiles - .Where(f => f.FileType == LeafOutputFileType.ToUser), - archive, directory); + compressAction(archive, leafInput, directory); + } + + if (leftBehindFiles.Count > 0) + { + leftBehindFiles.Insert(0, "NOTICE. The following LeafInput were not included due to file size issue."); + leftBehindFiles.Insert(1, "---"); + CompressStringToFile(archive, leftBehindFiles.Join(Environment.NewLine), "README.TXT"); } }); private static byte[] NewMemoryZipArchive(Action addFiles) { using (var compressedFileStream = new MemoryStream()) - using (var archive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, true)) { - addFiles(archive, compressedFileStream); + using (var archive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, true)) + { + addFiles(archive, compressedFileStream); + } + // ZipArchive must be disposed before returning the data return compressedFileStream.ToArray(); } } - private static long CompressInputFiles(IEnumerable inputFiles, ZipArchive archive, string prefix = "") + private static long CompressInputFiles(ZipArchive archive, IEnumerable inputFiles, + string directory = "") { var contentsLength = 0L; foreach (var inputFile in inputFiles) { contentsLength += inputFile.Contents.LongLength; - var entry = archive.CreateEntry(Path.Combine(prefix, inputFile.Filename)); + var entry = archive.CreateEntry(Path.Combine(directory, inputFile.Filename)); using (var originalFileStream = new MemoryStream(inputFile.Contents)) using (var entryStream = entry.Open()) originalFileStream.CopyTo(entryStream); @@ -218,13 +233,14 @@ namespace LeafWeb.Core.Entities return contentsLength; } - private static long CompressOutputFiles(IEnumerable outputFiles, ZipArchive archive, string prefix = "") + private static long CompressOutputFiles(ZipArchive archive, IEnumerable outputFiles, + string directory = "") { var contentsLength = 0L; foreach (var outputFile in outputFiles) { contentsLength += outputFile.FileContents.Contents.LongLength; - var entry = archive.CreateEntry(Path.Combine(prefix, outputFile.Filename)); + var entry = archive.CreateEntry(Path.Combine(directory, outputFile.Filename)); using (var originalFileStream = new MemoryStream(outputFile.FileContents.Contents)) using (var entryStream = entry.Open()) originalFileStream.CopyTo(entryStream); @@ -232,9 +248,20 @@ namespace LeafWeb.Core.Entities return contentsLength; } + private static void CompressStringToFile(ZipArchive archive, string contents, string filename) + { + var entry = archive.CreateEntry(filename); + using (var writer = new StreamWriter(entry.Open())) + { + writer.Write(contents); + } + } + public int GetOutputFileSizeSum() { return OutputFiles.Sum(o => o.FileContents.Contents.Length); } + + #endregion } } \ No newline at end of file