diff --git a/app/extractors/tubes/_kvs.py b/app/extractors/tubes/_kvs.py index 0bc7270..3a5ed94 100644 --- a/app/extractors/tubes/_kvs.py +++ b/app/extractors/tubes/_kvs.py @@ -40,6 +40,13 @@ _LICENSE_RE = re.compile(r"license_code\s*:\s*[\"'](\$[^\"']+)[\"']", re.IGNOREC _HASH_LENGTH = 32 +# get_file 302-follow timeout. Zdrowy CDN odpowiada <1s; gdy wideo zostało usunięte +# z CDN (strona istnieje, ale get_file stalluje) request wisi do timeoutu. Trzymamy +# go NISKO i osobno od page-fetch timeoutu — bug 6ec1960e 2026-06-02: yesporn.vip +# przeszedł na cdn4/remote_control.php i dla martwych scen wszystkie 3 jakości +# wisiały po 60s = 180s → mobile "resolving w nieskończoność". +_GETFILE_TIMEOUT = 10.0 + def _license_token(license_code: str) -> list[int]: license_code = license_code.replace("$", "") @@ -134,16 +141,25 @@ def resolve_kvs(page_url: str, *, base_url: str, timeout: float = 60.0) -> list[ for m in _TEXT_RE.finditer(html): quality_by_var[m.group(1).lower()] = m.group(2).strip() + # get_file timeout NISKI (osobny od page-fetch) + early-break: gdy 2 pierwsze + # jakości nie rozwiążą się (przy 0 dotychczasowych wyników) scena jest martwa na + # CDN — nie ma sensu czekać na trzecią (oszczędza kolejne _GETFILE_TIMEOUT). + gf_timeout = min(timeout, _GETFILE_TIMEOUT) seen_dec: set[str] = set() result: list[StreamSource] = [] + fails = 0 for m in _URL_RE.finditer(html): var_name = m.group(1).lower() decoded = real_url(m.group(2), license_code) if decoded in seen_dec: continue seen_dec.add(decoded) - final = _resolve_get_file(session, base_url, decoded, timeout) + final = _resolve_get_file(session, base_url, decoded, gf_timeout) if not final: + fails += 1 + if fails >= 2 and not result: + log.info("kvs: %d get_file fails, 0 results — martwa scena? %s", fails, page_url) + break continue result.append( StreamSource(