From 4e58471d40334f762aee74f35300f8a1da011147 Mon Sep 17 00:00:00 2001 From: DSPAUL Date: Sat, 20 Apr 2024 23:27:03 +0200 Subject: [PATCH] Replace DotNetZip with Sharpcompress --- src/COMPASS.csproj | 8 +-- src/Services/IOService.cs | 16 +++--- src/ViewModels/CollectionViewModel.cs | 10 ++-- src/ViewModels/ExportCollectionViewModel.cs | 38 ++++++------- src/ViewModels/SettingsViewModel.cs | 63 +++++++-------------- src/Windows/SettingsWindow.xaml | 7 +++ 6 files changed, 65 insertions(+), 77 deletions(-) diff --git a/src/COMPASS.csproj b/src/COMPASS.csproj index 139bd5f0..8e0582b1 100644 --- a/src/COMPASS.csproj +++ b/src/COMPASS.csproj @@ -62,13 +62,12 @@ - - + - + @@ -77,7 +76,8 @@ - + + diff --git a/src/Services/IOService.cs b/src/Services/IOService.cs index 9fe8417a..5a871d03 100644 --- a/src/Services/IOService.cs +++ b/src/Services/IOService.cs @@ -4,10 +4,11 @@ using COMPASS.Tools; using COMPASS.ViewModels; using HtmlAgilityPack; -using Ionic.Zip; using Microsoft.Win32; using Newtonsoft.Json.Linq; using Ookii.Dialogs.Wpf; +using SharpCompress.Archives; +using SharpCompress.Archives.Zip; using System; using System.Collections.Generic; using System.Diagnostics; @@ -135,7 +136,7 @@ public static async Task UnZipCollection(string path) ClearTmpData(tmpCollectionPath); //unzip the file to tmp folder - using ZipFile zip = ZipFile.Read(path); + using ZipArchive archive = ZipArchive.Open(path); //report progress var progressVM = ProgressViewModel.GetInstance(); @@ -144,11 +145,12 @@ public static async Task UnZipCollection(string path) progressVM.TotalAmount = 1; //extract - await Task.Run(() => zip.ExtractAll(tmpCollectionPath)); + await Task.Run(() => archive.ExtractToDirectory(tmpCollectionPath)); //TODO add cancelation and progress reporting progressVM.IncrementCounter(); return tmpCollectionPath; } + public static void ClearTmpData(string? tempPath = null) { if (tempPath == null) @@ -283,9 +285,9 @@ public static string[] PickFolders() } //Check compatibility - using (ZipFile zip = ZipFile.Read(path)) + using (ZipArchive archive = ZipArchive.Open(path)) { - var satchelInfoFile = zip.SingleOrDefault(entry => entry.FileName == Constants.SatchelInfoFileName); + var satchelInfoFile = archive.Entries.SingleOrDefault(entry => entry.Key == Constants.SatchelInfoFileName); if (satchelInfoFile == null) { //No version information means we cannot ensure compatibility, so abort @@ -298,7 +300,7 @@ public static string[] PickFolders() //Read the file contents using var stream = new MemoryStream(); - satchelInfoFile.Extract(stream); + satchelInfoFile.WriteTo(stream); stream.Seek(0, SeekOrigin.Begin); using StreamReader reader = new(stream); string json = reader.ReadToEnd(); @@ -317,7 +319,7 @@ public static string[] PickFolders() var currentVersion = Assembly.GetExecutingAssembly().GetName().Version!; var minVersions = new List { currentVersion }; //keep a list of min requirements - var filesInZip = zip.Select(entry => entry.FileName).ToList(); + var filesInZip = archive.Entries.Select(entry => entry.Key).ToList(); //Check Codex version if (filesInZip.Contains(Constants.CodicesFileName)) diff --git a/src/ViewModels/CollectionViewModel.cs b/src/ViewModels/CollectionViewModel.cs index ca5697f5..98f90b6f 100644 --- a/src/ViewModels/CollectionViewModel.cs +++ b/src/ViewModels/CollectionViewModel.cs @@ -5,8 +5,10 @@ using COMPASS.Tools; using COMPASS.ViewModels.Import; using COMPASS.Windows; -using Ionic.Zip; using Microsoft.Win32; +using SharpCompress.Archives; +using SharpCompress.Archives.Zip; +using SharpCompress.Common; using System; using System.Collections.ObjectModel; using System.Diagnostics; @@ -376,11 +378,11 @@ public void ExportTags() CurrentCollection.SaveTags(); string targetPath = saveFileDialog.FileName; - using ZipFile zip = new(); - zip.AddFile(CurrentCollection.TagsDataFilePath, ""); + using var archive = ZipArchive.Create(); + archive.AddEntry(Constants.TagsFileName, CurrentCollection.TagsDataFilePath); //Export - zip.Save(targetPath); + archive.SaveTo(targetPath, CompressionType.None); Logger.Info($"Exported Tags from {CurrentCollection.DirectoryName} to {targetPath}"); } diff --git a/src/ViewModels/ExportCollectionViewModel.cs b/src/ViewModels/ExportCollectionViewModel.cs index 65fefa4d..82ba4d88 100644 --- a/src/ViewModels/ExportCollectionViewModel.cs +++ b/src/ViewModels/ExportCollectionViewModel.cs @@ -2,8 +2,10 @@ using COMPASS.Models; using COMPASS.Services; using COMPASS.Tools; -using Ionic.Zip; using Microsoft.Win32; +using SharpCompress.Archives; +using SharpCompress.Archives.Zip; +using SharpCompress.Common; using System; using System.IO; using System.Linq; @@ -128,8 +130,7 @@ public async Task ExportToFile(string targetPath) ContentSelectorVM.CuratedCollection.InitAsNew(); ContentSelectorVM.CuratedCollection.Save(); - using ZipFile zip = new(); - zip.AddDirectory(ContentSelectorVM.CuratedCollection.FullDataPath); + using var archive = ZipArchive.Create(); //Change Codex Path to relative and add those files if the options is set var itemsWithOfflineSource = ContentSelectorVM.CuratedCollection.AllCodices @@ -143,8 +144,7 @@ public async Task ExportToFile(string targetPath) //Add the file if (IncludeFiles && File.Exists(codex.Path)) { - int indexStartFilename = relativePath.Length - Path.GetFileName(codex.Path)!.Length; - zip.AddFile(codex.Path, Path.Combine("Files", relativePath[0..indexStartFilename])); + archive.AddEntry(Path.Combine("Files", relativePath), codex.Path); //keep the relative path, will be used during import to link the included files codex.Path = relativePath; } @@ -158,36 +158,28 @@ public async Task ExportToFile(string targetPath) //Add cover art if (IncludeCoverArt && File.Exists(codex.CoverArt)) { - zip.AddFile(codex.CoverArt, "CoverArt"); + archive.AddEntry(Path.Combine("CoverArt", Path.GetFileName(codex.CoverArt)), codex.CoverArt); } } + //Save changes ContentSelectorVM.CuratedCollection.SaveCodices(); - zip.UpdateFile(ContentSelectorVM.CuratedCollection.CodicesDataFilePath, ""); + + //Now add xml files + archive.AddAllFromDirectory(ContentSelectorVM.CuratedCollection.FullDataPath); //Progress reporting progressVM.Text = "Exporting Collection"; progressVM.ShowCount = false; progressVM.ResetCounter(); - zip.SaveProgress += (_, args) => - { - progressVM.TotalAmount = Math.Max(progressVM.TotalAmount, args.EntriesTotal); - if (args.EventType == ZipProgressEventType.Saving_AfterWriteEntry) - { - progressVM.IncrementCounter(); - } - }; + //TODO find new way to track progress //Add version so we can check compatibility when importing SatchelInfo info = new(); - zip.AddEntry(Constants.SatchelInfoFileName, JsonSerializer.Serialize(info)); + archive.AddEntry(Constants.SatchelInfoFileName, new MemoryStream(JsonSerializer.SerializeToUtf8Bytes(info))); //Export - await Task.Run(() => - { - zip.Save(targetPath); - Directory.Delete(ContentSelectorVM.CuratedCollection.FullDataPath, true); - }); + await Task.Run(() => archive.SaveTo(targetPath, CompressionType.None)); Logger.Info($"Exported {CollectionToExport.DirectoryName} to {targetPath}"); } catch (Exception ex) @@ -196,6 +188,10 @@ await Task.Run(() => progressVM.Clear(); CloseAction?.Invoke(); } + finally + { + Directory.Delete(ContentSelectorVM.CuratedCollection.FullDataPath, true); + } } public void UpdateSteps() diff --git a/src/ViewModels/SettingsViewModel.cs b/src/ViewModels/SettingsViewModel.cs index e53a8f13..aa4f0d0b 100644 --- a/src/ViewModels/SettingsViewModel.cs +++ b/src/ViewModels/SettingsViewModel.cs @@ -6,8 +6,9 @@ using COMPASS.Tools; using COMPASS.ViewModels.Import; using COMPASS.Windows; -using Ionic.Zip; using Microsoft.Win32; +using SharpCompress.Archives; +using SharpCompress.Archives.Zip; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -689,13 +690,11 @@ public void BrowseLocalFiles() Process.Start(startInfo); } - private readonly BackgroundWorker _createZipWorker = new(); - private readonly BackgroundWorker _extractZipWorker = new(); private LoadingWindow? _lw; - private RelayCommand? _backupLocalFilesCommand; - public RelayCommand BackupLocalFilesCommand => _backupLocalFilesCommand ??= new(BackupLocalFiles); - public void BackupLocalFiles() + private AsyncRelayCommand? _backupLocalFilesCommand; + public AsyncRelayCommand BackupLocalFilesCommand => _backupLocalFilesCommand ??= new(BackupLocalFiles); + public async Task BackupLocalFiles() { SaveFileDialog saveFileDialog = new() { @@ -712,16 +711,19 @@ public void BackupLocalFiles() MainViewModel.CollectionVM.CurrentCollection.Save(); SavePreferences(); - _createZipWorker.DoWork += CreateZip; - _createZipWorker.RunWorkerCompleted += CreateZipDone; + await Task.Run(() => CompressUserDataToZip(targetPath)); - _createZipWorker.RunWorkerAsync(targetPath); + _lw.Close(); } } - private RelayCommand? _restoreBackupCommand; - public RelayCommand RestoreBackupCommand => _restoreBackupCommand ??= new(RestoreBackup); - public void RestoreBackup() + private void CompressUserDataToZip(string zipPath) => + //zip up collections, easiest with system.IO.Compression + System.IO.Compression.ZipFile.CreateFromDirectory(CodexCollection.CollectionsPath, zipPath, System.IO.Compression.CompressionLevel.Optimal, true); + + private AsyncRelayCommand? _restoreBackupCommand; + public AsyncRelayCommand RestoreBackupCommand => _restoreBackupCommand ??= new(RestoreBackup); + public async Task RestoreBackup() { OpenFileDialog openFileDialog = new() { @@ -734,44 +736,23 @@ public void RestoreBackup() _lw = new("Restoring Backup"); _lw.Show(); - _extractZipWorker.DoWork += ExtractZip; - _extractZipWorker.RunWorkerCompleted += ExtractZipDone; - - _extractZipWorker.RunWorkerAsync(targetPath); - } - } + await Task.Run(() => ExtractZip(targetPath)); - private void CreateZip(object? sender, DoWorkEventArgs e) - { - if (e.Argument is not string targetPath) - { - return; + //restore collection that was open + MainViewModel.CollectionVM.CurrentCollection = new(Properties.Settings.Default.StartupCollection); + _lw?.Close(); } - - using ZipFile zip = new(); - zip.AddDirectory(CodexCollection.CollectionsPath, "Collections"); - zip.AddFile(PreferencesFilePath, ""); - zip.Save(targetPath); } - private void ExtractZip(object? sender, DoWorkEventArgs e) + private void ExtractZip(string sourcePath) { - if (e.Argument is not string sourcePath || !Path.Exists(sourcePath)) + if (!Path.Exists(sourcePath)) { Logger.Warn($"Cannot extract sourcePath as it does not exit"); return; } - using ZipFile zip = ZipFile.Read(sourcePath); - zip.ExtractAll(CompassDataPath, ExtractExistingFileAction.OverwriteSilently); - } - - private void CreateZipDone(object? sender, RunWorkerCompletedEventArgs e) => _lw?.Close(); - - private void ExtractZipDone(object? sender, RunWorkerCompletedEventArgs e) - { - //restore collection that was open - MainViewModel.CollectionVM.CurrentCollection = new(Properties.Settings.Default.StartupCollection); - _lw?.Close(); + using ZipArchive archive = ZipArchive.Open(sourcePath); + archive.ExtractToDirectory(CompassDataPath); } #endregion diff --git a/src/Windows/SettingsWindow.xaml b/src/Windows/SettingsWindow.xaml index a5dea991..97e18489 100644 --- a/src/Windows/SettingsWindow.xaml +++ b/src/Windows/SettingsWindow.xaml @@ -778,6 +778,13 @@ ScrapySharp --> + + + + SharpCompress + +