using IBKRTrader.Core.Database; using IBKRTrader.Core.Logging; using IBKRTrader.Core.Settings; using IBKRTrader.Modules.CongressTrading.Database; using IBKRTrader.Modules.CongressTrading.Scraper; using IBKRTrader.Core.Workers; namespace IBKRTrader.Modules.CongressTrading.Workers; /// /// Periodischer Scrape-Worker: alle 30 Minuten. /// Lädt nur Seite 1 (neueste 96 Trades) und prüft auf neue Einträge. /// Alle Daten (Datum, Typ, Value, Ticker, Mitglied) kommen direkt aus dem RSC-JSON. /// public class CongressScrapeWorker : WorkerBase { private readonly CapitolTradesScraper _scraper; private readonly CongressRepository _repo; public override string Name => "CT-ScrapeWorker"; public override string Module => "CT"; public override WorkerType Type => WorkerType.Worker; protected override TimeSpan? Interval => TimeSpan.FromMinutes(30); public CongressScrapeWorker( LoggingService logger, DatabaseService db, CapitolTradesScraper scraper, CongressRepository repo, SettingsService settings) : base(logger, db) { _scraper = scraper; _repo = repo; } protected override async Task ExecuteAsync(CancellationToken ct) { Logger.Info(Module, "Suche neue Kongress-Trades (Seite 1)..."); var knownMembers = await _repo.GetAllMemberBioIdsAsync(); var (trades, _) = await _scraper.ScrapeTradesPageAsync(1, ct); if (trades.Count == 0) { Logger.Warn(Module, "Scrape: Keine Trades auf Seite 1 gefunden."); Info.Info = $"Letzter Lauf {DateTime.Now:HH:mm}: 0 Trades"; return; } // Neue Kongressmitglieder var newMembers = 0; foreach (var trade in trades.Where(t => t.MemberSnapshot != null)) { var snapshot = trade.MemberSnapshot!; if (knownMembers.Contains(snapshot.BioId)) continue; await _repo.UpsertMemberAsync(snapshot); knownMembers.Add(snapshot.BioId); Logger.Info(Module, $"Neues Mitglied: {snapshot.Name} ({snapshot.BioId})"); newMembers++; } // Neue Trades var newTrades = 0; foreach (var trade in trades) { ct.ThrowIfCancellationRequested(); if (await _repo.TradeExistsAsync(trade.TradeId)) continue; await _repo.InsertTradeAsync(trade, detailsFetched: true); Logger.Info(Module, $" + {trade.IssuerName} ({trade.TradeType}) [{trade.Ticker}] von {trade.MemberBioId}"); newTrades++; } var summary = $"{newTrades} neue Trades, {newMembers} neue Mitglieder"; Logger.Info(Module, $"Scrape abgeschlossen: {summary}"); Info.Info = $"Letzter Lauf {DateTime.Now:HH:mm}: {summary}"; } }