goon/app/extractors/tubes/porndish.py
goon-foss d521e6379d fix: porndish gral cudze filmy, zwiastuny i zastepcze filmy jako scena, reklama fpoxxx
porndish: cache serwisu oddawal dla kazdego adresu ten sam wpis, wiec ~40 tys.
scen gralo jeden z dwoch filmow. Strona z ?nc=<godzina> omija cache, kanoniczny
adres musi miec ten sam slug, inaczej 502.
sxyland: zwiastuny z kafelkow "podobne" (data-trailer) byly brane za film;
skasowany plik nowplay podstawial wspolny zastepczy film, teraz HosterDead.
fpoxxx: strona skasowanego filmu (no-player) to HosterDead, nie strona z
reklama w WebView.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 12:21:22 +02:00

52 lines
2.1 KiB
Python

"""porndish.com: strona sceny z obejsciem zepsutego cache serwisu, potem embed-iframe.
Zgloszenie 88085cda (2026-10-12, "nic z porndish nie dziala"): cache strony porndish
(`x-cache-handler: autoptimize-pro-cache`, `cf-cache-status: HIT`) oddaje dla kazdego
`/porn/<slug>/` CUDZY wpis. Nowsze adresy dostawaly "[DadCrush] Carly Kiss", starsze
"[MyLifeInMiami] ...", wiec kazda z ~40 tys. scen porndish grala jeden z dwoch tych samych
filmow. Telemetria liczyla to jako sukces (wideo ruszalo, tylko nie to).
Dowolny parametr w zapytaniu omija cache (`BYPASS`), wiec dokladamy `?nc=<godzina>`
(jeden wariant na godzine, zeby nie mnozyc wpisow w ich cache). Do tego kontrola: kanoniczny
adres strony musi miec ten sam slug co zadany, inaczej nie oddajemy niczego (502), bo
cudzy film jest gorszy niz brak filmu.
"""
from __future__ import annotations
import logging
import re
import time
from urllib.parse import urlsplit
from app.extractors._fetch import fetch_tube_html
from app.extractors._models import StreamSource, TubePageError
from app.extractors.tubes import _embed_iframe
log = logging.getLogger(__name__)
_CANONICAL_RE = re.compile(
r"""<link[^>]+rel=["']canonical["'][^>]+href=["']([^"']+)["']"""
r"""|<meta[^>]+property=["']og:url["'][^>]+content=["']([^"']+)["']""",
re.IGNORECASE,
)
def _slug(url: str) -> str:
return urlsplit(url).path.rstrip("/").rsplit("/", 1)[-1].lower()
def extract(page_url: str, *, timeout: float = 60.0) -> list[StreamSource] | None:
sep = "&" if "?" in page_url else "?"
busted = f"{page_url}{sep}nc={int(time.time() // 3600)}"
html = fetch_tube_html(busted, timeout=timeout)
want = _slug(page_url)
m = _CANONICAL_RE.search(html)
got = _slug(m.group(1) or m.group(2)) if m else ""
if want and got and got != want:
log.warning("porndish: %s oddal cudzy wpis (%s)", page_url, got)
raise TubePageError(502, page_url)
# Adres z `nc` takze dla zapasu "cala strona w WebView": bez niego telefon tez dostalby
# cudzy wpis z cache.
return _embed_iframe.extract(busted, timeout=timeout, page_html=html)