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));
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<int> getNewCountAsync(List<ImportItem> importItems)

View File

@ -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);

View File

@ -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;

View File

@ -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<string> aaxToM4bConverterDecrypt(string proposedOutputFile, string aaxFilename, Account account)
private async Task<string> 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);

View File

@ -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; }
}
}

View File

@ -16,7 +16,7 @@ namespace InternalUtilities
_ = 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 string GetIdentityTokensJsonPath(this Account account)

View File

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

View File

@ -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;
}

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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);
}