Remove reliance on persistent Account objects across boundaries. If you open an account persister, then dispose of it

This commit is contained in:
Robert McRackan 2020-08-27 23:05:46 -04:00
parent 20b6f28cb5
commit 60f1d8117d
11 changed files with 42 additions and 39 deletions

View File

@ -51,15 +51,16 @@ namespace ApplicationServices
{ {
Dinah.Core.ArgumentValidator.EnsureNotNull(account, nameof(account)); Dinah.Core.ArgumentValidator.EnsureNotNull(account, nameof(account));
var localeName = account.Locale?.Name;
Log.Logger.Information("ImportLibraryAsync. {@DebugInfo}", new Log.Logger.Information("ImportLibraryAsync. {@DebugInfo}", new
{ {
account.AccountName, account.AccountName,
account.AccountId, account.AccountId,
LocaleName = account.Locale?.Name, LocaleName = localeName,
}); });
var dtoItems = await AudibleApiActions.GetAllLibraryItemsAsync(account, callback); 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<int> getNewCountAsync(List<ImportItem> importItems) private static async Task<int> getNewCountAsync(List<ImportItem> importItems)

View File

@ -108,7 +108,7 @@ namespace DtoImporterService
authors, authors,
narrators, narrators,
category, category,
importItem.Account.Locale.Name) importItem.LocaleName)
).Entity; ).Entity;
var publisherName = item.Publisher; var publisherName = item.Publisher;
@ -135,7 +135,7 @@ namespace DtoImporterService
book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars); book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars);
// needed during v3 => v4 migration // 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 // 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); book.UserDefinedItem.UpdateRating(item.MyUserRating_Overall, item.MyUserRating_Performance, item.MyUserRating_Story);

View File

@ -42,7 +42,7 @@ namespace DtoImporterService
var libraryBook = new LibraryBook( var libraryBook = new LibraryBook(
DbContext.Books.Local.Single(b => b.AudibleProductId == newItem.DtoItem.ProductId), DbContext.Books.Local.Single(b => b.AudibleProductId == newItem.DtoItem.ProductId),
newItem.DtoItem.DateAdded, newItem.DtoItem.DateAdded,
newItem.Account.AccountId); newItem.AccountId);
DbContext.Library.Add(libraryBook); DbContext.Library.Add(libraryBook);
} }
@ -52,7 +52,7 @@ namespace DtoImporterService
{ {
var item = importItems.FirstOrDefault(ii => ii.DtoItem.ProductId == u.Book.AudibleProductId); var item = importItems.FirstOrDefault(ii => ii.DtoItem.ProductId == u.Book.AudibleProductId);
if (item != null) if (item != null)
u.UpdateAccount(item.Account.AccountId); u.UpdateAccount(item.AccountId);
} }
var qtyNew = newItems.Count; var qtyNew = newItems.Count;

View File

@ -56,13 +56,7 @@ namespace FileLiberator
if (AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId)) if (AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId))
return new StatusHandler { "Cannot find decrypt. Final audio file already exists" }; return new StatusHandler { "Cannot find decrypt. Final audio file already exists" };
var proposedOutputFile = Path.Combine(AudibleFileStorage.DecryptInProgress, $"[{libraryBook.Book.AudibleProductId}].m4b"); var outputAudioFilename = await aaxToM4bConverterDecrypt(aaxFilename, libraryBook);
var account = AudibleApiStorage
.GetPersistentAccountsSettings()
.GetAccount(libraryBook.Account, libraryBook.Book.Locale);
var outputAudioFilename = await aaxToM4bConverterDecrypt(proposedOutputFile, aaxFilename, account);
// decrypt failed // decrypt failed
if (outputAudioFilename == null) if (outputAudioFilename == null)
@ -84,12 +78,18 @@ namespace FileLiberator
} }
} }
private async Task<string> aaxToM4bConverterDecrypt(string proposedOutputFile, string aaxFilename, Account account) private async Task<string> aaxToM4bConverterDecrypt(string aaxFilename, LibraryBook libraryBook)
{ {
DecryptBegin?.Invoke(this, $"Begin decrypting {aaxFilename}"); DecryptBegin?.Invoke(this, $"Begin decrypting {aaxFilename}");
try try
{ {
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
var account = persister
.AccountsSettings
.GetAccount(libraryBook.Account, libraryBook.Book.Locale);
var converter = await AaxToM4bConverter.CreateAsync(aaxFilename, account.DecryptKey); var converter = await AaxToM4bConverter.CreateAsync(aaxFilename, account.DecryptKey);
converter.AppName = "Libation"; converter.AppName = "Libation";
@ -99,6 +99,7 @@ namespace FileLiberator
CoverImageFilepathDiscovered?.Invoke(this, converter.coverBytes); 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.SetOutputFilename(proposedOutputFile);
converter.DecryptProgressUpdate += (s, progress) => UpdateProgress?.Invoke(this, progress); converter.DecryptProgressUpdate += (s, progress) => UpdateProgress?.Invoke(this, progress);

View File

@ -6,13 +6,7 @@ namespace InternalUtilities
public class ImportItem public class ImportItem
{ {
public Item DtoItem { get; set; } public Item DtoItem { get; set; }
public Account Account { get; set; } public string AccountId { get; set; }
public string LocaleName { get; set; }
public ImportItem() { }
public ImportItem(Item dtoItem, Account account)
{
DtoItem = dtoItem;
Account = account;
}
} }
} }

View File

@ -16,7 +16,7 @@ namespace InternalUtilities
_ = new AccountsSettingsPersister(new AccountsSettings(), AccountsSettingsFile); _ = new AccountsSettingsPersister(new AccountsSettings(), AccountsSettingsFile);
} }
public static AccountsSettings GetPersistentAccountsSettings() => GetAccountsSettingsPersister().AccountsSettings; /// <summary>If you use this, be a good citizen and DISPOSE of it</summary>
public static AccountsSettingsPersister GetAccountsSettingsPersister() => new AccountsSettingsPersister(AccountsSettingsFile); public static AccountsSettingsPersister GetAccountsSettingsPersister() => new AccountsSettingsPersister(AccountsSettingsFile);
public static string GetIdentityTokensJsonPath(this Account account) public static string GetIdentityTokensJsonPath(this Account account)

