Refactoring e nuove funzionalità per AutoBidder v4.0
* Aggiornamento alla versione 4.0.0 * Refactoring architetturale: introdotte partial classes e UserControls modulari per migliorare manutenibilità e leggibilità. * Aggiunti nuovi UserControls: `AuctionMonitorControl`, `BrowserControl`, `SettingsControl`, `StatisticsControl`. * Introdotto supporto per WebView2 per il browser integrato. * Migliorata gestione delle aste: aggiunta/rimozione tramite URL o ID, configurazione predefinita. * Nuove funzionalità di esportazione: supporto CSV, JSON, XML con opzioni configurabili. * Logging avanzato: codifica colore per severità e auto-scroll. * Tema scuro moderno e miglioramenti UI/UX: sidebar di navigazione, griglie virtualizzate, icone emoji. * Persistenza dati: salvataggio automatico di aste e impostazioni in file JSON. * Documentazione aggiornata: `README.md`, `CHANGELOG.md` e nuovi file di supporto. * Miglioramenti alla sicurezza: cookie di sessione salvati in modo sicuro con DPAPI. * Preparazione per future estensioni: placeholder per funzionalità avanzate e struttura modulare.
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using AutoBidder.Models;
|
||||
using AutoBidder.ViewModels;
|
||||
|
||||
namespace AutoBidder
|
||||
{
|
||||
/// <summary>
|
||||
/// Auction management: Add, Remove, Update
|
||||
/// </summary>
|
||||
public partial class MainWindow
|
||||
{
|
||||
private async Task AddAuctionById(string input)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
MessageBox.Show("Input non valido!", "Errore", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
string auctionId;
|
||||
string? productName;
|
||||
string originalUrl;
|
||||
|
||||
// Verifica se è un URL o solo un ID
|
||||
if (input.Contains("bidoo.com") || input.Contains("http"))
|
||||
{
|
||||
// È un URL - estrai ID e nome prodotto
|
||||
originalUrl = input.Trim();
|
||||
auctionId = ExtractAuctionId(originalUrl);
|
||||
if (string.IsNullOrEmpty(auctionId))
|
||||
{
|
||||
MessageBox.Show("Impossibile estrarre ID dall'URL!", "Errore", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
productName = ExtractProductName(originalUrl) ?? string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// È solo un ID numerico - costruisci URL generico
|
||||
auctionId = input.Trim();
|
||||
productName = string.Empty;
|
||||
originalUrl = $"https://it.bidoo.com/auction.php?a=asta_{auctionId}";
|
||||
}
|
||||
|
||||
// Verifica duplicati
|
||||
if (_auctionViewModels.Any(a => a.AuctionId == auctionId))
|
||||
{
|
||||
MessageBox.Show("Asta già monitorata!", "Duplicato", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
// Crea nome visualizzazione
|
||||
var displayName = string.IsNullOrEmpty(productName)
|
||||
? $"Asta {auctionId}"
|
||||
: $"{System.Net.WebUtility.HtmlDecode(productName)} ({auctionId})";
|
||||
|
||||
// Crea model
|
||||
var auction = new AuctionInfo
|
||||
{
|
||||
AuctionId = auctionId,
|
||||
Name = System.Net.WebUtility.HtmlDecode(displayName),
|
||||
OriginalUrl = originalUrl,
|
||||
TimerClick = 0,
|
||||
DelayMs = 50,
|
||||
IsActive = true
|
||||
};
|
||||
|
||||
// Aggiungi al monitor
|
||||
_auctionMonitor.AddAuction(auction);
|
||||
|
||||
// Crea ViewModel
|
||||
var vm = new AuctionViewModel(auction);
|
||||
_auctionViewModels.Add(vm);
|
||||
|
||||
SaveAuctions();
|
||||
UpdateTotalCount();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"Errore aggiunta asta: {ex.Message}");
|
||||
MessageBox.Show($"Errore: {ex.Message}", "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddAuctionFromUrl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsValidAuctionUrl(url))
|
||||
{
|
||||
MessageBox.Show("URL asta non valido!", "Errore", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var auctionId = ExtractAuctionId(url);
|
||||
if (string.IsNullOrEmpty(auctionId))
|
||||
{
|
||||
MessageBox.Show("Impossibile estrarre ID asta!", "Errore", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verifica duplicati
|
||||
if (_auctionViewModels.Any(a => a.AuctionId == auctionId))
|
||||
{
|
||||
MessageBox.Show("Asta già monitorata!", "Duplicato", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch nome (opzionale)
|
||||
var name = $"Asta {auctionId}";
|
||||
try
|
||||
{
|
||||
using var httpClient = new System.Net.Http.HttpClient();
|
||||
var html = await httpClient.GetStringAsync(url);
|
||||
var match = System.Text.RegularExpressions.Regex.Match(html, @"<title>([^<]+)</title>");
|
||||
if (match.Success)
|
||||
{
|
||||
name = System.Net.WebUtility.HtmlDecode(match.Groups[1].Value.Trim().Replace(" - Bidoo", ""));
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Crea model
|
||||
var auction = new AuctionInfo
|
||||
{
|
||||
AuctionId = auctionId,
|
||||
Name = System.Net.WebUtility.HtmlDecode(name),
|
||||
TimerClick = 0,
|
||||
DelayMs = 50,
|
||||
IsActive = true
|
||||
};
|
||||
|
||||
// Aggiungi al monitor
|
||||
_auctionMonitor.AddAuction(auction);
|
||||
|
||||
// Crea ViewModel
|
||||
var vm = new AuctionViewModel(auction);
|
||||
_auctionViewModels.Add(vm);
|
||||
|
||||
SaveAuctions();
|
||||
UpdateTotalCount();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[ERRORE] Errore aggiunta asta: {ex.Message}");
|
||||
MessageBox.Show($"Errore: {ex.Message}", "Errore", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveAuctions()
|
||||
{
|
||||
try
|
||||
{
|
||||
var auctions = _auctionMonitor.GetAuctions();
|
||||
Utilities.PersistenceManager.SaveAuctions(auctions);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[ERRORE] Errore salvataggio: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSavedAuctions()
|
||||
{
|
||||
try
|
||||
{
|
||||
var auctions = Utilities.PersistenceManager.LoadAuctions();
|
||||
foreach (var auction in auctions)
|
||||
{
|
||||
// Protezione: rimuovi eventuali BidHistory null
|
||||
auction.BidHistory = auction.BidHistory?.Where(b => b != null).ToList() ?? new System.Collections.Generic.List<BidHistory>();
|
||||
|
||||
// Decode HTML entities
|
||||
try { auction.Name = System.Net.WebUtility.HtmlDecode(auction.Name ?? string.Empty); } catch { }
|
||||
|
||||
_auctionMonitor.AddAuction(auction);
|
||||
var vm = new AuctionViewModel(auction);
|
||||
_auctionViewModels.Add(vm);
|
||||
}
|
||||
|
||||
// On startup treat persisted auctions as stopped
|
||||
foreach (var vm in _auctionViewModels)
|
||||
{
|
||||
vm.IsActive = false;
|
||||
vm.IsPaused = false;
|
||||
}
|
||||
|
||||
UpdateTotalCount();
|
||||
if (auctions.Count > 0)
|
||||
{
|
||||
Log($"[OK] Caricate {auctions.Count} aste salvate");
|
||||
}
|
||||
|
||||
LoadSavedSession();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"[ERRORE] Errore caricamento aste: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user