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>
76 lines
2.7 KiB
Python
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},
|
|
)
|
|
]
|