Refactoring gestione sessione e persistenza impostazioni

Introdotto `SessionService` per centralizzare la gestione della
sessione utente, migliorando la separazione delle responsabilità
e la testabilità. Risolto il problema del caricamento del cookie
di autenticazione all'avvio e garantita la persistenza delle
checkbox di esportazione (`IncludeMetadata`, `RemoveAfterExport`,
`OverwriteExisting`).

Ottimizzata la gestione della barra degli indirizzi del browser
con aggiornamenti locali immediati. Applicato il pattern "Load ?
Modify ? Save" per il salvataggio delle impostazioni, migliorando
la simmetria e la leggibilità del codice. Logging centralizzato
e semplificato per eventi rilevanti.

Aggiornata la documentazione per riflettere i cambiamenti e
verificati i test per garantire il corretto funzionamento.
This commit is contained in:
2025-11-24 12:00:13 +01:00
parent ee67bedc31
commit 62d5cebf9c
22 changed files with 5244 additions and 299 deletions
@@ -6,12 +6,12 @@ using AutoBidder.Utilities;
namespace AutoBidder
{
/// <summary>
/// Settings and configuration event handlers
/// Settings and configuration event handlers - REFACTORED
/// </summary>
public partial class MainWindow
{
/// <summary>
/// Carica impostazioni predefinite salvate nei controlli UI
/// Carica TUTTE le impostazioni salvate nei controlli UI
/// </summary>
private void LoadDefaultSettings()
{
@@ -19,24 +19,46 @@ namespace AutoBidder
{
var settings = SettingsManager.Load();
// Popola i controlli con i valori salvati - Aste
// === SEZIONE 1: Impostazioni Predefinite Aste ===
DefaultBidBeforeDeadlineMs.Text = settings.DefaultBidBeforeDeadlineMs.ToString();
DefaultCheckAuctionOpen.IsChecked = settings.DefaultCheckAuctionOpenBeforeBid;
DefaultMinPrice.Text = settings.DefaultMinPrice.ToString("F2", System.Globalization.CultureInfo.InvariantCulture);
DefaultMaxPrice.Text = settings.DefaultMaxPrice.ToString("F2", System.Globalization.CultureInfo.InvariantCulture);
DefaultMaxClicks.Text = settings.DefaultMaxClicks.ToString();
// Popola i controlli con i valori salvati - Limiti Log
// === SEZIONE 2: Limiti Log ===
Settings.MaxLogLinesPerAuction.Text = settings.MaxLogLinesPerAuction.ToString();
Settings.MaxGlobalLogLines.Text = settings.MaxGlobalLogLines.ToString();
Log($"[OK] Impostazioni predefinite caricate: Anticipo={settings.DefaultBidBeforeDeadlineMs}ms, Log Asta={settings.MaxLogLinesPerAuction}, Log Globale={settings.MaxGlobalLogLines}", LogLevel.Info);
// === SEZIONE 3: Stati Iniziali Aste ===
var loadAuctionsStopped = Settings.FindName("LoadAuctionsStopped") as System.Windows.Controls.RadioButton;
var loadAuctionsPaused = Settings.FindName("LoadAuctionsPaused") as System.Windows.Controls.RadioButton;
var loadAuctionsActive = Settings.FindName("LoadAuctionsActive") as System.Windows.Controls.RadioButton;
if (loadAuctionsStopped != null) loadAuctionsStopped.IsChecked = settings.DefaultStartAuctionsOnLoad == "Stopped";
if (loadAuctionsPaused != null) loadAuctionsPaused.IsChecked = settings.DefaultStartAuctionsOnLoad == "Paused";
if (loadAuctionsActive != null) loadAuctionsActive.IsChecked = settings.DefaultStartAuctionsOnLoad == "Active";
var newAuctionStopped = Settings.FindName("NewAuctionStopped") as System.Windows.Controls.RadioButton;
var newAuctionPaused = Settings.FindName("NewAuctionPaused") as System.Windows.Controls.RadioButton;
var newAuctionActive = Settings.FindName("NewAuctionActive") as System.Windows.Controls.RadioButton;
if (newAuctionStopped != null) newAuctionStopped.IsChecked = settings.DefaultNewAuctionState == "Stopped";
if (newAuctionPaused != null) newAuctionPaused.IsChecked = settings.DefaultNewAuctionState == "Paused";
if (newAuctionActive != null) newAuctionActive.IsChecked = settings.DefaultNewAuctionState == "Active";
// === SEZIONE 4: Cookie (da SessionManager separato) ===
var session = Services.SessionManager.LoadSession();
if (session != null && !string.IsNullOrEmpty(session.CookieString))
{
SettingsCookieTextBox.Text = session.CookieString;
}
}
catch (Exception ex)
{
Log($"[WARN] Errore caricamento defaults: {ex.Message}", LogLevel.Warn);
Log($"[ERRORE] Caricamento impostazioni: {ex.Message}", LogLevel.Error);
// Valori di fallback se il caricamento fallisce
// Valori di fallback
DefaultBidBeforeDeadlineMs.Text = "200";
DefaultCheckAuctionOpen.IsChecked = false;
DefaultMinPrice.Text = "0.00";
@@ -44,6 +66,11 @@ namespace AutoBidder
DefaultMaxClicks.Text = "0";
Settings.MaxLogLinesPerAuction.Text = "500";
Settings.MaxGlobalLogLines.Text = "1000";
var loadAuctionsStopped = Settings.FindName("LoadAuctionsStopped") as System.Windows.Controls.RadioButton;
var newAuctionStopped = Settings.FindName("NewAuctionStopped") as System.Windows.Controls.RadioButton;
if (loadAuctionsStopped != null) loadAuctionsStopped.IsChecked = true;
if (newAuctionStopped != null) newAuctionStopped.IsChecked = true;
}
}
@@ -52,28 +79,26 @@ namespace AutoBidder
try
{
var cookie = SettingsCookieTextBox.Text?.Trim();
if (string.IsNullOrEmpty(cookie))
{
// Silenzioso - nessun MessageBox
return;
}
_auctionMonitor.InitializeSessionWithCookie(cookie, string.Empty);
var success = await _auctionMonitor.UpdateUserInfoAsync();
var session = _auctionMonitor.GetSession();
if (success && session != null)
// ? NUOVO: Usa SessionService per validare e attivare
var result = await _sessionService.ValidateAndActivateSessionAsync(cookie);
if (result.Success && result.Session != null)
{
Services.SessionManager.SaveSession(session);
SetUserBanner(session.Username ?? string.Empty, session.RemainingBids);
// Salva sessione su disco
_sessionService.SaveSession(result.Session);
StartButton.IsEnabled = true;
Log($"[OK] Sessione salvata per: {session.Username}");
// Rimosso MessageBox - verrà mostrato dal chiamante
Log($"[OK] Cookie valido e salvato - Utente: {result.Session.Username}, Puntate: {result.Session.RemainingBids}", LogLevel.Success);
}
else
{
Log($"[WARN] Cookie non valido o scaduto", LogLevel.Warn);
// Rimosso MessageBox - verrà mostrato dal chiamante se necessario
Log($"[ERRORE] {result.ErrorMessage ?? "Cookie non valido o scaduto"}", LogLevel.Error);
}
}
catch (Exception ex)
@@ -98,12 +123,12 @@ namespace AutoBidder
if (stattrb != null)
{
SettingsCookieTextBox.Text = stattrb.Value;
Log("[OK] Cookie importato dal browser");
Log("[OK] Cookie importato dal browser", LogLevel.Success);
MessageBox.Show(this, "Cookie importato con successo!\nClicca 'Salva' per confermare.", "Importa Cookie", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
Log("[WARN] Cookie __stattrb non trovato nel browser", LogLevel.Warn);
Log("[ERRORE] Cookie __stattrb non trovato nel browser", LogLevel.Error);
MessageBox.Show(this, "Cookie __stattrb non trovato.\nAssicurati di aver effettuato il login su bidoo.com nella scheda Browser.", "Cookie Non Trovato", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
@@ -116,37 +141,53 @@ namespace AutoBidder
private void CancelCookieButton_Click(object sender, RoutedEventArgs e)
{
SettingsCookieTextBox.Text = string.Empty;
var session = Services.SessionManager.LoadSession();
if (session != null && !string.IsNullOrEmpty(session.CookieString))
{
SettingsCookieTextBox.Text = session.CookieString;
}
else
{
SettingsCookieTextBox.Text = string.Empty;
}
}
private void SaveSettingsButton_Click(object sender, RoutedEventArgs e)
{
try
{
var lastExt = ExtJson.IsChecked == true ? ".json" : ExtXml.IsChecked == true ? ".xml" : ".csv";
var scope = "All";
// ? Carica le impostazioni esistenti per non perdere gli altri valori
var settings = Utilities.SettingsManager.Load() ?? new Utilities.AppSettings();
// === SEZIONE EXPORT: Percorso e Formato ===
settings.ExportPath = ExportPathTextBox.Text;
settings.LastExportExt = ExtJson.IsChecked == true ? ".json" : ExtXml.IsChecked == true ? ".xml" : ".csv";
// === SEZIONE EXPORT: Scope (Aste da esportare) ===
var cbClosed = this.FindName("ExportClosedToolbar") as System.Windows.Controls.CheckBox;
var cbUnknown = this.FindName("ExportUnknownToolbar") as System.Windows.Controls.CheckBox;
var cbOpen = this.FindName("ExportOpenToolbar") as System.Windows.Controls.CheckBox;
var scope = "All";
if (cbClosed != null && cbClosed.IsChecked == true) scope = "Closed";
else if (cbUnknown != null && cbUnknown.IsChecked == true) scope = "Unknown";
else if (cbOpen != null && cbOpen.IsChecked == true) scope = "Open";
settings.ExportScope = scope;
settings.ExportOpen = cbOpen?.IsChecked ?? true;
settings.ExportClosed = cbClosed?.IsChecked ?? true;
settings.ExportUnknown = cbUnknown?.IsChecked ?? true;
// === SEZIONE EXPORT: Opzioni ? FIX: Aggiunte le 3 checkbox mancanti ===
settings.IncludeOnlyUsedBids = IncludeUsedBids.IsChecked == true;
settings.IncludeLogs = IncludeLogs.IsChecked == true;
settings.IncludeUserBids = IncludeUserBids.IsChecked == true;
settings.IncludeMetadata = IncludeMetadata.IsChecked == true; // ? AGGIUNTO
settings.RemoveAfterExport = RemoveAfterExport.IsChecked == true; // ? AGGIUNTO
settings.OverwriteExisting = OverwriteExisting.IsChecked == true; // ? AGGIUNTO
var s = new AppSettings()
{
ExportPath = ExportPathTextBox.Text,
LastExportExt = lastExt,
ExportScope = scope,
IncludeOnlyUsedBids = IncludeUsedBids.IsChecked == true,
IncludeLogs = IncludeLogs.IsChecked == true,
IncludeUserBids = IncludeUserBids.IsChecked == true
};
SettingsManager.Save(s);
ExportPreferences.SaveLastExportExtension(s.LastExportExt);
Log("[OK] Impostazioni export salvate", LogLevel.Success);
// Rimosso MessageBox - verrà mostrato dal chiamante
SettingsManager.Save(settings);
ExportPreferences.SaveLastExportExtension(settings.LastExportExt);
}
catch (Exception ex)
{
@@ -172,7 +213,6 @@ namespace AutoBidder
SettingsCookieTextBox.Text = string.Empty;
}
Log("[INFO] Impostazioni ripristinate", LogLevel.Info);
MessageBox.Show(this, "Impostazioni ripristinate alle ultime salvate.", "Annulla", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
@@ -186,53 +226,78 @@ namespace AutoBidder
{
try
{
// Salva impostazioni predefinite aste
// ? Carica le impostazioni esistenti per non perdere gli altri valori
var settings = Utilities.SettingsManager.Load() ?? new Utilities.AppSettings();
// === SEZIONE DEFAULTS: Validazione e Salvataggio ===
if (int.TryParse(DefaultBidBeforeDeadlineMs.Text, out var bidMs) && bidMs >= 0 && bidMs <= 5000)
{
var settings = Utilities.SettingsManager.Load() ?? new Utilities.AppSettings();
settings.DefaultBidBeforeDeadlineMs = bidMs;
settings.DefaultCheckAuctionOpenBeforeBid = DefaultCheckAuctionOpen.IsChecked ?? false;
if (double.TryParse(DefaultMinPrice.Text.Replace(',', '.'), System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out var minPrice))
{
settings.DefaultMinPrice = minPrice;
}
if (double.TryParse(DefaultMaxPrice.Text.Replace(',', '.'), System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out var maxPrice))
{
settings.DefaultMaxPrice = maxPrice;
}
if (int.TryParse(DefaultMaxClicks.Text, out var maxClicks))
{
settings.DefaultMaxClicks = maxClicks;
}
// ? NUOVO: Salva limiti log
if (int.TryParse(Settings.MaxLogLinesPerAuction.Text, out var maxLogPerAuction) && maxLogPerAuction > 0)
{
settings.MaxLogLinesPerAuction = maxLogPerAuction;
}
if (int.TryParse(Settings.MaxGlobalLogLines.Text, out var maxGlobalLog) && maxGlobalLog > 0)
{
settings.MaxGlobalLogLines = maxGlobalLog;
}
Utilities.SettingsManager.Save(settings);
Log($"[OK] Impostazioni salvate: Anticipo={bidMs}ms, MinPrice=€{settings.DefaultMinPrice:F2}, MaxPrice=€{settings.DefaultMaxPrice:F2}, MaxClicks={maxClicks}, LogAsta={settings.MaxLogLinesPerAuction}, LogGlobale={settings.MaxGlobalLogLines}", LogLevel.Success);
// Rimosso MessageBox - verrà mostrato dal chiamante
}
else
{
Log("[WARN] Valore anticipo puntata non valido (deve essere 0-5000)", LogLevel.Warn);
Log("[ERRORE] Valore anticipo puntata non valido (deve essere 0-5000ms)", LogLevel.Error);
return;
}
settings.DefaultCheckAuctionOpenBeforeBid = DefaultCheckAuctionOpen.IsChecked ?? false;
if (double.TryParse(DefaultMinPrice.Text.Replace(',', '.'), System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out var minPrice))
{
settings.DefaultMinPrice = minPrice;
}
if (double.TryParse(DefaultMaxPrice.Text.Replace(',', '.'), System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out var maxPrice))
{
settings.DefaultMaxPrice = maxPrice;
}
if (int.TryParse(DefaultMaxClicks.Text, out var maxClicks))
{
settings.DefaultMaxClicks = maxClicks;
}
// === SEZIONE DEFAULTS: Limiti Log ===
if (int.TryParse(Settings.MaxLogLinesPerAuction.Text, out var maxLogPerAuction) && maxLogPerAuction > 0)
{
settings.MaxLogLinesPerAuction = maxLogPerAuction;
}
else
{
Log("[ERRORE] Valore max log per asta non valido (deve essere > 0)", LogLevel.Error);
}
if (int.TryParse(Settings.MaxGlobalLogLines.Text, out var maxGlobalLog) && maxGlobalLog > 0)
{
settings.MaxGlobalLogLines = maxGlobalLog;
}
else
{
Log("[ERRORE] Valore max log globale non valido (deve essere > 0)", LogLevel.Error);
}
// === SEZIONE DEFAULTS: Stati Iniziali Aste ===
var loadAuctionsActive = Settings.FindName("LoadAuctionsActive") as System.Windows.Controls.RadioButton;
var loadAuctionsPaused = Settings.FindName("LoadAuctionsPaused") as System.Windows.Controls.RadioButton;
settings.DefaultStartAuctionsOnLoad = loadAuctionsActive?.IsChecked == true ? "Active" :
loadAuctionsPaused?.IsChecked == true ? "Paused" :
"Stopped";
var newAuctionActive = Settings.FindName("NewAuctionActive") as System.Windows.Controls.RadioButton;
var newAuctionPaused = Settings.FindName("NewAuctionPaused") as System.Windows.Controls.RadioButton;
settings.DefaultNewAuctionState = newAuctionActive?.IsChecked == true ? "Active" :
newAuctionPaused?.IsChecked == true ? "Paused" :
"Stopped";
Utilities.SettingsManager.Save(settings);
}
catch (Exception ex)
{
Log($"[ERRORE] Salvataggio defaults: {ex.Message}", LogLevel.Error);
Log($"[ERRORE] Salvataggio impostazioni: {ex.Message}", LogLevel.Error);
}
}
@@ -242,13 +307,11 @@ namespace AutoBidder
{
// Ricarica defaults salvati
LoadDefaultSettings();
Log("[INFO] Impostazioni predefinite ripristinate", LogLevel.Info);
MessageBox.Show(this, "Impostazioni predefinite ripristinate.", "Annulla", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
Log($"[ERRORE] Ripristino defaults: {ex.Message}", LogLevel.Error);
Log($"[ERRORE] Ripristino impostazioni: {ex.Message}", LogLevel.Error);
MessageBox.Show(this, "Errore durante ripristino: " + ex.Message, "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
}
}