KeyHunter parser v10 + 18 scanners + tests (synthetic fixtures only, no keys/db/tokens)
This commit is contained in:
106
revalidate_live.py
Normal file
106
revalidate_live.py
Normal file
@@ -0,0 +1,106 @@
|
||||
"""Re-validate all keys whose status claims WORKING/FREE/LIMITED.
|
||||
|
||||
Root cause: validator_loop only re-checks NEW keys; stale live statuses rot.
|
||||
This script reconciles DB with reality using eternal_v10's m.validate().
|
||||
No inner threads — m.validate already has per-request timeouts.
|
||||
"""
|
||||
import importlib.util
|
||||
import sqlite3
|
||||
import sys
|
||||
import time
|
||||
from collections import Counter
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from pathlib import Path
|
||||
import threading
|
||||
|
||||
PROJ = Path(__file__).resolve().parent
|
||||
DB_PATH = PROJ / "data" / "keys.db"
|
||||
EV10 = PROJ / "src" / "eternal_v10.py"
|
||||
THREADS = 10 # conservative to avoid WAL contention with harvesters
|
||||
LIVE = {"WORKING", "LIMITED", "FREE"}
|
||||
|
||||
_lock = threading.Lock()
|
||||
_statuses = Counter()
|
||||
_prov_live = Counter()
|
||||
_prov_dead = Counter()
|
||||
|
||||
# --- import eternal_v10 ---
|
||||
spec = importlib.util.spec_from_file_location("ev10_reval", str(EV10))
|
||||
m = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(m)
|
||||
print("[init] eternal_v10 imported", flush=True)
|
||||
|
||||
# Patch _DB_LOCK to no-op: each _connect() creates own connection,
|
||||
# WAL handles concurrent writes. Avoids contention with harvesters.
|
||||
class _NoopLock:
|
||||
def __enter__(self): return self
|
||||
def __exit__(self, *a): pass
|
||||
def acquire(self, *a): return True
|
||||
def release(self): pass
|
||||
m._DB_LOCK = _NoopLock()
|
||||
print("[init] _DB_LOCK patched to no-op", flush=True)
|
||||
# --- runtime GOOGLE patch ---
|
||||
GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models"
|
||||
|
||||
def _v_google(_prov, key):
|
||||
try:
|
||||
r = m.requests.get(GEMINI_URL, params={"key": key}, timeout=15)
|
||||
if r.status_code == 200:
|
||||
n = len(r.json().get("models", []))
|
||||
return "WORKING", "GEMINI API", f"{n} models", str(n)
|
||||
if r.status_code == 429:
|
||||
return "WORKING", "GEMINI API (rate-limited)", "429", "429"
|
||||
return "DEAD", "", "", ""
|
||||
except Exception:
|
||||
return "ERR", "", "", ""
|
||||
|
||||
m.VALIDATORS["google"] = _v_google
|
||||
print("[init] GOOGLE runtime validator patched", flush=True)
|
||||
|
||||
db = sqlite3.connect(str(DB_PATH), timeout=120)
|
||||
rows = db.execute(
|
||||
"SELECT val, prov FROM keys "
|
||||
"WHERE status IN ('WORKING','FREE','LIMITED') "
|
||||
"ORDER BY id"
|
||||
).fetchall()
|
||||
db.close()
|
||||
total = len(rows)
|
||||
print(f"[init] revalidating {total} stale-live keys", flush=True)
|
||||
if not rows:
|
||||
print("[done] nothing to revalidate", flush=True)
|
||||
sys.exit(0)
|
||||
|
||||
done = 0
|
||||
|
||||
def work(item):
|
||||
global done
|
||||
val, prov = item
|
||||
try:
|
||||
res = m.validate(val, prov)
|
||||
st = res[0]
|
||||
except Exception as e:
|
||||
st = "ERR"
|
||||
with _lock:
|
||||
_statuses[st] += 1
|
||||
if st in LIVE:
|
||||
_prov_live[prov] += 1
|
||||
else:
|
||||
_prov_dead[prov] += 1
|
||||
done += 1
|
||||
if done % 50 == 0 or done == total:
|
||||
print(f"[{done}/{total}] " + " ".join(f"{s}={c}" for s, c in _statuses.most_common()), flush=True)
|
||||
return st
|
||||
|
||||
t0 = time.time()
|
||||
with ThreadPoolExecutor(max_workers=THREADS) as ex:
|
||||
futures = {ex.submit(work, r): r for r in rows}
|
||||
for f in as_completed(futures):
|
||||
pass # work() handles counters internally
|
||||
|
||||
print(f"[done] {total} keys in {(time.time()-t0)/60:.1f} min", flush=True)
|
||||
print("=== live after ===", flush=True)
|
||||
for p, c in _prov_live.most_common():
|
||||
print(f" {p}: {c}", flush=True)
|
||||
print("=== dead/err ===", flush=True)
|
||||
for p, c in _prov_dead.most_common():
|
||||
print(f" {p}: {c}", flush=True)
|
||||
Reference in New Issue
Block a user