diff --git a/ApplicationServices/UNTESTED/LibraryCommands.cs b/ApplicationServices/UNTESTED/LibraryCommands.cs index 802d8834..6e370e54 100644 --- a/ApplicationServices/UNTESTED/LibraryCommands.cs +++ b/ApplicationServices/UNTESTED/LibraryCommands.cs @@ -41,13 +41,23 @@ namespace ApplicationServices private static async Task> scanAccountsAsync(ILoginCallback callback, Account[] accounts) { - var tasks = accounts.Select(account => scanAccountAsync(callback, account)).ToList(); + var tasks = new List>>(); + foreach (var account in accounts) + { + // get APIs in serial, esp b/c of logins + var api = await AudibleApiActions.GetApiAsync(callback, account); + + // add scanAccountAsync as a TASK: do not await + tasks.Add(scanAccountAsync(api, account)); + } + + // import library in parallel var arrayOfLists = await Task.WhenAll(tasks); var importItems = arrayOfLists.SelectMany(a => a).ToList(); return importItems; } - private static async Task> scanAccountAsync(ILoginCallback callback, Account account) + private static async Task> scanAccountAsync(Api api, Account account) { Dinah.Core.ArgumentValidator.EnsureNotNull(account, nameof(account)); @@ -59,7 +69,7 @@ namespace ApplicationServices LocaleName = localeName, }); - var dtoItems = await AudibleApiActions.GetAllLibraryItemsAsync(account, callback); + var dtoItems = await AudibleApiActions.GetLibraryValidatedAsync(api); return dtoItems.Select(d => new ImportItem { DtoItem = d, AccountId = account.AccountId, LocaleName = localeName }).ToList(); } diff --git a/InternalUtilities/UNTESTED/AudibleApiActions.cs b/InternalUtilities/UNTESTED/AudibleApiActions.cs index e6a49464..2a22ba36 100644 --- a/InternalUtilities/UNTESTED/AudibleApiActions.cs +++ b/InternalUtilities/UNTESTED/AudibleApiActions.cs @@ -20,7 +20,7 @@ namespace InternalUtilities loginCallback); /// USE THIS from within Libation. It wraps the call with correct JSONPath - public static Task GetApiAsync(Account account, ILoginCallback loginCallback = null) + public static Task GetApiAsync(ILoginCallback loginCallback, Account account) => EzApiCreator.GetApiAsync( account.Locale, AudibleApiStorage.AccountsSettingsFile, @@ -32,18 +32,17 @@ namespace InternalUtilities // 2 retries == 3 total .RetryAsync(2); - public static Task> GetAllLibraryItemsAsync(Account account, ILoginCallback callback) + public static Task> GetLibraryValidatedAsync(Api api) { // bug on audible's side. the 1st time after a long absence, a query to get library will return without titles or authors. a subsequent identical query will be successful. this is true whether or tokens are refreshed // worse, this 1st dummy call doesn't seem to help: // var page = await api.GetLibraryAsync(new AudibleApi.LibraryOptions { NumberOfResultPerPage = 1, PageNumber = 1, PurchasedAfter = DateTime.Now.AddYears(-20), ResponseGroups = AudibleApi.LibraryOptions.ResponseGroupOptions.ALL_OPTIONS }); // i don't want to incur the cost of making a full dummy call every time because it fails sometimes - return policy.ExecuteAsync(() => getItemsAsync(account, callback)); + return policy.ExecuteAsync(() => getItemsAsync(api)); } - private static async Task> getItemsAsync(Account account, ILoginCallback callback) + private static async Task> getItemsAsync(Api api) { - var api = await GetApiAsync(account, callback); var items = await api.GetAllLibraryItemsAsync(); // remove episode parents and 'audible plus' check-outs diff --git a/InternalUtilities/UNTESTED/AudibleApiExtensions.cs b/InternalUtilities/UNTESTED/AudibleApiExtensions.cs deleted file mode 100644 index 394ece01..00000000 --- a/InternalUtilities/UNTESTED/AudibleApiExtensions.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using AudibleApi; -using AudibleApiDTOs; - -// -// probably not the best place for this -// but good enough for now -// -namespace InternalUtilities -{ - public static class AudibleApiExtensions - { - public static async Task> GetAllLibraryItemsAsync(this Api api) - { - var allItems = new List(); - - for (var i = 1; ; i++) - { - var page = await api.GetLibraryAsync(new LibraryOptions - { - NumberOfResultPerPage = 1000, - PageNumber = i, - PurchasedAfter = new DateTime(2000, 1, 1), - ResponseGroups = LibraryOptions.ResponseGroupOptions.ALL_OPTIONS - }); - - var pageStr = page.ToString(); - - LibraryDtoV10 libResult; - try - { - // important! use this convert method - libResult = LibraryDtoV10.FromJson(pageStr); - } - catch (Exception ex) - { - Serilog.Log.Logger.Error(ex, "Error converting library for importing use. Full library:\r\n" + pageStr); - throw; - } - - if (!libResult.Items.Any()) - break; - - Serilog.Log.Logger.Information($"Page {i}: {libResult.Items.Length} results"); - allItems.AddRange(libResult.Items); - } - - return allItems; - } - } -} diff --git a/LibationWinForms/UNTESTED/Dialogs/Login/AudibleLoginDialog.cs b/LibationWinForms/UNTESTED/Dialogs/Login/AudibleLoginDialog.cs index ca492bd8..64e18df6 100644 --- a/LibationWinForms/UNTESTED/Dialogs/Login/AudibleLoginDialog.cs +++ b/LibationWinForms/UNTESTED/Dialogs/Login/AudibleLoginDialog.cs @@ -17,7 +17,9 @@ namespace LibationWinForms.Dialogs.Login { Email = this.emailTb.Text; Password = this.passwordTb.Text; + DialogResult = DialogResult.OK; + // Close() not needed for AcceptButton } } } diff --git a/LibationWinForms/UNTESTED/Dialogs/Login/CaptchaDialog.cs b/LibationWinForms/UNTESTED/Dialogs/Login/CaptchaDialog.cs index ecbf3852..bc6a6965 100644 --- a/LibationWinForms/UNTESTED/Dialogs/Login/CaptchaDialog.cs +++ b/LibationWinForms/UNTESTED/Dialogs/Login/CaptchaDialog.cs @@ -25,7 +25,9 @@ namespace LibationWinForms.Dialogs.Login private void submitBtn_Click(object sender, EventArgs e) { Answer = this.answerTb.Text; + DialogResult = DialogResult.OK; + // Close() not needed for AcceptButton } } } \ No newline at end of file