"""4k69.com — get_file stream extractor (platforma jak fullmovies/hdporngg). Scene page (SSR za Cloudflare → curl_cffi) ma 3 get_file URL-e na www.4kporno.xxx (`..._2160m.mp4` / `_720m` / `_480m`) — w JSON-LD contentUrl i w JS playera, NIE w `` tagach (dlatego nie _source_getfile, tylko skan całej strony). Jak fpvcdn (fullmovies, ta sama rodzina `/get_file/8512/`): get_file binduje CDN do IP fetchera, jest stateless i ważny ≥90s → oddajemy NIEZRESOLWOWANE z mobile_direct_ok — telefon follow-uje 302 z własnym IP (cross-IP test 2026-06-10: lokalny ISP 206 video/mp4). 2160p pomijamy (CDN time-out ~30s, jak fpvcdn). """ from __future__ import annotations import logging import re from app.extractors._fetch import fetch_tube_html from app.extractors._models import StreamSource log = logging.getLogger(__name__) _GET_FILE_RE = re.compile(r"https://[a-z0-9.\-]+/get_file/[^\s\"'\\]+\.mp4/?", re.IGNORECASE) _QUALITY_RE = re.compile(r"_(\d{3,4})[mp]?\.mp4", re.IGNORECASE) _SKIP_QUALITY_RE = re.compile(r"^(2160|1440)$") def extract(page_url: str, *, timeout: float = 60.0) -> list[StreamSource] | None: html = fetch_tube_html(page_url, timeout=timeout) seen: set[str] = set() out: list[StreamSource] = [] for m in _GET_FILE_RE.finditer(html): url = m.group(0) if url in seen: continue seen.add(url) qm = _QUALITY_RE.search(url) quality_num = qm.group(1) if qm else None if quality_num and _SKIP_QUALITY_RE.match(quality_num): continue # `_preview.mp4` itp. bez liczby jakości — pomiń (trailer, nie scena). if not quality_num: continue out.append(StreamSource( link=url, quality=f"{quality_num}p", type="mp4", referer="https://4k69.com/", raw={"mobile_direct_ok": True}, )) if not out: log.info("4k69: no get_file URLs on %s", page_url) return None out.sort(key=lambda s: int((s.quality or "0p")[:-1]), reverse=True) return out