Rimuovi export settings, aggiungi filtro livello log

- Rimossa la sezione "Impostazioni Export" dalla UI e dal code-behind, inclusi controlli, eventi e file legacy di export.
- Aggiunta configurazione del livello minimo di log (ErrorOnly, Normal, Informational, Debug, Trace) con guida e legenda colori.
- La funzione di log ora filtra i messaggi in base al livello selezionato.
- Aggiornati modelli di impostazioni e enum LogLevel per supportare i nuovi livelli.
- Refactoring commenti e uniformità sezioni impostazioni.
- Migliorata la chiarezza del log di avvio applicazione.
This commit is contained in:
2025-12-11 14:20:05 +01:00
parent 79756d878d
commit 7b405ed78e
19 changed files with 497 additions and 894 deletions
+46 -46
View File
@@ -1,11 +1,11 @@
using System;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using AutoBidder.Models;
using AutoBidder.ViewModels;
using AutoBidder.Utilities;
using AutoBidder.Services; // AGGIUNTO per RequestPriority e HtmlResponse
using AutoBidder.Services; // ? AGGIUNTO per RequestPriority e HtmlResponse
namespace AutoBidder
{
@@ -28,10 +28,10 @@ namespace AutoBidder
string? productName = null;
string originalUrl;
// Verifica se è un URL o solo un ID
// Verifica se è un URL o solo un ID
if (input.Contains("bidoo.com") || input.Contains("http"))
{
// È un URL - estrai ID e nome prodotto dall'URL stesso
// È un URL - estrai ID e nome prodotto dall'URL stesso
originalUrl = input.Trim();
auctionId = ExtractAuctionId(originalUrl);
if (string.IsNullOrEmpty(auctionId))
@@ -44,7 +44,7 @@ namespace AutoBidder
}
else
{
// È solo un ID numerico - costruisci URL generico
// È solo un ID numerico - costruisci URL generico
auctionId = input.Trim();
originalUrl = $"https://it.bidoo.com/auction.php?a=asta_{auctionId}";
}
@@ -52,11 +52,11 @@ namespace AutoBidder
// Verifica duplicati
if (_auctionViewModels.Any(a => a.AuctionId == auctionId))
{
MessageBox.Show("Asta già monitorata!", "Duplicato", MessageBoxButton.OK, MessageBoxImage.Information);
MessageBox.Show("Asta già monitorata!", "Duplicato", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
// MODIFICATO: Nome senza ID (già nella colonna separata)
// ? MODIFICATO: Nome senza ID (già nella colonna separata)
var displayName = string.IsNullOrEmpty(productName)
? $"Asta {auctionId}"
: DecodeAllHtmlEntities(productName);
@@ -64,7 +64,7 @@ namespace AutoBidder
// CARICA IMPOSTAZIONI PREDEFINITE SALVATE
var settings = Utilities.SettingsManager.Load();
// Determina stato iniziale dalla configurazione
// ? Determina stato iniziale dalla configurazione
bool isActive = false;
bool isPaused = false;
@@ -109,7 +109,7 @@ namespace AutoBidder
};
_auctionViewModels.Add(vm);
// Auto-start del monitoraggio se l'asta è attiva e il monitoraggio è fermo
// ? Auto-start del monitoraggio se l'asta è attiva e il monitoraggio è fermo
if (isActive && !_isAutomationActive)
{
_auctionMonitor.Start();
@@ -124,7 +124,7 @@ namespace AutoBidder
var stateText = isActive ? (isPaused ? "Paused" : "Active") : "Stopped";
Log($"[ADD] Asta aggiunta con stato={stateText}, Anticipo={settings.DefaultBidBeforeDeadlineMs}ms", Utilities.LogLevel.Info);
// NUOVO: Se il nome non è stato estratto, recuperalo in background DOPO l'aggiunta
// ? NUOVO: Se il nome non è stato estratto, recuperalo in background DOPO l'aggiunta
if (string.IsNullOrEmpty(productName))
{
_ = FetchAuctionNameInBackgroundAsync(auction, vm);
@@ -144,7 +144,7 @@ namespace AutoBidder
{
try
{
// USA IL SERVIZIO CENTRALIZZATO invece di HttpClient diretto
// ? USA IL SERVIZIO CENTRALIZZATO invece di HttpClient diretto
var response = await _htmlCacheService.GetHtmlAsync(
auction.OriginalUrl,
RequestPriority.Normal,
@@ -153,7 +153,7 @@ namespace AutoBidder
if (!response.Success)
{
Log($"[WARN] Impossibile recuperare nome per asta {auction.AuctionId}: {response.Error}", LogLevel.Warn);
Log($"[WARN] Impossibile recuperare nome per asta {auction.AuctionId}: {response.Error}", LogLevel.Warning);
return;
}
@@ -163,9 +163,9 @@ namespace AutoBidder
if (match.Success)
{
var productName = match.Groups[1].Value.Trim().Replace(" - Bidoo", "");
// Decodifica entity HTML (incluse quelle non standard)
// ? Decodifica entity HTML (incluse quelle non standard)
productName = DecodeAllHtmlEntities(productName);
// MODIFICATO: Nome senza ID
// ? MODIFICATO: Nome senza ID
var newName = productName;
// Aggiorna il nome su thread UI
@@ -182,12 +182,12 @@ namespace AutoBidder
}
else
{
Log($"[WARN] Nome non trovato nell'HTML per asta {auction.AuctionId}", LogLevel.Warn);
Log($"[WARN] Nome non trovato nell'HTML per asta {auction.AuctionId}", LogLevel.Warning);
}
}
catch (Exception ex)
{
Log($"[WARN] Errore recupero nome per asta {auction.AuctionId}: {ex.Message}", LogLevel.Warn);
Log($"[WARN] Errore recupero nome per asta {auction.AuctionId}: {ex.Message}", LogLevel.Warning);
}
}
@@ -202,16 +202,16 @@ namespace AutoBidder
// Prima decodifica entity standard
var decoded = System.Net.WebUtility.HtmlDecode(text);
// Poi sostituisci entity non standard che WebUtility.HtmlDecode non gestisce
// ? Poi sostituisci entity non standard che WebUtility.HtmlDecode non gestisce
decoded = decoded.Replace("+", "+");
decoded = decoded.Replace("=", "=");
decoded = decoded.Replace("−", "-");
decoded = decoded.Replace("×", "×");
decoded = decoded.Replace("÷", "÷");
decoded = decoded.Replace("×", "×");
decoded = decoded.Replace("÷", "÷");
decoded = decoded.Replace("%", "%");
decoded = decoded.Replace("$", "$");
decoded = decoded.Replace("€", "€");
decoded = decoded.Replace("£", "£");
decoded = decoded.Replace("€", "€");
decoded = decoded.Replace("£", "£");
return decoded;
}
@@ -236,7 +236,7 @@ namespace AutoBidder
// Verifica duplicati
if (_auctionViewModels.Any(a => a.AuctionId == auctionId))
{
MessageBox.Show("Asta già monitorata!", "Duplicato", MessageBoxButton.OK, MessageBoxImage.Information);
MessageBox.Show("Asta già monitorata!", "Duplicato", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
@@ -244,7 +244,7 @@ namespace AutoBidder
var name = $"Asta {auctionId}";
try
{
// USA IL SERVIZIO CENTRALIZZATO
// ? USA IL SERVIZIO CENTRALIZZATO
var response = await _htmlCacheService.GetHtmlAsync(url, RequestPriority.Normal);
if (response.Success)
@@ -261,7 +261,7 @@ namespace AutoBidder
// CARICA IMPOSTAZIONI PREDEFINITE SALVATE
var settings = Utilities.SettingsManager.Load();
// Determina stato iniziale dalla configurazione
// ? Determina stato iniziale dalla configurazione
bool isActive = false;
bool isPaused = false;
@@ -306,7 +306,7 @@ namespace AutoBidder
};
_auctionViewModels.Add(vm);
// Auto-start del monitoraggio se l'asta è attiva e il monitoraggio è fermo
// ? Auto-start del monitoraggio se l'asta è attiva e il monitoraggio è fermo
if (isActive && !_isAutomationActive)
{
_auctionMonitor.Start();
@@ -353,12 +353,12 @@ namespace AutoBidder
{
try
{
// Aspetta 30 secondi prima di ritentare (dà tempo alle altre richieste di completare)
// Aspetta 30 secondi prima di ritentare (dà tempo alle altre richieste di completare)
await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(30));
// Trova aste con nomi generici "Asta XXXX"
var auctionsWithGenericNames = _auctionViewModels
.Where(vm => vm.Name.StartsWith("Asta ") && !vm.Name.Contains("Shop") && !vm.Name.Contains("€"))
.Where(vm => vm.Name.StartsWith("Asta ") && !vm.Name.Contains("Shop") && !vm.Name.Contains("€"))
.ToList();
if (auctionsWithGenericNames.Count > 0)
@@ -375,7 +375,7 @@ namespace AutoBidder
}
catch (Exception ex)
{
Log($"[WARN] Errore retry nomi aste: {ex.Message}", LogLevel.Warn);
Log($"[WARN] Errore retry nomi aste: {ex.Message}", LogLevel.Warning);
}
}
@@ -396,7 +396,7 @@ namespace AutoBidder
{
try
{
// Carica impostazioni
// ? Carica impostazioni
var settings = Utilities.SettingsManager.Load();
// Ottieni username corrente dalla sessione per ripristinare IsMyBid
@@ -409,10 +409,10 @@ namespace AutoBidder
// Protezione: rimuovi eventuali BidHistory null
auction.BidHistory = auction.BidHistory?.Where(b => b != null).ToList() ?? new System.Collections.Generic.List<BidHistory>();
// Decode HTML entities (incluse quelle non standard)
// ? Decode HTML entities (incluse quelle non standard)
try { auction.Name = DecodeAllHtmlEntities(auction.Name ?? string.Empty); } catch { }
// Ripristina IsMyBid per tutte le puntate in RecentBids
// ? Ripristina IsMyBid per tutte le puntate in RecentBids
if (auction.RecentBids != null && auction.RecentBids.Count > 0 && !string.IsNullOrEmpty(currentUsername))
{
foreach (var bid in auction.RecentBids)
@@ -422,11 +422,11 @@ namespace AutoBidder
}
// NUOVO: Gestione stato in base a RememberAuctionStates
// ? NUOVO: Gestione stato in base a RememberAuctionStates
if (settings.RememberAuctionStates)
{
// MODO 1: Ripristina lo stato salvato di ogni asta (IsActive e IsPaused vengono dal file salvato)
// Non serve fare nulla, lo stato è già quello salvato nel file
// Non serve fare nulla, lo stato è già quello salvato nel file
}
else
{
@@ -455,7 +455,7 @@ namespace AutoBidder
_auctionViewModels.Add(vm);
}
// Avvia monitoraggio se ci sono aste in stato Active O Paused
// ? Avvia monitoraggio se ci sono aste in stato Active O Paused
bool hasActiveOrPausedAuctions = auctions.Any(a => a.IsActive);
if (hasActiveOrPausedAuctions && auctions.Count > 0)
@@ -538,7 +538,7 @@ namespace AutoBidder
// Aggiorna Valore (Compra Subito)
if (auction.BuyNowPrice.HasValue)
{
AuctionMonitor.ProductBuyNowPriceText.Text = $"{auction.BuyNowPrice.Value:F2}€";
AuctionMonitor.ProductBuyNowPriceText.Text = $"{auction.BuyNowPrice.Value:F2}€";
}
else
{
@@ -548,7 +548,7 @@ namespace AutoBidder
// Aggiorna Spese di Spedizione
if (auction.ShippingCost.HasValue)
{
AuctionMonitor.ProductShippingCostText.Text = $"{auction.ShippingCost.Value:F2}€";
AuctionMonitor.ProductShippingCostText.Text = $"{auction.ShippingCost.Value:F2}€";
}
else
{
@@ -579,28 +579,28 @@ namespace AutoBidder
{
bool hasGenericName = auction.Name.StartsWith("Asta ") &&
!auction.Name.Contains("Shop") &&
!auction.Name.Contains("€") &&
!auction.Name.Contains("€") &&
!auction.Name.Contains("Buono") &&
!auction.Name.Contains("Carburante");
Log($"[PRODUCT INFO] Caricamento automatico per: {auction.Name}{(hasGenericName ? " (+ nome generico)" : "")}", Utilities.LogLevel.Info);
// USA IL SERVIZIO CENTRALIZZATO
// ? USA IL SERVIZIO CENTRALIZZATO
var response = await _htmlCacheService.GetHtmlAsync(
auction.OriginalUrl,
RequestPriority.High, // Priorità alta per info prodotto
RequestPriority.High, // Priorità alta per info prodotto
bypassCache: false
);
if (!response.Success)
{
Log($"[PRODUCT INFO] Errore caricamento: {response.Error}", Utilities.LogLevel.Warn);
Log($"[PRODUCT INFO] Errore caricamento: {response.Error}", Utilities.LogLevel.Warning);
return;
}
bool updated = false;
// 1. Se nome generico, estrai nome reale dal <title>
// 1. ? Se nome generico, estrai nome reale dal <title>
if (hasGenericName)
{
var matchTitle = System.Text.RegularExpressions.Regex.Match(response.Html, @"<title>([^<]+)</title>");
@@ -608,7 +608,7 @@ namespace AutoBidder
{
var productName = matchTitle.Groups[1].Value.Trim().Replace(" - Bidoo", "");
productName = DecodeAllHtmlEntities(productName);
// MODIFICATO: Nome senza ID
// ? MODIFICATO: Nome senza ID
var newName = productName;
auction.Name = newName;
@@ -617,15 +617,15 @@ namespace AutoBidder
}
}
// 2. Estrai informazioni prodotto (prezzo, spedizione, limiti)
// 2. ? Estrai informazioni prodotto (prezzo, spedizione, limiti)
var extracted = Utilities.ProductValueCalculator.ExtractProductInfo(response.Html, auction);
if (extracted)
{
updated = true;
Log($"[PRODUCT INFO] Valore={auction.BuyNowPrice:F2}€, Spedizione={auction.ShippingCost:F2}€{(response.FromCache ? " (cached)" : "")}", Utilities.LogLevel.Success);
Log($"[PRODUCT INFO] Valore={auction.BuyNowPrice:F2}€, Spedizione={auction.ShippingCost:F2}€{(response.FromCache ? " (cached)" : "")}", Utilities.LogLevel.Success);
}
// 3. Salva e aggiorna UI solo se qualcosa è cambiato
// 3. ? Salva e aggiorna UI solo se qualcosa è cambiato
if (updated)
{
SaveAuctions();
@@ -650,7 +650,7 @@ namespace AutoBidder
}
catch (Exception ex)
{
Log($"[PRODUCT INFO] Errore caricamento: {ex.Message}", Utilities.LogLevel.Warn);
Log($"[PRODUCT INFO] Errore caricamento: {ex.Message}", Utilities.LogLevel.Warning);
}
}
}