diff --git a/FileLiberator/DownloadFile.cs b/FileLiberator/DownloadFile.cs index dd67f8e0..9f23b1e0 100644 --- a/FileLiberator/DownloadFile.cs +++ b/FileLiberator/DownloadFile.cs @@ -18,7 +18,7 @@ namespace FileLiberator var client = new HttpClient(); var progress = new Progress(); - progress.ProgressChanged += OnProgressChanged; + progress.ProgressChanged += (_, e) => StreamingProgressChanged?.Invoke(this, e); StreamingBegin?.Invoke(this, proposedDownloadFilePath); @@ -32,9 +32,5 @@ namespace FileLiberator StreamingCompleted?.Invoke(this, proposedDownloadFilePath); } } - private void OnProgressChanged(object sender, DownloadProgress e) - { - StreamingProgressChanged.Invoke(this, e); - } } } diff --git a/FileLiberator/IProcessableExt.cs b/FileLiberator/IProcessableExt.cs index eff721d2..3a4339e3 100644 --- a/FileLiberator/IProcessableExt.cs +++ b/FileLiberator/IProcessableExt.cs @@ -23,17 +23,12 @@ namespace FileLiberator .GetLibrary_Flat_NoTracking() .Where(libraryBook => processable.Validate(libraryBook)); - public static async Task ProcessSingleAsync(this IProcessable processable, LibraryBook libraryBook) + public static async Task ProcessSingleAsync(this IProcessable processable, LibraryBook libraryBook, bool validate) { - if (!processable.Validate(libraryBook)) + if (validate && !processable.Validate(libraryBook)) return new StatusHandler { "Validation failed" }; - return await processable.ProcessBookAsync_NoValidation(libraryBook); - } - - public static async Task ProcessBookAsync_NoValidation(this IProcessable processable, LibraryBook libraryBook) - { - Serilog.Log.Logger.Information("Begin " + nameof(ProcessBookAsync_NoValidation) + " {@DebugInfo}", new + Serilog.Log.Logger.Information("Begin " + nameof(ProcessSingleAsync) + " {@DebugInfo}", new { libraryBook.Book.Title, libraryBook.Book.AudibleProductId, diff --git a/LibationLauncher/LibationLauncher.csproj b/LibationLauncher/LibationLauncher.csproj index 7f4ef331..67686809 100644 --- a/LibationLauncher/LibationLauncher.csproj +++ b/LibationLauncher/LibationLauncher.csproj @@ -13,7 +13,7 @@ win-x64 - 5.4.9.264 + 5.4.9.269 diff --git a/LibationLauncher/Program.cs b/LibationLauncher/Program.cs index 1cfbda22..bcfb1f4d 100644 --- a/LibationLauncher/Program.cs +++ b/LibationLauncher/Program.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; -using AudibleApi; using AudibleApi.Authorization; using DataLayer; using Microsoft.EntityFrameworkCore; @@ -13,7 +12,6 @@ using FileManager; using InternalUtilities; using LibationWinForms; using LibationWinForms.Dialogs; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Serilog; diff --git a/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.cs b/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.cs index 6ba3b4ee..a982958b 100644 --- a/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.cs +++ b/LibationWinForms/BookLiberation/BaseForms/AudioDecodeBaseForm.cs @@ -40,9 +40,9 @@ namespace LibationWinForms.BookLiberation private void OnUnsubscribeAll(object sender, EventArgs e) { - Disposed -= OnUnsubscribeAll; if (Streamable is IAudioDecodable audioDecodable) { + Disposed -= OnUnsubscribeAll; audioDecodable.RequestCoverArt -= OnRequestCoverArt; audioDecodable.TitleDiscovered -= OnTitleDiscovered; audioDecodable.AuthorsDiscovered -= OnAuthorsDiscovered; @@ -62,10 +62,10 @@ namespace LibationWinForms.BookLiberation FileManager.PictureSize._500x500)); //Set default values from library - OnTitleDiscovered(null, libraryBook.Book.Title); - OnAuthorsDiscovered(null, string.Join(", ", libraryBook.Book.Authors)); - OnNarratorsDiscovered(null, string.Join(", ", libraryBook.Book.NarratorNames)); - OnCoverImageDiscovered(null, + OnTitleDiscovered(sender, libraryBook.Book.Title); + OnAuthorsDiscovered(sender, string.Join(", ", libraryBook.Book.Authors)); + OnNarratorsDiscovered(sender, string.Join(", ", libraryBook.Book.NarratorNames)); + OnCoverImageDiscovered(sender, FileManager.PictureStorage.GetPicture( new FileManager.PictureDefinition( libraryBook.Book.PictureId, @@ -74,7 +74,6 @@ namespace LibationWinForms.BookLiberation #endregion #region IStreamable event handler overrides - public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { if (!downloadProgress.ProgressPercentage.HasValue) @@ -88,11 +87,9 @@ namespace LibationWinForms.BookLiberation public override void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) => updateRemainingTime((int)timeRemaining.TotalSeconds); - #endregion #region IAudioDecodable event handlers - public virtual void OnRequestCoverArt(object sender, Action setCoverArtDelegate) => setCoverArtDelegate(GetCoverArtDelegate?.Invoke()); @@ -117,16 +114,13 @@ namespace LibationWinForms.BookLiberation public virtual void OnCoverImageDiscovered(object sender, byte[] coverArt) => pictureBox1.UIThread(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt)); - #endregion - // thread-safe UI updates private void updateBookInfo() => bookInfoLbl.UIThread(() => bookInfoLbl.Text = $"{title}\r\nBy {authorNames}\r\nNarrated by {narratorNames}"); private void updateRemainingTime(int remaining) => remainingTimeLbl.UIThread(() => remainingTimeLbl.Text = $"ETA:\r\n{remaining} sec"); - } } diff --git a/LibationWinForms/BookLiberation/BaseForms/ProcessBaseForm.cs b/LibationWinForms/BookLiberation/BaseForms/ProcessBaseForm.cs index 2b59a31d..c57aaa8b 100644 --- a/LibationWinForms/BookLiberation/BaseForms/ProcessBaseForm.cs +++ b/LibationWinForms/BookLiberation/BaseForms/ProcessBaseForm.cs @@ -22,7 +22,7 @@ namespace LibationWinForms.BookLiberation //Don't unsubscribe from Dispose because it fires on //IStreamable.StreamingCompleted, and the IProcessable - //events need to live past that. + //events need to live past that event. processable.Completed += OnUnsubscribeAll; } } @@ -42,7 +42,6 @@ namespace LibationWinForms.BookLiberation public virtual void OnBegin(object sender, LibraryBook libraryBook) => LogMe.Info($"Begin: {libraryBook.Book}"); public virtual void OnStatusUpdate(object sender, string statusUpdate) => LogMe.Info("- " + statusUpdate); public virtual void OnCompleted(object sender, LibraryBook libraryBook) => LogMe.Info($"Completed: {libraryBook.Book}{Environment.NewLine}"); - #endregion } } diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index 1575be89..de57f6b5 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -79,7 +79,7 @@ namespace LibationWinForms.BookLiberation var automatedBackupsForm = new AutomatedBackupsForm(); var logMe = LogMe.RegisterForm(automatedBackupsForm); - var convertBook = CreateStreamProcessable(null, logMe); + var convertBook = CreateStreamProcessable(logMe); await new BackupLoop(logMe, convertBook, automatedBackupsForm).RunBackupAsync(); } @@ -91,7 +91,7 @@ namespace LibationWinForms.BookLiberation var automatedBackupsForm = new AutomatedBackupsForm(); var logMe = LogMe.RegisterForm(automatedBackupsForm); - var downloadPdf = CreateStreamProcessable(completedAction, logMe); + var downloadPdf = CreateStreamProcessable(logMe, completedAction); await new BackupLoop(logMe, downloadPdf, automatedBackupsForm).RunBackupAsync(); } @@ -107,25 +107,22 @@ namespace LibationWinForms.BookLiberation } var downloadFile = CreateStreamable(onDownloadFileStreamingCompleted); - - new System.Threading.Thread(() => downloadFile.PerformDownloadFileAsync(url, destination).GetAwaiter().GetResult()) - { IsBackground = true } - .Start(); + async void runDownload() => await downloadFile.PerformDownloadFileAsync(url, destination); + new Task(runDownload).Start(); } private static IProcessable CreateBackupBook(EventHandler completedAction, LogMe logMe) { - var downloadPdf = CreateStreamProcessable(null, logMe); + var downloadPdf = CreateStreamProcessable(logMe); //Chain pdf download on DownloadDecryptBook.Completed async void onDownloadDecryptBookCompleted(object sender, LibraryBook e) { await downloadPdf.TryProcessAsync(e); - completedAction(sender, e); } - var downloadDecryptBook = CreateStreamProcessable(onDownloadDecryptBookCompleted, logMe); + var downloadDecryptBook = CreateStreamProcessable(logMe, onDownloadDecryptBookCompleted); return downloadDecryptBook; } @@ -134,9 +131,10 @@ namespace LibationWinForms.BookLiberation /// /// The derrived type to create. /// The derrived Form to create on , Show on , and Close & Dispose on + /// The logger /// An additional event handler to handle /// A new of type - private static TStrProc CreateStreamProcessable(EventHandler completedAction = null, LogMe logMe = null) + private static TStrProc CreateStreamProcessable(LogMe logMe, EventHandler completedAction = null) where TForm : ProcessBaseForm, new() where TStrProc : IStreamProcessable, new() { @@ -192,9 +190,9 @@ namespace LibationWinForms.BookLiberation } protected abstract Task RunAsync(); - protected abstract string SkipDialogText { get; } protected abstract MessageBoxButtons SkipDialogButtons { get; } + protected abstract MessageBoxDefaultButton SkipDialogDefaultButton { get; } protected abstract DialogResult CreateSkipFileResult { get; } public async Task RunBackupAsync() @@ -214,13 +212,13 @@ namespace LibationWinForms.BookLiberation LogMe.Info("DONE"); } - protected async Task ProcessOneAsync(Func> func, LibraryBook libraryBook) + protected async Task ProcessOneAsync(LibraryBook libraryBook, bool validate) { string logMessage; try { - var statusHandler = await func(libraryBook); + var statusHandler = await Processable.ProcessSingleAsync(libraryBook, validate); if (statusHandler.IsSuccess) return true; @@ -258,7 +256,7 @@ $@" Title: {libraryBook.Book.Title} details = "[Error retrieving details]"; } - var dialogResult = MessageBox.Show(string.Format(SkipDialogText, details), "Skip importing this book?", SkipDialogButtons, MessageBoxIcon.Question); + var dialogResult = MessageBox.Show(string.Format(SkipDialogText, details), "Skip importing this book?", SkipDialogButtons, MessageBoxIcon.Question, SkipDialogDefaultButton); if (dialogResult == DialogResult.Abort) return false; @@ -291,6 +289,7 @@ An error occurred while trying to process this book. Skip this book permanently? - Click NO to skip the book this time only. We'll try again later. ".Trim(); protected override MessageBoxButtons SkipDialogButtons => MessageBoxButtons.YesNo; + protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button2; protected override DialogResult CreateSkipFileResult => DialogResult.Yes; public BackupSingle(LogMe logMe, IProcessable processable, LibraryBook libraryBook) @@ -302,7 +301,7 @@ An error occurred while trying to process this book. Skip this book permanently? protected override async Task RunAsync() { if (_libraryBook is not null) - await ProcessOneAsync(Processable.ProcessSingleAsync, _libraryBook); + await ProcessOneAsync(_libraryBook, validate: true); } } @@ -319,6 +318,7 @@ An error occurred while trying to process this book. - IGNORE: Permanently ignore this book. Continue processing books. (Will not try this book again later.) ".Trim(); protected override MessageBoxButtons SkipDialogButtons => MessageBoxButtons.AbortRetryIgnore; + protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button1; protected override DialogResult CreateSkipFileResult => DialogResult.Ignore; public BackupLoop(LogMe logMe, IProcessable processable, AutomatedBackupsForm automatedBackupsForm) @@ -329,7 +329,7 @@ An error occurred while trying to process this book. // support for 'skip this time only' requires state. iterators provide this state for free. therefore: use foreach/iterator here foreach (var libraryBook in Processable.GetValidLibraryBooks()) { - var keepGoing = await ProcessOneAsync(Processable.ProcessBookAsync_NoValidation, libraryBook); + var keepGoing = await ProcessOneAsync(libraryBook, validate: false); if (!keepGoing) return;