From 60f1d8117da59024c2a1dd184ee586c8201c17fe Mon Sep 17 00:00:00 2001 From: Robert McRackan Date: Thu, 27 Aug 2020 23:05:46 -0400 Subject: [PATCH] Remove reliance on persistent Account objects across boundaries. If you open an account persister, then dispose of it --- .../UNTESTED/LibraryCommands.cs | 5 +++-- DtoImporterService/UNTESTED/BookImporter.cs | 4 ++-- .../UNTESTED/LibraryImporter.cs | 4 ++-- FileLiberator/UNTESTED/DecryptBook.cs | 19 ++++++++++--------- InternalUtilities/ImportItem.cs | 10 ++-------- .../UNTESTED/AudibleApiStorage.cs | 2 +- LibationLauncher/LibationLauncher.csproj | 2 +- LibationLauncher/UNTESTED/Program.cs | 3 ++- .../UNTESTED/Dialogs/AccountsDialog.cs | 12 ++++++------ .../UNTESTED/Dialogs/ScanAccountsDialog.cs | 11 +++++++---- LibationWinForms/UNTESTED/Form1.cs | 9 ++++++--- 11 files changed, 42 insertions(+), 39 deletions(-) diff --git a/ApplicationServices/UNTESTED/LibraryCommands.cs b/ApplicationServices/UNTESTED/LibraryCommands.cs index 5c5bcb6f..802d8834 100644 --- a/ApplicationServices/UNTESTED/LibraryCommands.cs +++ b/ApplicationServices/UNTESTED/LibraryCommands.cs @@ -51,15 +51,16 @@ namespace ApplicationServices { Dinah.Core.ArgumentValidator.EnsureNotNull(account, nameof(account)); + var localeName = account.Locale?.Name; Log.Logger.Information("ImportLibraryAsync. {@DebugInfo}", new { account.AccountName, account.AccountId, - LocaleName = account.Locale?.Name, + LocaleName = localeName, }); var dtoItems = await AudibleApiActions.GetAllLibraryItemsAsync(account, callback); - return dtoItems.Select(d => new ImportItem { DtoItem = d, Account = account }).ToList(); + return dtoItems.Select(d => new ImportItem { DtoItem = d, AccountId = account.AccountId, LocaleName = localeName }).ToList(); } private static async Task getNewCountAsync(List importItems) diff --git a/DtoImporterService/UNTESTED/BookImporter.cs b/DtoImporterService/UNTESTED/BookImporter.cs index 6541d250..8d6bbd27 100644 --- a/DtoImporterService/UNTESTED/BookImporter.cs +++ b/DtoImporterService/UNTESTED/BookImporter.cs @@ -108,7 +108,7 @@ namespace DtoImporterService authors, narrators, category, - importItem.Account.Locale.Name) + importItem.LocaleName) ).Entity; var publisherName = item.Publisher; @@ -135,7 +135,7 @@ namespace DtoImporterService book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars); // needed during v3 => v4 migration - book.UpdateLocale(importItem.Account.Locale.Name); + book.UpdateLocale(importItem.LocaleName); // important to update user-specific info. this will have changed if user has rated/reviewed the book since last library import book.UserDefinedItem.UpdateRating(item.MyUserRating_Overall, item.MyUserRating_Performance, item.MyUserRating_Story); diff --git a/DtoImporterService/UNTESTED/LibraryImporter.cs b/DtoImporterService/UNTESTED/LibraryImporter.cs index f9549b62..48e9b628 100644 --- a/DtoImporterService/UNTESTED/LibraryImporter.cs +++ b/DtoImporterService/UNTESTED/LibraryImporter.cs @@ -42,7 +42,7 @@ namespace DtoImporterService var libraryBook = new LibraryBook( DbContext.Books.Local.Single(b => b.AudibleProductId == newItem.DtoItem.ProductId), newItem.DtoItem.DateAdded, - newItem.Account.AccountId); + newItem.AccountId); DbContext.Library.Add(libraryBook); } @@ -52,7 +52,7 @@ namespace DtoImporterService { var item = importItems.FirstOrDefault(ii => ii.DtoItem.ProductId == u.Book.AudibleProductId); if (item != null) - u.UpdateAccount(item.Account.AccountId); + u.UpdateAccount(item.AccountId); } var qtyNew = newItems.Count; diff --git a/FileLiberator/UNTESTED/DecryptBook.cs b/FileLiberator/UNTESTED/DecryptBook.cs index dbc56796..39118e35 100644 --- a/FileLiberator/UNTESTED/DecryptBook.cs +++ b/FileLiberator/UNTESTED/DecryptBook.cs @@ -56,13 +56,7 @@ namespace FileLiberator if (AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId)) return new StatusHandler { "Cannot find decrypt. Final audio file already exists" }; - var proposedOutputFile = Path.Combine(AudibleFileStorage.DecryptInProgress, $"[{libraryBook.Book.AudibleProductId}].m4b"); - - var account = AudibleApiStorage - .GetPersistentAccountsSettings() - .GetAccount(libraryBook.Account, libraryBook.Book.Locale); - - var outputAudioFilename = await aaxToM4bConverterDecrypt(proposedOutputFile, aaxFilename, account); + var outputAudioFilename = await aaxToM4bConverterDecrypt(aaxFilename, libraryBook); // decrypt failed if (outputAudioFilename == null) @@ -84,12 +78,18 @@ namespace FileLiberator } } - private async Task aaxToM4bConverterDecrypt(string proposedOutputFile, string aaxFilename, Account account) + private async Task aaxToM4bConverterDecrypt(string aaxFilename, LibraryBook libraryBook) { DecryptBegin?.Invoke(this, $"Begin decrypting {aaxFilename}"); try { + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + + var account = persister + .AccountsSettings + .GetAccount(libraryBook.Account, libraryBook.Book.Locale); + var converter = await AaxToM4bConverter.CreateAsync(aaxFilename, account.DecryptKey); converter.AppName = "Libation"; @@ -98,7 +98,8 @@ namespace FileLiberator NarratorsDiscovered?.Invoke(this, converter.tags.narrator); CoverImageFilepathDiscovered?.Invoke(this, converter.coverBytes); - // override default which was set in CreateAsync + // override default which was set in CreateAsync + var proposedOutputFile = Path.Combine(AudibleFileStorage.DecryptInProgress, $"[{libraryBook.Book.AudibleProductId}].m4b"); converter.SetOutputFilename(proposedOutputFile); converter.DecryptProgressUpdate += (s, progress) => UpdateProgress?.Invoke(this, progress); diff --git a/InternalUtilities/ImportItem.cs b/InternalUtilities/ImportItem.cs index fafb622e..8f80537d 100644 --- a/InternalUtilities/ImportItem.cs +++ b/InternalUtilities/ImportItem.cs @@ -6,13 +6,7 @@ namespace InternalUtilities public class ImportItem { public Item DtoItem { get; set; } - public Account Account { get; set; } - - public ImportItem() { } - public ImportItem(Item dtoItem, Account account) - { - DtoItem = dtoItem; - Account = account; - } + public string AccountId { get; set; } + public string LocaleName { get; set; } } } diff --git a/InternalUtilities/UNTESTED/AudibleApiStorage.cs b/InternalUtilities/UNTESTED/AudibleApiStorage.cs index 46ee170d..3de08430 100644 --- a/InternalUtilities/UNTESTED/AudibleApiStorage.cs +++ b/InternalUtilities/UNTESTED/AudibleApiStorage.cs @@ -16,7 +16,7 @@ namespace InternalUtilities _ = new AccountsSettingsPersister(new AccountsSettings(), AccountsSettingsFile); } - public static AccountsSettings GetPersistentAccountsSettings() => GetAccountsSettingsPersister().AccountsSettings; + /// If you use this, be a good citizen and DISPOSE of it public static AccountsSettingsPersister GetAccountsSettingsPersister() => new AccountsSettingsPersister(AccountsSettingsFile); public static string GetIdentityTokensJsonPath(this Account account) diff --git a/LibationLauncher/LibationLauncher.csproj b/LibationLauncher/LibationLauncher.csproj index 15e25462..19f5cc0a 100644 --- a/LibationLauncher/LibationLauncher.csproj +++ b/LibationLauncher/LibationLauncher.csproj @@ -13,7 +13,7 @@ win-x64 - 3.1.12.306 + 3.1.12.311 diff --git a/LibationLauncher/UNTESTED/Program.cs b/LibationLauncher/UNTESTED/Program.cs index 3b133295..31442faa 100644 --- a/LibationLauncher/UNTESTED/Program.cs +++ b/LibationLauncher/UNTESTED/Program.cs @@ -162,7 +162,8 @@ namespace LibationLauncher }; // saves to new file - AudibleApiStorage.GetPersistentAccountsSettings().Add(account); + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + persister.AccountsSettings.Add(account); return account; } diff --git a/LibationWinForms/UNTESTED/Dialogs/AccountsDialog.cs b/LibationWinForms/UNTESTED/Dialogs/AccountsDialog.cs index 8032e03f..59bedf94 100644 --- a/LibationWinForms/UNTESTED/Dialogs/AccountsDialog.cs +++ b/LibationWinForms/UNTESTED/Dialogs/AccountsDialog.cs @@ -39,9 +39,10 @@ namespace LibationWinForms.Dialogs private void populateGridValues() { // WARNING: accounts persister will write ANY EDIT to object immediately to file - // here: copy strings + // here: copy strings and dispose of persister // only persist in 'save' step - var accounts = AudibleApiStorage.GetPersistentAccountsSettings().Accounts; + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + var accounts = persister.AccountsSettings.Accounts; if (!accounts.Any()) return; @@ -107,12 +108,11 @@ namespace LibationWinForms.Dialogs { try { - // without transaction, accounts persister will write ANY EDIT immediately to file. - var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + // without transaction, accounts persister will write ANY EDIT immediately to file + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + persister.BeginTransation(); - persist(persister.AccountsSettings); - persister.CommitTransation(); _parent.RefreshImportMenu(); diff --git a/LibationWinForms/UNTESTED/Dialogs/ScanAccountsDialog.cs b/LibationWinForms/UNTESTED/Dialogs/ScanAccountsDialog.cs index 3ed1a113..aa38453e 100644 --- a/LibationWinForms/UNTESTED/Dialogs/ScanAccountsDialog.cs +++ b/LibationWinForms/UNTESTED/Dialogs/ScanAccountsDialog.cs @@ -29,13 +29,16 @@ namespace LibationWinForms.Dialogs } private void ScanAccountsDialog_Load(object sender, EventArgs e) { - // DO NOT dispose of this connection. - // Here we (clumsily) connect to the persistent file. Accounts returned from here are used throughout library scan INCLUDING updates. eg: identity tokens - var accounts = AudibleApiStorage.GetPersistentAccountsSettings().Accounts; + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + var accounts = persister.AccountsSettings.Accounts; foreach (var account in accounts) { - var item = new listItem { Account=account,Text = $"{account.AccountName} ({account.AccountId} - {account.Locale.Name})" }; + var item = new listItem + { + Account = account, + Text = $"{account.AccountName} ({account.AccountId} - {account.Locale.Name})" + }; this.accountsClb.Items.Add(item, account.LibraryScan); } } diff --git a/LibationWinForms/UNTESTED/Form1.cs b/LibationWinForms/UNTESTED/Form1.cs index f7907fe7..59490918 100644 --- a/LibationWinForms/UNTESTED/Form1.cs +++ b/LibationWinForms/UNTESTED/Form1.cs @@ -231,7 +231,8 @@ namespace LibationWinForms #region Import menu public void RefreshImportMenu() { - var count = AudibleApiStorage.GetPersistentAccountsSettings().Accounts.Count; + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + var count = persister.AccountsSettings.Accounts.Count; noAccountsYetAddAccountToolStripMenuItem.Visible = count == 0; scanLibraryToolStripMenuItem.Visible = count == 1; @@ -247,13 +248,15 @@ namespace LibationWinForms private void scanLibraryToolStripMenuItem_Click(object sender, EventArgs e) { - var firstAccount = AudibleApiStorage.GetPersistentAccountsSettings().GetAll().FirstOrDefault(); + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + var firstAccount = persister.AccountsSettings.GetAll().FirstOrDefault(); scanLibraries(firstAccount); } private void scanLibraryOfAllAccountsToolStripMenuItem_Click(object sender, EventArgs e) { - var allAccounts = AudibleApiStorage.GetPersistentAccountsSettings().GetAll(); + using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); + var allAccounts = persister.AccountsSettings.GetAll(); scanLibraries(allAccounts); }