From df9f384d5796dfa567c20b2ce97134b6e3fa7a9a Mon Sep 17 00:00:00 2001 From: jerem Date: Wed, 17 Jun 2026 11:09:48 +0200 Subject: [PATCH] Trackers: ajoute yggreborn (Flask, login email+CSRF), ratio seul MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- .env.example | 7 +++++++ backend/integrations/trackers.py | 34 +++++++++++++++++++++++++++++++- backend/templates/dashboard.html | 2 +- dev/preview.py | 8 ++++---- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index da42a51..aa21662 100644 --- a/.env.example +++ b/.env.example @@ -60,6 +60,13 @@ MONITORINK_CODEX_TOKEN_FILE=/hermes/auth.json #MONITORINK_TRACKER_TR4KER_URL=https://tr4ker.net #MONITORINK_TRACKER_TR4KER_USER=TonIdentifiant #MONITORINK_TRACKER_TR4KER_PASS=TonMotDePasse +# yggreborn (YggTorrent) : type "yggreborn" (Flask + CSRF). ⚠️ USER = EMAIL (login par email). +# Ratio seul (lu dans l'en-tête), pas de up/down ni jetons. +#MONITORINK_TRACKER_YGGREBORN_LABEL=yggreborn +#MONITORINK_TRACKER_YGGREBORN_TYPE=yggreborn +#MONITORINK_TRACKER_YGGREBORN_URL=https://www.yggreborn.org +#MONITORINK_TRACKER_YGGREBORN_USER=ton.email@exemple.com +#MONITORINK_TRACKER_YGGREBORN_PASS=TonMotDePasse #MONITORINK_TRACKER_TTL=1800 # Home Assistant (optionnel) — laisser vide pour désactiver diff --git a/backend/integrations/trackers.py b/backend/integrations/trackers.py index 16b01b6..9fe4ecb 100644 --- a/backend/integrations/trackers.py +++ b/backend/integrations/trackers.py @@ -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: diff --git a/backend/templates/dashboard.html b/backend/templates/dashboard.html index 0c8550f..d6a3918 100644 --- a/backend/templates/dashboard.html +++ b/backend/templates/dashboard.html @@ -215,7 +215,7 @@ {% if t.ok %}{{ t.ratio_h }} {% else %}{{ t.error }}{% endif %} - {% if t.ok %}
envoyé {{ t.up_h }} · reçu {{ t.down_h }}
+ {% if t.ok %}{% if t.up_bytes or t.down_bytes %}
envoyé {{ t.up_h }} · reçu {{ t.down_h }}
{% endif %} {% if t.tokens is not none %}
{{ t.tokens_h }} {{ t.tokens_label }}
{% endif %}{% endif %} {% endfor %} diff --git a/dev/preview.py b/dev/preview.py index 51f32c4..42994f9 100644 --- a/dev/preview.py +++ b/dev/preview.py @@ -67,10 +67,10 @@ CTX = { "vpn_ok": True, "vpn_port": 51820, }, "trackers": [ - {"ok": True, "label": "c411", "ratio_h": "1,04", "up_h": "378 Go", "down_h": "365 Go", "tokens": None}, - {"ok": True, "label": "torr9", "ratio_h": "1,62", "up_h": "226 Go", "down_h": "140 Go", "tokens": 2168, "tokens_h": "2 168", "tokens_label": "jetons"}, - {"ok": True, "label": "tr4ker", "ratio_h": "5233,52", "up_h": "5,62 To", "down_h": "1 Go", "tokens": 223, "tokens_h": "223", "tokens_label": "Crédit"}, - {"ok": False, "label": "yggreborn", "error": "2FA requise"}, + {"ok": True, "label": "c411", "ratio_h": "1,04", "up_bytes": 1, "up_h": "378 Go", "down_h": "365 Go", "tokens": None}, + {"ok": True, "label": "torr9", "ratio_h": "1,62", "up_bytes": 1, "up_h": "226 Go", "down_h": "140 Go", "tokens": 2168, "tokens_h": "2 168", "tokens_label": "jetons"}, + {"ok": True, "label": "tr4ker", "ratio_h": "5233,52", "up_bytes": 1, "up_h": "5,62 To", "down_h": "1 Go", "tokens": 223, "tokens_h": "223", "tokens_label": "Crédit"}, + {"ok": True, "label": "yggreborn", "ratio_h": "7,63", "up_bytes": 0, "down_bytes": 0, "tokens": None}, ], "ha_states": [ {"label": "Salon", "display": "21°"},