"""pornbusy.com — dispatch po hosterze z `itemprop="embedURL"`. Katalog jest rozproszony po hosterach (próbka 120 scen): ~41% loadvid, ~20% rodzina seekplayer (av.ezplayer.me / av.seeks.cloud / 4k.upn.one / 4k.player4me.vip — objęte poszerzonym `_HOST_RE` silnika), ~8% zpi.cx, ~12% upload18 (token z wbitym `i=/24` = IP-bound), reszta ogon. Obsługujemy trzy pierwsze (~69% katalogu): - loadvid → manifest przez POST, marker `manifest_producer` (patrz hosters/loadvid.py) - seekplayer → istniejący silnik (ten sam AES key/IV) - zpi.cx → `embedURL` JEST plikiem wideo (mimo `.webm` w nazwie to mp4); zweryfikowane: Range 206 `video/mp4`, bez Referera, bez tokena upload18 i ogon zwracamy jako None — resolve na VPS wymusiłby proxowanie CAŁEGO wideo (token IP-bound), co łamie zasadę no-video-proxy. """ from __future__ import annotations import logging import re from urllib.parse import urlparse from app.extractors._fetch import fetch_tube_html from app.extractors._models import StreamSource from app.extractors.hosters import loadvid, seekplayer_engine log = logging.getLogger(__name__) _BASE = "https://pornbusy.com" _EMBED_RE = re.compile(r'itemprop="embedURL"\s+content="([^"]+)"', re.IGNORECASE) _IFRAME_RE = re.compile(r']+src="([^"]+)"', re.IGNORECASE) _ZPI_HOST_RE = re.compile(r"^(?:[a-z0-9]+\.)?zpi\.cx$", re.IGNORECASE) def extract(page_url: str, *, timeout: float = 60.0) -> list[StreamSource] | None: html_text = fetch_tube_html(page_url, timeout=timeout) m = _EMBED_RE.search(html_text) or _IFRAME_RE.search(html_text) if not m: log.info("pornbusy: no embedURL/iframe on %s", page_url) return None embed = m.group(1).strip() if embed.startswith("//"): embed = "https:" + embed if loadvid.matches(embed): return loadvid.extract(embed, timeout=timeout) if seekplayer_engine.matches(embed): sources = seekplayer_engine.extract(embed, timeout=timeout) if not sources: return None player_origin = f"https://{urlparse(embed).hostname}/" out: list[StreamSource] = [] for s in sources: raw = dict(s.raw or {}) raw["proxy_no_verify"] = True out.append( StreamSource( link=s.link, type=s.type or "m3u8", quality=s.quality, # Referer = origin PLAYERA, nie strony (jak przy galaxyporn: # z Refererem strony CDN zwraca 403). referer=s.referer or player_origin, raw=raw, ) ) return out host = (urlparse(embed).hostname or "").lower() if _ZPI_HOST_RE.match(host): # embedURL to bezpośrednio plik (rozszerzenie `.webm` myli — to mp4). return [ StreamSource( link=embed, type="mp4", raw={"mobile_direct_ok": True}, ) ] log.info("pornbusy: unsupported hoster %s (%s)", host, page_url) return None