goon/app/extractors/_models.py
goon-foss a4486980a4 style: myslniki em/en z komentarzy i docstringow (calosc repo)
1745 wystapien w 291 plikach (backend, scripts, mobile). Dominowal jeden ksztalt,
' — ' laczace zdania, wiec poszedl przecinek; myslnik otwierajacy mysl zdjety;
zakresy 0–5 i A–Z na dywiz.

Podzial komentarz/kod robil skaner stanow, nie regex, zeby nie ruszyc myslnika
stojacego w stringu albo w wyrazeniu regularnym. Potwierdzone maszynowo: po wycieciu
komentarzy z wersji HEAD i z dysku obie sa identyczne we wszystkich 291 plikach,
czyli poza komentarzami nie zmienilo sie nic. 233 pliki .py parsuja sie bez bledu,
tsc ma te same 11 bledow w tych samych 3 plikach co przed zmiana.

Dwie rzeczy wymagaly poprawki po automacie: wyrownane listy definicji, gdzie myslnik
byl separatorem kolumny (37 miejsc, kolumna przywrocona), i trzy przeniesienia mysli
do nowej linii, gdzie zostawal wiszacy przecinek na poczatku (poprawione recznie).

Bundla nie republikuje: Hermes i tak nie niesie komentarzy, wiec dla uzytkownika
to zero zmiany.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 11:51:57 +02:00

48 lines
1.5 KiB
Python

"""Stream source DTO + wspólne wyjątki extractorów."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
@dataclass
class StreamSource:
"""Pojedynczy resolved stream URL.
Mapuje na `StreamLink` w playback API (api/playback.py), `link` → `stream_url`,
`quality` → `quality`, `type` → `type`.
`referer`, opcjonalny override Referera używanego przez stream_proxy. Niektóre
CDN-y (KVS-style watchporn.to, fpo.xxx itp.) zwracają 410/403 gdy Referer nie
pasuje do *embed page'a* (np. proxy używa `Referer: 0dayxx.com` ale CDN expectuje
`Referer: watchporn.to`). Gdy None → caller (playback.py) używa `page_url`.
"""
link: str
quality: str | None = None
type: str | None = None # 'mp4' | 'm3u8' | 'mpd' | 'hoster'
raw: dict[str, Any] | None = None
referer: str | None = None
class HosterDead(Exception):
"""Hoster embed page mówi że video jest skasowane / nie istnieje.
Caller w playback.py łapie i oznacza `playback_source.dead_at`.
"""
class TubePageError(Exception):
"""Tube page fetch zwrócił HTTP error (404/410/5xx).
Caller (playback.py) może oznaczyć dead_at jeśli 404/410. Trzymamy `status_code`
+ `url` w atrybutach żeby caller nie musiał parsować message stringa.
"""
def __init__(self, status_code: int, url: str):
super().__init__(f"HTTP {status_code} for {url}")
self.status_code = status_code
self.url = url
__all__ = ["StreamSource", "HosterDead", "TubePageError"]