View File

@ -13,7 +13,7 @@
<!-- <PublishSingleFile>true</PublishSingleFile> --> <!-- <PublishSingleFile>true</PublishSingleFile> -->
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Version>3.1.12.306</Version> <Version>3.1.12.311</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -162,7 +162,8 @@ namespace LibationLauncher
}; };
// saves to new file // saves to new file
AudibleApiStorage.GetPersistentAccountsSettings().Add(account); using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
persister.AccountsSettings.Add(account);
return account; return account;
} }

View File

@ -39,9 +39,10 @@ namespace LibationWinForms.Dialogs
private void populateGridValues() private void populateGridValues()
{ {
// WARNING: accounts persister will write ANY EDIT to object immediately to file // 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 // only persist in 'save' step
var accounts = AudibleApiStorage.GetPersistentAccountsSettings().Accounts; using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
var accounts = persister.AccountsSettings.Accounts;
if (!accounts.Any()) if (!accounts.Any())
return; return;
@ -107,12 +108,11 @@ namespace LibationWinForms.Dialogs
{ {
try try
{ {
// without transaction, accounts persister will write ANY EDIT immediately to file. // without transaction, accounts persister will write ANY EDIT immediately to file
var persister = AudibleApiStorage.GetAccountsSettingsPersister(); using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
persister.BeginTransation(); persister.BeginTransation();
persist(persister.AccountsSettings); persist(persister.AccountsSettings);
persister.CommitTransation(); persister.CommitTransation();
_parent.RefreshImportMenu(); _parent.RefreshImportMenu();

View File

@ -29,13 +29,16 @@ namespace LibationWinForms.Dialogs
} }
private void ScanAccountsDialog_Load(object sender, EventArgs e) private void ScanAccountsDialog_Load(object sender, EventArgs e)
{ {
// DO NOT dispose of this connection. using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
// Here we (clumsily) connect to the persistent file. Accounts returned from here are used throughout library scan INCLUDING updates. eg: identity tokens var accounts = persister.AccountsSettings.Accounts;
var accounts = AudibleApiStorage.GetPersistentAccountsSettings().Accounts;
foreach (var account in 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); this.accountsClb.Items.Add(item, account.LibraryScan);
} }
} }

View File

@ -231,7 +231,8 @@ namespace LibationWinForms
#region Import menu #region Import menu
public void RefreshImportMenu() public void RefreshImportMenu()
{ {
var count = AudibleApiStorage.GetPersistentAccountsSettings().Accounts.Count; using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
var count = persister.AccountsSettings.Accounts.Count;
noAccountsYetAddAccountToolStripMenuItem.Visible = count == 0; noAccountsYetAddAccountToolStripMenuItem.Visible = count == 0;
scanLibraryToolStripMenuItem.Visible = count == 1; scanLibraryToolStripMenuItem.Visible = count == 1;
@ -247,13 +248,15 @@ namespace LibationWinForms
private void scanLibraryToolStripMenuItem_Click(object sender, EventArgs e) 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); scanLibraries(firstAccount);
} }
private void scanLibraryOfAllAccountsToolStripMenuItem_Click(object sender, EventArgs e) 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); scanLibraries(allAccounts);
} }