goon/app/extractors/tubes/yespornvip.py
jtrzupek 172642d55c fix(extractor/yespornvip): use event_reporting2 URL (server 1) — server 7 needs session cookies
Verify 2026-05-29: extractor zwracal video_url server `/get_file/7/...?embed=true`
ktore 404-uje na direct fetch nawet ze swiezym tokenem - URL wymaga PHPSESSID
z embed page session (cookies jar mobile-side nie matchuje VPS-side ekstraktora).

Switch na `event_reporting2` ktore wskazuje na `/get_file/1/...` - standalone
time-bound signed URL, 200 OK direct fetch z UA+Referer. Quality label
zachowany z `video_url_text`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 09:48:12 +02:00

76 lines
2.7 KiB
Python

"""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/<id>` w iframe. Embed page renderuje KVS
player z `flashvars`:
- `video_url: 'function/0/https://yesporn.vip/get_file/7/<token>/.../<id>.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/<token>/.../<id>.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/.../<id>.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/<id>/<slug>/ → /embed/<id>.
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},
)
]