From f284f53eddc578d8a9c7653d9f0f3cba5d062720 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sat, 3 Jul 2021 20:21:11 -0600 Subject: [PATCH 1/4] Clicking on red stoplight now only decrypts that book with no conformation. --- .../ProcessorAutomationController.cs | 36 ++++++++++--------- LibationWinForms/ProductsGrid.cs | 10 +----- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index 1b6455e2..da02e3c2 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -47,13 +47,14 @@ namespace LibationWinForms.BookLiberation Serilog.Log.Logger.Information("Begin " + nameof(BackupSingleBookAsync) + " {@DebugInfo}", new { productId }); var backupBook = getWiredUpBackupBook(completedAction); - - (AutomatedBackupsForm automatedBackupsForm, LogMe logMe) = attachToBackupsForm(backupBook); - automatedBackupsForm.KeepGoingVisible = false; + + (Action unsibscribeEvents, LogMe logMe) = attachToBackupsForm(backupBook); var libraryBook = IProcessableExt.GetSingleLibraryBook(productId); // continue even if libraryBook is null. we'll display even that in the processing box - await new BackupSingle(logMe, backupBook, automatedBackupsForm, libraryBook).RunBackupAsync(); + await new BackupSingle(logMe, backupBook, libraryBook).RunBackupAsync(); + + unsibscribeEvents(); } public static async Task BackupAllBooksAsync(EventHandler completedAction = null) @@ -61,8 +62,12 @@ namespace LibationWinForms.BookLiberation Serilog.Log.Logger.Information("Begin " + nameof(BackupAllBooksAsync)); var backupBook = getWiredUpBackupBook(completedAction); + var automatedBackupsForm = new AutomatedBackupsForm(); + + (Action unsibscribeEvents, LogMe logMe) = attachToBackupsForm(backupBook, automatedBackupsForm); + + automatedBackupsForm.FormClosing += (_, __) => unsibscribeEvents(); - (AutomatedBackupsForm automatedBackupsForm, LogMe logMe) = attachToBackupsForm(backupBook); await new BackupLoop(logMe, backupBook, automatedBackupsForm).RunBackupAsync(); } @@ -93,11 +98,10 @@ namespace LibationWinForms.BookLiberation private static void updateIsLiberated(object sender, LibraryBook e) => ApplicationServices.SearchEngineCommands.UpdateIsLiberated(e.Book); - private static (AutomatedBackupsForm, LogMe) attachToBackupsForm(BackupBook backupBook) + private static (Action unsibscribeEvents, LogMe) attachToBackupsForm(BackupBook backupBook, AutomatedBackupsForm automatedBackupsForm = null) { - #region create form and logger - var automatedBackupsForm = new AutomatedBackupsForm(); - var logMe = LogMe.RegisterForm(automatedBackupsForm); + #region create logger + var logMe = automatedBackupsForm is null? new LogMe() : LogMe.RegisterForm(automatedBackupsForm); #endregion #region define how model actions will affect form behavior @@ -121,7 +125,7 @@ namespace LibationWinForms.BookLiberation #region when form closes, unsubscribe from model's events // unsubscribe so disposed forms aren't still trying to receive notifications - automatedBackupsForm.FormClosing += (_, __) => + Action unsibscribe = () => { backupBook.DecryptBook.Begin -= decryptBookBegin; backupBook.DecryptBook.StatusUpdate -= statusUpdate; @@ -132,7 +136,7 @@ namespace LibationWinForms.BookLiberation }; #endregion - return (automatedBackupsForm, logMe); + return (unsibscribe, logMe); } public static async Task BackupAllPdfsAsync(EventHandler completedAction = null) @@ -367,7 +371,7 @@ namespace LibationWinForms.BookLiberation protected IProcessable Processable { get; } protected AutomatedBackupsForm AutomatedBackupsForm { get; } - protected BackupRunner(LogMe logMe, IProcessable processable, AutomatedBackupsForm automatedBackupsForm) + protected BackupRunner(LogMe logMe, IProcessable processable, AutomatedBackupsForm automatedBackupsForm = null) { LogMe = logMe; Processable = processable; @@ -382,7 +386,7 @@ namespace LibationWinForms.BookLiberation public async Task RunBackupAsync() { - AutomatedBackupsForm.Show(); + AutomatedBackupsForm?.Show(); try { @@ -393,7 +397,7 @@ namespace LibationWinForms.BookLiberation LogMe.Error(ex); } - AutomatedBackupsForm.FinalizeUI(); + AutomatedBackupsForm?.FinalizeUI(); LogMe.Info("DONE"); } @@ -454,8 +458,8 @@ An error occurred while trying to process this book. Skip this book permanently? protected override MessageBoxButtons SkipDialogButtons => MessageBoxButtons.YesNo; protected override DialogResult CreateSkipFileResult => DialogResult.Yes; - public BackupSingle(LogMe logMe, IProcessable processable, AutomatedBackupsForm automatedBackupsForm, LibraryBook libraryBook) - : base(logMe, processable, automatedBackupsForm) + public BackupSingle(LogMe logMe, IProcessable processable, LibraryBook libraryBook) + : base(logMe, processable) { _libraryBook = libraryBook; } diff --git a/LibationWinForms/ProductsGrid.cs b/LibationWinForms/ProductsGrid.cs index 87f7e9f8..2e837432 100644 --- a/LibationWinForms/ProductsGrid.cs +++ b/LibationWinForms/ProductsGrid.cs @@ -182,15 +182,7 @@ namespace LibationWinForms return; } - // not liberated: liberate - var msg - = "Liberate entire library instead?" - + "\r\n\r\nClick Yes to begin liberating your entire library" - + "\r\n\r\nClick No to liberate this book only"; - if (MessageBox.Show(msg, "Liberate entire library?", MessageBoxButtons.YesNo) == DialogResult.Yes) - await BookLiberation.ProcessorAutomationController.BackupAllBooksAsync((_, libraryBook) => RefreshRow(libraryBook.Book.AudibleProductId)); - else - await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(productId, (_, __) => RefreshRow(productId)); + await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(productId, (_, __) => RefreshRow(productId)); } #endregion From d73701c939ec80443c1208563202c0090eedbe2c Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sat, 3 Jul 2021 20:34:50 -0600 Subject: [PATCH 2/4] Stop automatic processing if form is closed instead of crashing. --- .../BookLiberation/AutomatedBackupsForm.cs | 11 ++++++++--- .../BookLiberation/ProcessorAutomationController.cs | 7 +++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/LibationWinForms/BookLiberation/AutomatedBackupsForm.cs b/LibationWinForms/BookLiberation/AutomatedBackupsForm.cs index f663fe18..485e13be 100644 --- a/LibationWinForms/BookLiberation/AutomatedBackupsForm.cs +++ b/LibationWinForms/BookLiberation/AutomatedBackupsForm.cs @@ -24,13 +24,18 @@ namespace LibationWinForms.BookLiberation InitializeComponent(); } - public void WriteLine(string text) - => logTb.UIThread(() => logTb.AppendText($"{DateTime.Now} {text}{Environment.NewLine}")); + public void WriteLine(string text) + { + if (!IsDisposed) + logTb.UIThread(() => logTb.AppendText($"{DateTime.Now} {text}{Environment.NewLine}")); + } public void FinalizeUI() { keepGoingCb.Enabled = false; - logTb.AppendText(""); + + if (!IsDisposed) + logTb.AppendText(""); } private void AutomatedBackupsForm_FormClosing(object sender, FormClosingEventArgs e) => keepGoingCb.Checked = false; diff --git a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index da02e3c2..9703a66e 100644 --- a/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -66,9 +66,9 @@ namespace LibationWinForms.BookLiberation (Action unsibscribeEvents, LogMe logMe) = attachToBackupsForm(backupBook, automatedBackupsForm); - automatedBackupsForm.FormClosing += (_, __) => unsibscribeEvents(); - await new BackupLoop(logMe, backupBook, automatedBackupsForm).RunBackupAsync(); + + unsibscribeEvents(); } private static BackupBook getWiredUpBackupBook(EventHandler completedAction) @@ -496,6 +496,9 @@ An error occurred while trying to process this book if (!keepGoing) return; + if (AutomatedBackupsForm.IsDisposed) + break; + if (!AutomatedBackupsForm.KeepGoing) { if (AutomatedBackupsForm.KeepGoingVisible && !AutomatedBackupsForm.KeepGoingChecked) From 05426eb6180463f24256fcea8a907f3b2e9bf960 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sat, 3 Jul 2021 21:54:28 -0600 Subject: [PATCH 3/4] Added uri refresh to step 2. --- AaxDecrypter/AaxcDownloadConverter.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AaxDecrypter/AaxcDownloadConverter.cs b/AaxDecrypter/AaxcDownloadConverter.cs index b7d1d3fa..c24a8c14 100644 --- a/AaxDecrypter/AaxcDownloadConverter.cs +++ b/AaxDecrypter/AaxcDownloadConverter.cs @@ -142,6 +142,9 @@ namespace AaxDecrypter if (File.Exists(jsonDownloadState)) { nfsPersister = new NetworkFileStreamPersister(jsonDownloadState); + //If More thaan ~1 hour has elapsed since getting the download url, it will expire. + //The new url will be to the same file. + nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl)); } else { From 6d856f73e74cc907aa1e3ce707d4afd19ae0a1b5 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Sat, 3 Jul 2021 22:06:56 -0600 Subject: [PATCH 4/4] Reused yellow stoplight to indicate and interrupted and resumable download. --- FileLiberator/DownloadDecryptBook.cs | 3 +-- FileManager/AudibleFileStorage.cs | 14 +++++++------- LibationWinForms/Form1.cs | 2 +- LibationWinForms/GridEntry.cs | 4 ++-- LibationWinForms/ProductsGrid.cs | 6 +++--- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/FileLiberator/DownloadDecryptBook.cs b/FileLiberator/DownloadDecryptBook.cs index 60fcad80..9a9270d7 100644 --- a/FileLiberator/DownloadDecryptBook.cs +++ b/FileLiberator/DownloadDecryptBook.cs @@ -213,8 +213,7 @@ namespace FileLiberator } public bool Validate(LibraryBook libraryBook) - => !AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId) - && !AudibleFileStorage.AAX.Exists(libraryBook.Book.AudibleProductId); + => !AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId); public void Cancel() { diff --git a/FileManager/AudibleFileStorage.cs b/FileManager/AudibleFileStorage.cs index 3d1bf74f..d7db110c 100644 --- a/FileManager/AudibleFileStorage.cs +++ b/FileManager/AudibleFileStorage.cs @@ -9,7 +9,7 @@ using Dinah.Core.Collections.Generic; namespace FileManager { // could add images here, but for now images are stored in a well-known location - public enum FileType { Unknown, Audio, AAX, PDF } + public enum FileType { Unknown, Audio, AAXC, PDF } /// /// Files are large. File contents are never read by app. @@ -25,7 +25,7 @@ namespace FileManager #region static public static AudioFileStorage Audio { get; } = new AudioFileStorage(); - public static AudibleFileStorage AAX { get; } = new AaxFileStorage(); + public static AudibleFileStorage AAXC { get; } = new AaxcFileStorage(); public static AudibleFileStorage PDF { get; } = new PdfFileStorage(); public static string DownloadsInProgress @@ -77,7 +77,7 @@ namespace FileManager public FileType FileType => (FileType)Value; private IEnumerable extensions_noDots { get; } - private string extAggr { get; } + private string extAggr { get; } protected AudibleFileStorage(FileType fileType) : base((int)fileType, fileType.ToString()) { @@ -153,16 +153,16 @@ namespace FileManager } } - public class AaxFileStorage : AudibleFileStorage + public class AaxcFileStorage : AudibleFileStorage { - public override string[] Extensions { get; } = new[] { "aax" }; + public override string[] Extensions { get; } = new[] { "aaxc" }; // we always want to use the latest config value, therefore // - DO use 'get' arrow "=>" // - do NOT use assign "=" - public override string StorageDirectory => DownloadsFinal; + public override string StorageDirectory => DownloadsInProgress; - public AaxFileStorage() : base(FileType.AAX) { } + public AaxcFileStorage() : base(FileType.AAXC) { } } public class PdfFileStorage : AudibleFileStorage diff --git a/LibationWinForms/Form1.cs b/LibationWinForms/Form1.cs index 3c4fa133..b6241779 100644 --- a/LibationWinForms/Form1.cs +++ b/LibationWinForms/Form1.cs @@ -117,7 +117,7 @@ namespace LibationWinForms { if (AudibleFileStorage.Audio.Exists(productId)) return AudioFileState.full; - if (AudibleFileStorage.AAX.Exists(productId)) + if (AudibleFileStorage.AAXC.Exists(productId)) return AudioFileState.aax; return AudioFileState.none; } diff --git a/LibationWinForms/GridEntry.cs b/LibationWinForms/GridEntry.cs index 39e4bce8..bac23cca 100644 --- a/LibationWinForms/GridEntry.cs +++ b/LibationWinForms/GridEntry.cs @@ -26,11 +26,11 @@ namespace LibationWinForms [Browsable(false)] public IEnumerable TagsEnumerated => book.UserDefinedItem.TagsEnumerated; - public enum LiberatedState { NotDownloaded, DRM, Liberated } + public enum LiberatedState { NotDownloaded, PartialDownload, Liberated } [Browsable(false)] public LiberatedState Liberated_Status => FileManager.AudibleFileStorage.Audio.Exists(book.AudibleProductId) ? LiberatedState.Liberated - : FileManager.AudibleFileStorage.AAX.Exists(book.AudibleProductId) ? LiberatedState.DRM + : FileManager.AudibleFileStorage.AAXC.Exists(book.AudibleProductId) ? LiberatedState.PartialDownload : LiberatedState.NotDownloaded; public enum PdfState { NoPdf, Downloaded, NotDownloaded } diff --git a/LibationWinForms/ProductsGrid.cs b/LibationWinForms/ProductsGrid.cs index 2e837432..f4cd7fc9 100644 --- a/LibationWinForms/ProductsGrid.cs +++ b/LibationWinForms/ProductsGrid.cs @@ -126,7 +126,7 @@ namespace LibationWinForms var libState = liberatedStatus switch { GridEntry.LiberatedState.Liberated => "Liberated", - GridEntry.LiberatedState.DRM => "Downloaded but needs DRM removed", + GridEntry.LiberatedState.PartialDownload => "File has been at least\r\npartially downloaded", GridEntry.LiberatedState.NotDownloaded => "Book NOT downloaded", _ => throw new Exception("Unexpected liberation state") }; @@ -142,7 +142,7 @@ namespace LibationWinForms var text = libState + pdfState; if (liberatedStatus == GridEntry.LiberatedState.NotDownloaded || - liberatedStatus == GridEntry.LiberatedState.DRM || + liberatedStatus == GridEntry.LiberatedState.PartialDownload || pdfStatus == GridEntry.PdfState.NotDownloaded) text += "\r\nClick to complete"; @@ -154,7 +154,7 @@ namespace LibationWinForms { var image_lib = liberatedStatus == GridEntry.LiberatedState.NotDownloaded ? "red" - : liberatedStatus == GridEntry.LiberatedState.DRM ? "yellow" + : liberatedStatus == GridEntry.LiberatedState.PartialDownload ? "yellow" : liberatedStatus == GridEntry.LiberatedState.Liberated ? "green" : throw new Exception("Unexpected liberation state"); var image_pdf