"""yesporn.vip — KVS engine direct stream extractor. User bug-report 2026-05-27 (#1, scene 0d8ec317): "Yespornvip dalej nie działa". Origin `tube:yespornvip` istniał w playback_sources ale brak wpisu w `_REGISTRY` → `try_extract()` zwracał None → mobile player no-source. Detail page sceny linkuje do `/embed/` w iframe. Embed page renderuje KVS player z `flashvars`: - `video_url: 'function/0/https://yesporn.vip/get_file/7//.../.mp4/?embed=true'` — **NIE używać.** Server `/get_file/7/` wymaga PHPSESSID + cookies z embed page (testowane 2026-05-29: 404 nawet z fresh tokenem, mobile-side cookies nie matchują VPS-side session). KVS kt_player.js loaduje to wewnątrz embed page gdzie cookies są dostępne. - `event_reporting2: 'https://yesporn.vip/get_file/1//.../.mp4/'` — server `/get_file/1/` jest standalone, time-bound signed URL, **200 OK** direct fetch z headerami (UA + Referer). Bierzemy to. - `video_url_text: '480p'` — quality label. Single quality (480p) z embed. CDN time-bound signed, mobile gra direct z phone IP (zero VPS bandwidth). """ 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__) _BASE = "https://yesporn.vip" # `event_reporting2: 'https://.../get_file/1/.../.mp4/'` — analytics ping URL # który (per testom 2026-05-29) jest sessionless i 200 OK direct. _EVENT_REPORTING2_RE = re.compile( r"event_reporting2\s*:\s*'(https?://[^']+/get_file/[^']+\.mp4/?[^']*)'", re.IGNORECASE, ) _QUALITY_RE = re.compile(r"video_url_text\s*:\s*'([^']*)'", re.IGNORECASE) def extract(page_url: str, *, timeout: float = 60.0) -> list[StreamSource] | None: if "/embed/" not in page_url: # Detail page → derive embed URL via /video/// → /embed/. m = re.search(r"/video/(\d+)/", page_url) if m: embed_url = f"{_BASE}/embed/{m.group(1)}" else: log.info("yespornvip: cannot derive embed from %s", page_url) return None else: embed_url = page_url html = fetch_tube_html(embed_url, timeout=timeout) m = _EVENT_REPORTING2_RE.search(html) if not m: log.info("yespornvip: no event_reporting2 in flashvars on %s", embed_url) return None url = m.group(1) quality = None q_match = _QUALITY_RE.search(html) if q_match: quality = q_match.group(1).strip() or None return [ StreamSource( link=url, type="mp4", quality=quality, referer=_BASE + "/", raw={"mobile_direct_ok": True}, ) ]