Trackers: yggreborn affiche aussi envoyé/reçu (tuiles /account/)

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.
This commit is contained in:
jerem
2026-06-17 11:22:46 +02:00
parent e773259aa7
commit c253ecf226
3 changed files with 30 additions and 13 deletions

View File

@@ -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)
acc = await client.get(f"{spec.base_url}/account/")
text = re.sub(r"\s+", " ", re.sub(r"<[^>]+>", " ", acc.text))
rm = _YGG_RATIO.search(text)
if not rm:
raise _AuthError("ratio introuvable")
return TrackerStat(spec.key, spec.label, ok=True, ratio=float(rm.group(1)))
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 = {

View File

@@ -215,7 +215,7 @@
{% if t.ok %}<span class="ratio num">{{ t.ratio_h }}</span>
{% else %}<span class="io"><span class="ko">{{ t.error }}</span></span>{% endif %}
</div>
{% if t.ok %}{% if t.up_bytes or t.down_bytes %}<div class="io num">envoyé {{ t.up_h }} · reçu {{ t.down_h }}</div>{% endif %}
{% if t.ok %}{% if t.has_io %}<div class="io num">envoyé {{ t.up_h }} · reçu {{ t.down_h }}</div>{% endif %}
{% if t.tokens is not none %}<div class="io num">{{ t.tokens_h }} {{ t.tokens_label }}</div>{% endif %}{% endif %}
</div>
{% endfor %}

View File

@@ -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°"},