remove selenium related code for now
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
using BlueLaminate.Cli;
|
||||
using BlueLaminate.Cli.Logging;
|
||||
using BlueLaminate.EFCore.Data;
|
||||
using BlueLaminate.Scraper.Browser;
|
||||
using BlueLaminate.Scraper.CsFloat;
|
||||
using BlueLaminate.Scraper.Proxies;
|
||||
using BlueLaminate.Scraper.Skins;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenTelemetry;
|
||||
@@ -49,30 +47,6 @@ syncSkins.SetAction((parseResult, ct) =>
|
||||
loggerFactory,
|
||||
ct));
|
||||
|
||||
var countryOption = new Option<string?>("--country")
|
||||
{
|
||||
Description = "Optional ISO country code(s) for the exit IP, e.g. \"us\" or \"us,gb\". Default: random."
|
||||
};
|
||||
var rotatingOption = new Option<bool>("--rotating")
|
||||
{
|
||||
Description = "Use a rotating exit IP instead of a pinned (sticky) session."
|
||||
};
|
||||
|
||||
var probeProxy = new Command(
|
||||
"probe-proxy",
|
||||
"Launch non-headless Edge through the IPRoyal residential proxy and print the exit IP "
|
||||
+ "to confirm auth works and the IP is residential. Reads IPROYAL_USERNAME / IPROYAL_PASSWORD.")
|
||||
{
|
||||
countryOption,
|
||||
rotatingOption,
|
||||
};
|
||||
probeProxy.SetAction((parseResult, ct) =>
|
||||
ProbeProxyAsync(
|
||||
parseResult.GetValue(countryOption),
|
||||
parseResult.GetValue(rotatingOption),
|
||||
loggerFactory,
|
||||
ct));
|
||||
|
||||
var defIndexOption = new Option<int?>("--def-index")
|
||||
{
|
||||
Description = "CSFloat weapon def_index (e.g. AK-47=7, M4A4=16)."
|
||||
@@ -81,50 +55,6 @@ var paintIndexOption = new Option<int?>("--paint-index")
|
||||
{
|
||||
Description = "CSFloat paint_index for a specific skin (e.g. M4A4 | Cyber Security=985)."
|
||||
};
|
||||
var urlOption = new Option<string?>("--url")
|
||||
{
|
||||
Description = "Full CSFloat URL to open. Overrides --def-index/--paint-index when set."
|
||||
};
|
||||
var loadImagesOption = new Option<bool>("--load-images")
|
||||
{
|
||||
Description = "Load images (uses more bandwidth). Default off to conserve the metered plan."
|
||||
};
|
||||
var diagnoseOption = new Option<bool>("--diagnose")
|
||||
{
|
||||
Description = "Log every CSFloat-domain response (url + status + type) to reveal where a "
|
||||
+ "Steam-login wall appears, not just /api/ JSON."
|
||||
};
|
||||
var outOption = new Option<string>("--out")
|
||||
{
|
||||
Description = "Directory to write captured JSON to.",
|
||||
DefaultValueFactory = _ => "captures",
|
||||
};
|
||||
|
||||
var captureCsfloat = new Command(
|
||||
"capture-csfloat",
|
||||
"Open a CSFloat search page through the residential proxy and dump every CSFloat /api/ "
|
||||
+ "JSON response to disk while you browse (open a listing → 'Latest Sales'). "
|
||||
+ "Reads IPROYAL_USERNAME / IPROYAL_PASSWORD.")
|
||||
{
|
||||
defIndexOption,
|
||||
paintIndexOption,
|
||||
urlOption,
|
||||
countryOption,
|
||||
loadImagesOption,
|
||||
diagnoseOption,
|
||||
outOption,
|
||||
};
|
||||
captureCsfloat.SetAction((parseResult, ct) =>
|
||||
CaptureCsfloatAsync(
|
||||
parseResult.GetValue(defIndexOption),
|
||||
parseResult.GetValue(paintIndexOption),
|
||||
parseResult.GetValue(urlOption),
|
||||
parseResult.GetValue(countryOption),
|
||||
parseResult.GetValue(loadImagesOption),
|
||||
parseResult.GetValue(diagnoseOption),
|
||||
parseResult.GetValue(outOption)!,
|
||||
loggerFactory,
|
||||
ct));
|
||||
|
||||
var sortByOption = new Option<string>("--sort-by")
|
||||
{
|
||||
@@ -226,8 +156,6 @@ sweepCatalog.SetAction((parseResult, ct) =>
|
||||
var root = new RootCommand("BlueLaminate CLI — Counter-Strike skin tracker tools.")
|
||||
{
|
||||
syncSkins,
|
||||
probeProxy,
|
||||
captureCsfloat,
|
||||
fetchListings,
|
||||
sweepListings,
|
||||
sweepCatalog,
|
||||
@@ -235,111 +163,6 @@ var root = new RootCommand("BlueLaminate CLI — Counter-Strike skin tracker too
|
||||
|
||||
return await root.Parse(args).InvokeAsync();
|
||||
|
||||
// Acquire an IPRoyal residential lease, drive a real (non-headless) Edge browser
|
||||
// through it, and report the exit IP. This is the proxy/Selenium spike: it proves
|
||||
// authenticated residential routing end-to-end for a few KB before any CSFloat
|
||||
// scraping spends real bandwidth.
|
||||
static async Task<int> ProbeProxyAsync(
|
||||
string? country, bool rotating, ILoggerFactory loggerFactory, CancellationToken ct)
|
||||
{
|
||||
var username = Environment.GetEnvironmentVariable("IPROYAL_USERNAME");
|
||||
var password = Environment.GetEnvironmentVariable("IPROYAL_PASSWORD");
|
||||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||
{
|
||||
Console.Error.WriteLine(
|
||||
"Set IPROYAL_USERNAME and IPROYAL_PASSWORD environment variables first.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
var provider = new IpRoyalProxyProvider(username, password);
|
||||
var factory = new BrowserDriverFactory(loggerFactory.CreateLogger<BrowserDriverFactory>());
|
||||
var probe = new ProxyProbe(provider, factory, loggerFactory.CreateLogger<ProxyProbe>());
|
||||
|
||||
try
|
||||
{
|
||||
var info = await probe.RunAsync(new ProxyRequest(Country: country, Sticky: !rotating));
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($" Exit IP : {info.Ip}");
|
||||
Console.WriteLine($" Location: {info.City}, {info.Region}, {info.Country}");
|
||||
Console.WriteLine($" Org/ASN : {info.Org}");
|
||||
Console.WriteLine($" Hostname: {info.Hostname ?? "—"}");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(
|
||||
"Check Org/ASN: a consumer ISP = residential; a hosting provider = datacenter.");
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"Proxy probe failed: {ex.Message}");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase B: open a CSFloat search page through the residential proxy and dump
|
||||
// every CSFloat /api/ JSON response to disk while the operator browses. This is
|
||||
// how we discover the real endpoint/field shapes (active listings + Latest
|
||||
// Sales) before designing tables or automating navigation.
|
||||
static async Task<int> CaptureCsfloatAsync(
|
||||
int? defIndex, int? paintIndex, string? url, string? country,
|
||||
bool loadImages, bool diagnose, string outDir, ILoggerFactory loggerFactory, CancellationToken ct)
|
||||
{
|
||||
var username = Environment.GetEnvironmentVariable("IPROYAL_USERNAME");
|
||||
var password = Environment.GetEnvironmentVariable("IPROYAL_PASSWORD");
|
||||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||
{
|
||||
Console.Error.WriteLine(
|
||||
"Set IPROYAL_USERNAME and IPROYAL_PASSWORD environment variables first.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
var targetUrl = BuildCsfloatUrl(url, defIndex, paintIndex);
|
||||
var provider = new IpRoyalProxyProvider(username, password);
|
||||
var factory = new BrowserDriverFactory(loggerFactory.CreateLogger<BrowserDriverFactory>());
|
||||
var capture = new CsFloatCaptureService(
|
||||
provider, factory, loggerFactory.CreateLogger<CsFloatCaptureService>());
|
||||
|
||||
Console.WriteLine($"Opening {targetUrl}");
|
||||
Console.WriteLine(
|
||||
"When the page loads: click a listing, then the 'Latest Sales' tab. "
|
||||
+ "Capturing all CSFloat /api/ responses.");
|
||||
Console.WriteLine("Press Enter here when you're done to close the browser.");
|
||||
|
||||
try
|
||||
{
|
||||
// Block until the operator presses Enter; the browser stays open and
|
||||
// capturing the whole time. ReadLine is sync, so push it off-thread.
|
||||
var count = await capture.RunAsync(
|
||||
targetUrl,
|
||||
outDir,
|
||||
new ProxyRequest(Country: country, Sticky: true),
|
||||
loadImages,
|
||||
diagnose,
|
||||
() => Task.Run(() => Console.ReadLine(), ct));
|
||||
|
||||
var full = Path.GetFullPath(outDir);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"Captured {count} response(s) to {full}");
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"CSFloat capture failed: {ex.Message}");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer an explicit --url; otherwise build a search URL from the indexes,
|
||||
// defaulting to the M4A4 | Cyber Security example so the command runs as-is.
|
||||
static string BuildCsfloatUrl(string? url, int? defIndex, int? paintIndex)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
return url;
|
||||
|
||||
var def = defIndex ?? 16;
|
||||
var paint = paintIndex ?? 985;
|
||||
return $"https://csfloat.com/search?def_index={def}&paint_index={paint}";
|
||||
}
|
||||
|
||||
// Fetch active listings for one skin via CSFloat's official API and print them.
|
||||
// Fetch-and-print only — no DB — so we can verify the real field shapes against a
|
||||
// live key before designing the Listing schema. Defaults to the M4A4 | Cyber
|
||||
|
||||
Reference in New Issue
Block a user