Libation/Source/LibationWinForms/Form1.ScanAuto.cs
Michael Bucari-Tovo f35c82d59d Change ApiExtended to always allow provide login option
Previously, only some calls to ApiExtended.CreateAsync() would prompt users to login if necessary. Other calls would only work if the account already had a valid identity, and they would throw exceptions otherwise.

Changed ApiExtended so that the UI registers a static ILoginChoiceEager factory delegate that ApiExtended will use in the event that a login is required.
2025-05-09 17:32:12 -06:00

106 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApplicationServices;
using AudibleUtilities;
using Dinah.Core;
using LibationFileManager;
namespace LibationWinForms
{
// This is for the auto-scanner. It is unrelated to manual scanning/import
public partial class Form1
{
private InterruptableTimer autoScanTimer;
private void Configure_ScanAuto()
{
// creating InterruptableTimer inside 'Configure_' is a break from the pattern. As long as no one else needs to access or subscribe to it, this is ok
autoScanTimer = new InterruptableTimer(TimeSpan.FromMinutes(5));
// subscribe as async/non-blocking. I'd actually rather prefer blocking but real-world testing found that caused a deadlock in the AudibleAPI
autoScanTimer.Elapsed += async (_, __) =>
{
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
var accounts = persister.AccountsSettings
.GetAll()
.Where(a => a.LibraryScan)
.ToArray();
// in autoScan, new books SHALL NOT show dialog
try
{
Task importAsync() => LibraryCommands.ImportAccountAsync(accounts);
if (InvokeRequired)
await Invoke(importAsync);
else
await importAsync();
}
catch (OperationCanceledException)
{
Serilog.Log.Information("Audible login attempt cancelled by user");
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Error invoking auto-scan");
}
};
// load init state to menu checkbox
Load += updateAutoScanLibraryToolStripMenuItem;
// if enabled: begin on load
Shown += startAutoScan;
// if new 'default' account is added, run autoscan
AccountsSettingsPersister.Saving += accountsPreSave;
AccountsSettingsPersister.Saved += accountsPostSave;
Configuration.Instance.PropertyChanged += Configuration_PropertyChanged;
}
[PropertyChangeFilter(nameof(Configuration.AutoScan))]
private void Configuration_PropertyChanged(object sender, PropertyChangedEventArgsEx e)
{
// when autoscan setting is changed, update menu checkbox and run autoscan
updateAutoScanLibraryToolStripMenuItem(sender, e);
startAutoScan(sender, e);
}
private List<(string AccountId, string LocaleName)> preSaveDefaultAccounts;
private List<(string AccountId, string LocaleName)> getDefaultAccounts()
{
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
return persister.AccountsSettings
.GetAll()
.Where(a => a.LibraryScan)
.Select(a => (a.AccountId, a.Locale.Name))
.ToList();
}
private void accountsPreSave(object sender = null, EventArgs e = null)
=> preSaveDefaultAccounts = getDefaultAccounts();
private void accountsPostSave(object sender = null, EventArgs e = null)
{
var postSaveDefaultAccounts = getDefaultAccounts();
var newDefaultAccounts = postSaveDefaultAccounts.Except(preSaveDefaultAccounts).ToList();
if (newDefaultAccounts.Any())
startAutoScan();
}
private void startAutoScan(object sender = null, EventArgs e = null)
{
if (Configuration.Instance.AutoScan)
autoScanTimer.PerformNow();
else
autoScanTimer.Stop();
}
private void updateAutoScanLibraryToolStripMenuItem(object sender, EventArgs e) => autoScanLibraryToolStripMenuItem.Checked = Configuration.Instance.AutoScan;
private void autoScanLibraryToolStripMenuItem_Click(object sender, EventArgs e) => Configuration.Instance.AutoScan = !autoScanLibraryToolStripMenuItem.Checked;
}
}