#!/usr/bin/env python # -*- coding: utf-8 -*- """Liveness pass over a proxy pool: curl ipinfo through each URL. Usage: python verify.py pool.jsonl [--limit N] [--timeout SEC] Prints one line per proxy and a summary: alive / unique_ip / countries. """ import argparse import json import subprocess import sys try: sys.stdout.reconfigure(encoding="utf-8") except Exception: pass ap = argparse.ArgumentParser() ap.add_argument("pool") ap.add_argument("--limit", type=int, default=0, help="0 = all") ap.add_argument("--timeout", type=int, default=35) ap.add_argument("--out", default="verify.json") a = ap.parse_args() rows = [json.loads(l) for l in open(a.pool, encoding="utf-8") if l.strip()] if a.limit: rows = rows[:a.limit] alive, ips, ccs = 0, set(), set() for r in rows: out = subprocess.run(["curl", "-s", "-m", str(a.timeout), "--proxy", r["url"], "https://ipinfo.io/json"], capture_output=True, text=True, timeout=a.timeout + 25).stdout try: d = json.loads(out) except Exception: d = {} r.update({"ip": d.get("ip"), "country": d.get("country"), "city": d.get("city"), "org": d.get("org")}) if d.get("ip"): alive += 1 ips.add(d["ip"]) ccs.add(d.get("country")) print("%-4s %-3s %-16s %-3s %-14s %s" % (r.get("acct"), r.get("cc"), d.get("ip", "FAIL"), d.get("country", "--"), (d.get("city") or "")[:14], (d.get("org") or "")[:26])) json.dump(rows, open(a.out, "w", encoding="utf-8"), ensure_ascii=False, indent=1) print("\nTOTAL %d | alive %d | unique_ip %d | countries %d %s" % (len(rows), alive, len(ips), len(ccs), sorted(c for c in ccs if c)))