Brings up the pull-model scraper: the .NET C2 hands skin+wear jobs to Python nodriver workers that scrape cs.money and post results back, plus the supporting Core/EFCore data model, migrations, and docker-compose orchestration. IPRoyal proxying lets workers scale horizontally with a distinct residential exit IP each: every worker process mints its own sticky session at startup, and an in-process forwarding proxy injects the gateway auth so Chromium talks only to an auth-free localhost endpoint (zero CDP). On a Cloudflare challenge a worker rotates to a fresh session/IP and re-warms. Verified end-to-end against live IPRoyal: distinct US residential exits per worker and IP rotation on demand. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
2.0 KiB
C#
53 lines
2.0 KiB
C#
using System.Text.Json.Serialization;
|
|
|
|
namespace BlueLaminate.Core.CsMoney;
|
|
|
|
/// <summary>
|
|
/// The subset of a cs.money <c>sell-orders</c> item we persist, parsed from the
|
|
/// JSON the Python worker scrapes. Decimals are parsed directly (not via double) so
|
|
/// the full-precision float round-trips exactly into <c>numeric(20,18)</c>.
|
|
/// </summary>
|
|
public sealed class CsMoneyItem
|
|
{
|
|
[JsonPropertyName("id")] public long Id { get; set; }
|
|
[JsonPropertyName("asset")] public CsMoneyAsset? Asset { get; set; }
|
|
[JsonPropertyName("pricing")] public CsMoneyPricing? Pricing { get; set; }
|
|
[JsonPropertyName("stickers")] public List<CsMoneySticker?>? Stickers { get; set; }
|
|
[JsonPropertyName("links")] public CsMoneyLinks? Links { get; set; }
|
|
}
|
|
|
|
public sealed class CsMoneyAsset
|
|
{
|
|
[JsonPropertyName("id")] public long? Id { get; set; }
|
|
[JsonPropertyName("names")] public CsMoneyNames? Names { get; set; }
|
|
[JsonPropertyName("isStatTrak")] public bool IsStatTrak { get; set; }
|
|
[JsonPropertyName("isSouvenir")] public bool IsSouvenir { get; set; }
|
|
[JsonPropertyName("quality")] public string? Quality { get; set; }
|
|
[JsonPropertyName("pattern")] public int? Pattern { get; set; }
|
|
[JsonPropertyName("phase")] public string? Phase { get; set; }
|
|
[JsonPropertyName("float")] public decimal? Float { get; set; }
|
|
}
|
|
|
|
public sealed class CsMoneyNames
|
|
{
|
|
[JsonPropertyName("short")] public string? Short { get; set; }
|
|
[JsonPropertyName("full")] public string? Full { get; set; }
|
|
}
|
|
|
|
public sealed class CsMoneyPricing
|
|
{
|
|
[JsonPropertyName("default")] public decimal Default { get; set; }
|
|
[JsonPropertyName("priceBeforeDiscount")] public decimal? PriceBeforeDiscount { get; set; }
|
|
[JsonPropertyName("computed")] public decimal? Computed { get; set; }
|
|
}
|
|
|
|
public sealed class CsMoneyLinks
|
|
{
|
|
[JsonPropertyName("inspectLink")] public string? InspectLink { get; set; }
|
|
}
|
|
|
|
public sealed class CsMoneySticker
|
|
{
|
|
[JsonPropertyName("name")] public string? Name { get; set; }
|
|
}
|