"""4k69.com — okcdn.ru (OK.ru CDN) direct stream extractor. 2026-06-14: 4k69 zmigrowało player z get_file (4kporno.xxx) na jwplayer + okcdn.ru (OK.ru video CDN). Strona (SSR za Cloudflare → curl_cffi/proxy) ma w inline jwplayer setupie pary `"file": "", "label": ""` na WSZYSTKIE jakości (4K/2K/1080p/720p/480p/360p/240p). To samo w LD-JSON `contentUrl` (jeden, niższy). okcdn URL ma `expires=` (time-bound), `srcIp=` (IP edge Cloudflare który frontował fetch) i `sig=` per jakość. KLUCZOWE (reverse-engineer + cross-IP test 2026-06-14): `srcIp` NIE jest egzekwowane — URL gra z dowolnego IP (206 video/mp4 z residential IP ≠ srcIp). Więc resolwujemy server-side i oddajemy `mobile_direct_ok` → telefon gra DIRECT, zero VPS proxy, zero WebView/reklam (VAST preroll jest runtime-only, nie ma go w statycznym HTML, więc parsując HTML omijamy go całkiem). Pomijamy 4K/2K (jak wcześniej 2160/1440 — za duże na mobile). """ 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__) # Pary file+label z jwplayer setupu: "file":"","label":"1080p". Label bierzemy # wprost ze strony (pewniejsze niż mapowanie OK.ru type=N). _OKCDN_FILE_RE = re.compile( r'"file"\s*:\s*"(https?://[^"]*okcdn[^"]+)"\s*,\s*"label"\s*:\s*"([^"]+)"', re.IGNORECASE, ) # Za duże na mobile (jak stary skip 2160/1440). _SKIP_LABEL_RE = re.compile(r"^(4k|2k|2160|1440)", re.IGNORECASE) def _quality_num(label: str) -> int: m = re.match(r"(\d+)", label or "") return int(m.group(1)) if m else 0 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 _OKCDN_FILE_RE.finditer(html): url = m.group(1).replace("&", "&") label = m.group(2).strip() if url in seen: continue seen.add(url) if _SKIP_LABEL_RE.match(label): continue out.append(StreamSource( link=url, quality=label, type="mp4", referer="https://4k69.com/", # srcIp nieegzekwowane (cross-IP test 2026-06-14) → telefon gra direct. raw={"mobile_direct_ok": True}, )) if not out: log.info("4k69: no okcdn sources on %s", page_url) return None out.sort(key=lambda s: _quality_num(s.quality or ""), reverse=True) return out