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 ratio: float = 0.0
up_bytes: int = 0 up_bytes: int = 0
down_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: int | None = None # jetons/points de seed (None = le tracker n'en a pas)
tokens_label: str = "jetons" 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 @property
def tokens_h(self) -> str: def tokens_h(self) -> str:
return f"{self.tokens:,}".replace(",", " ") if self.tokens is not None else "" return f"{self.tokens:,}".replace(",", " ") if self.tokens is not None else ""
@@ -62,11 +70,11 @@ class TrackerStat:
@property @property
def up_h(self) -> str: 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 @property
def down_h(self) -> str: 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. # 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: async def _fetch_yggreborn(spec: TrackerSpec) -> TrackerStat:
"""yggreborn (YggTorrent) : site rendu serveur (Flask), login form classique avec """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 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 API : on lit la page `/account/` qui affiche les tuiles « 60.55 Go Upload », « 7.94 Go
directement (pas de up/down exposé simplement ; l'user veut juste le ratio).""" 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): if not (spec.base_url and spec.username and spec.password):
return TrackerStat(spec.key, spec.label, ok=False, error="non configuré") 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(): if "incorrect" in resp.text.lower():
raise _AuthError("identifiants refusés (identifier = email)") raise _AuthError("identifiants refusés (identifier = email)")
rm = _YGG_RATIO.search(resp.text) acc = await client.get(f"{spec.base_url}/account/")
if not rm:
raise _AuthError("ratio introuvable")
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 = { _FETCHERS = {

View File

@@ -215,7 +215,7 @@
{% if t.ok %}<span class="ratio num">{{ t.ratio_h }}</span> {% if t.ok %}<span class="ratio num">{{ t.ratio_h }}</span>
{% else %}<span class="io"><span class="ko">{{ t.error }}</span></span>{% endif %} {% else %}<span class="io"><span class="ko">{{ t.error }}</span></span>{% endif %}
</div> </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 %} {% if t.tokens is not none %}<div class="io num">{{ t.tokens_h }} {{ t.tokens_label }}</div>{% endif %}{% endif %}
</div> </div>
{% endfor %} {% endfor %}

View File

@@ -67,10 +67,10 @@ CTX = {
"vpn_ok": True, "vpn_port": 51820, "vpn_ok": True, "vpn_port": 51820,
}, },
"trackers": [ "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": "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", "up_bytes": 1, "up_h": "226 Go", "down_h": "140 Go", "tokens": 2168, "tokens_h": "2 168", "tokens_label": "jetons"}, {"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", "up_bytes": 1, "up_h": "5,62 To", "down_h": "1 Go", "tokens": 223, "tokens_h": "223", "tokens_label": "Crédit"}, {"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", "up_bytes": 0, "down_bytes": 0, "tokens": None}, {"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": [ "ha_states": [
{"label": "Salon", "display": "21°"}, {"label": "Salon", "display": "21°"},