using BlueLaminate.Core.Listings; using BlueLaminate.Scraper.CsFloat; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.CommandLine; namespace BlueLaminate.Cli.Commands; /// /// sweep-catalog: catalogue-driven sweep querying each catalogue skin's /// listings by def_index+paint_index. Presentation over /// . /// internal static class SweepCatalogCommand { public static Command Build(IHost host) { var command = new Command( "sweep-catalog", "Catalogue-driven sweep: query each catalogue skin's listings by def_index+paint_index, " + "split by wear band (min_float/max_float), so only weapons are fetched (no " + "stickers/cases/agents) and each wear band is an independent checkpoint. Each band is " + "paged to completion, so Removed-tracking is accurate. Runs continuously (looping the " + "catalogue, never-swept/stalest bands first) until Ctrl+C; paces off rate-limit headers. " + "Reads CSFLOAT_API_KEY."); command.SetAction((parseResult, ct) => RunAsync(host, ct)); return command; } private static async Task RunAsync(IHost host, CancellationToken ct) { using var scope = host.Services.CreateScope(); CsFloatListingsClient? client = null; try { var service = scope.ServiceProvider.GetRequiredService(); client = scope.ServiceProvider.GetRequiredService(); Console.WriteLine("Catalogue sweep (weapons only). Running until Ctrl+C…"); var r = await service.SweepCatalogAsync(ct: ct); Console.WriteLine(); Console.WriteLine($"Catalogue sweep {r.StoppedReason}:"); Console.WriteLine($" Wear-bands : {r.SkinsCovered}"); Console.WriteLine($" Pages fetched : {r.Pages}"); Console.WriteLine($" Listings seen : {r.Seen}"); Console.WriteLine($" Inserted : {r.Inserted}"); Console.WriteLine($" Updated : {r.Updated}"); Console.WriteLine($" Removed : {r.Removed}"); Console.WriteLine(); Console.WriteLine(client.LastRateLimit.ToString()); return 0; } catch (CsFloatApiException ex) { Console.Error.WriteLine(ex.Message); if (client is not null) { Console.Error.WriteLine(client.LastRateLimit.ToString()); } return 1; } catch (Exception ex) { Console.Error.WriteLine($"Catalogue sweep failed: {ex.Message}"); return 1; } } }