Remove reliance on persistent Account objects across boundaries. If you open an account persister, then dispose of it
This commit is contained in:
parent
20b6f28cb5
commit
60f1d8117d
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user