From c253ecf226ba6c132faa660e04a737c3b2b84a5c Mon Sep 17 00:00:00 2001 From: jerem Date: Wed, 17 Jun 2026 11:22:46 +0200 Subject: [PATCH] =?UTF-8?q?Trackers:=20yggreborn=20affiche=20aussi=20envoy?= =?UTF-8?q?=C3=A9/re=C3=A7u=20(tuiles=20/account/)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lecture des tuiles Upload/Download de /account/ (libellés Go/To gardés tels quels via up_str/down_str pour conserver les décimales). Condition io -> has_io. --- backend/integrations/trackers.py | 33 ++++++++++++++++++++++++-------- backend/templates/dashboard.html | 2 +- dev/preview.py | 8 ++++---- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/backend/integrations/trackers.py b/backend/integrations/trackers.py index 9fe4ecb..9c870f9 100644 --- a/backend/integrations/trackers.py +++ b/backend/integrations/trackers.py @@ -42,9 +42,17 @@ class TrackerStat: ratio: float = 0.0 up_bytes: int = 0 down_bytes: int = 0 + # Affichage envoyé/reçu pré-formaté (si le tracker fournit des libellés tout faits + # plutôt que des octets bruts, ex. yggreborn) ; sinon on formate up_bytes/down_bytes. + up_str: str | None = None + down_str: str | None = None tokens: int | None = None # jetons/points de seed (None = le tracker n'en a pas) tokens_label: str = "jetons" + @property + def has_io(self) -> bool: + return bool(self.up_bytes or self.down_bytes or self.up_str or self.down_str) + @property def tokens_h(self) -> str: return f"{self.tokens:,}".replace(",", " ") if self.tokens is not None else "" @@ -62,11 +70,11 @@ class TrackerStat: @property def up_h(self) -> str: - return self._human(self.up_bytes) + return self.up_str if self.up_str is not None else self._human(self.up_bytes) @property def down_h(self) -> str: - return self._human(self.down_bytes) + return self.down_str if self.down_str is not None else self._human(self.down_bytes) # Sessions réutilisées (cookies httpx) et derniers résultats connus, par tracker. @@ -210,8 +218,9 @@ async def _fetch_tr4ker(spec: TrackerSpec) -> TrackerStat: 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).""" + API : on lit la page `/account/` qui affiche les tuiles « 60.55 Go Upload », « 7.94 Go + Download » et « Ratio : 7.63 ». Pas de jetons (non demandé). Les libellés Go/To du site + sont gardés tels quels (up_str/down_str) pour ne pas perdre les décimales.""" if not (spec.base_url and spec.username and spec.password): return TrackerStat(spec.key, spec.label, ok=False, error="non configuré") @@ -227,11 +236,19 @@ async def _fetch_yggreborn(spec: TrackerSpec) -> TrackerStat: }) 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") + acc = await client.get(f"{spec.base_url}/account/") - return TrackerStat(spec.key, spec.label, ok=True, ratio=float(rm.group(1))) + text = re.sub(r"\s+", " ", re.sub(r"<[^>]+>", " ", acc.text)) + rm = _YGG_RATIO.search(text) + if not rm: + raise _AuthError("ratio introuvable") + up = re.search(r"([\d.,]+\s*[KMGT]?o)\s*Upload\b", text) + dn = re.search(r"([\d.,]+\s*[KMGT]?o)\s*Download\b", text) + return TrackerStat( + spec.key, spec.label, ok=True, ratio=float(rm.group(1)), + up_str=up.group(1).strip().replace(".", ",") if up else None, + down_str=dn.group(1).strip().replace(".", ",") if dn else None, + ) _FETCHERS = { diff --git a/backend/templates/dashboard.html b/backend/templates/dashboard.html index 5a81f0b..2e82a40 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 %}{% if t.up_bytes or t.down_bytes %}
envoyé {{ t.up_h }} · reçu {{ t.down_h }}
{% endif %} + {% if t.ok %}{% if t.has_io %}
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 42994f9..be6c9ee 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_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}, + {"ok": True, "label": "c411", "ratio_h": "1,04", "has_io": True, "up_h": "378 Go", "down_h": "365 Go", "tokens": None}, + {"ok": True, "label": "torr9", "ratio_h": "1,62", "has_io": True, "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", "has_io": True, "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", "has_io": True, "up_h": "60,55 Go", "down_h": "7,94 Go", "tokens": None}, ], "ha_states": [ {"label": "Salon", "display": "21°"},