Trackers: ajoute yggreborn (Flask, login email+CSRF), ratio seul

Type yggreborn : login form classique (identifier=EMAIL, password, csrf_token),
ratio lu dans l'en-tête (Ratio : X.XX). Pas de up/down ni jetons (ligne envoyé/
reçu rendue conditionnelle sur up/down>0).
This commit is contained in:
jerem
2026-06-17 11:09:48 +02:00
parent f6f6694215
commit df9f384d57
4 changed files with 45 additions and 6 deletions

View File

@@ -29,6 +29,8 @@ from config import TrackerSpec, config
_UA = ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/126.0 Safari/537.36")
_CSRF_META = re.compile(r'name="csrf-token"\s+content="([^"]+)"')
_CSRF_INPUT = re.compile(r'name="csrf_token"[^>]*value="([^"]+)"')
_YGG_RATIO = re.compile(r"Ratio\s*:\s*([\d.]+)")
@dataclass
@@ -205,7 +207,37 @@ async def _fetch_tr4ker(spec: TrackerSpec) -> TrackerStat:
)
_FETCHERS = {"unit3d_nuxt": _fetch_unit3d, "torr9": _fetch_torr9, "tr4ker": _fetch_tr4ker}
async def _fetch_yggreborn(spec: TrackerSpec) -> TrackerStat:
"""yggreborn (YggTorrent) : site rendu serveur (Flask), login form classique avec
CSRF. ⚠️ l'`identifier` est l'EMAIL (champ `type=email`), pas le pseudo. Pas de token
API ; le ratio est affiché tel quel dans l'en-tête (« Ratio : 7.63 ») -> on le lit
directement (pas de up/down exposé simplement ; l'user veut juste le ratio)."""
if not (spec.base_url and spec.username and spec.password):
return TrackerStat(spec.key, spec.label, ok=False, error="non configuré")
async with httpx.AsyncClient(
timeout=20, follow_redirects=True, headers={"User-Agent": _UA},
) as client:
page = await client.get(f"{spec.base_url}/login")
m = _CSRF_INPUT.search(page.text)
if not m:
raise _AuthError("csrf introuvable")
resp = await client.post(f"{spec.base_url}/login", data={
"csrf_token": m.group(1), "identifier": spec.username, "password": spec.password,
})
if "incorrect" in resp.text.lower():
raise _AuthError("identifiants refusés (identifier = email)")
rm = _YGG_RATIO.search(resp.text)
if not rm:
raise _AuthError("ratio introuvable")
return TrackerStat(spec.key, spec.label, ok=True, ratio=float(rm.group(1)))
_FETCHERS = {
"unit3d_nuxt": _fetch_unit3d, "torr9": _fetch_torr9,
"tr4ker": _fetch_tr4ker, "yggreborn": _fetch_yggreborn,
}
async def _fetch_one(spec: TrackerSpec) -> TrackerStat: