"""naughtymachinima.com — jawne `` bez tokenu. Dodany 2026-08-13. Najprostszy playback z całego wertykału animacji. Trzy rendycje wprost w HTML, bez AJAX-a, bez tokenu, bez Cloudflare: Kontrast z [[rule34video]] (drugie źródło 3D): tam też był KVS z gotowymi URL-ami, ale `v-acctoken` był ZWIĄZANY Z IP i telefon musiał resolwować sam. Tutaj URL nie ma żadnego tokenu, więc nie ma czego wiązać. Zweryfikowane z VPS-a: 206 na Range, `ftypisom` w pierwszym KB (faststart), 140 MB, działa BEZ Referera. Stąd `mobile_direct_ok`. **Dwie pułapki, obie odsiewane jawnie:** 1. **Pusty ``** na końcu listy (placeholder playera). Bez sprawdzenia pustego src trafiłby na listę jako link do niczego. 2. **`/images/preroll/NMintro.mp4`** to intro serwisu, nie treść. Leży w tym samym HTML i pasuje do naiwnego `\\.mp4`, a jako jedyny mp4 na `www.` zamiast `videos.`. """ 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://www.naughtymachinima.com" #: Tylko host plików, co samo w sobie odcina preroll z `www.naughtymachinima.com`. _SOURCE_RE = re.compile( r"]+src=[\"'](https?://videos\.naughtymachinima\.com/[^\"']+\.mp4)[\"'][^>]*?" r"label=[\"']([^\"']{1,10})[\"']", re.IGNORECASE, ) _QUALITY_RANK = {"1080p": 0, "720p": 1, "480p": 2, "360p": 3} def extract(page_url: str, *, timeout: float = 60.0) -> list[StreamSource] | None: html_text = fetch_tube_html(page_url, timeout=timeout) out: list[StreamSource] = [] seen: set[str] = set() for link, label in _SOURCE_RE.findall(html_text): if not link or link in seen or "/preroll/" in link: continue seen.add(link) out.append( StreamSource( link=link, type="mp4", quality=label.strip() or None, referer=_BASE + "/", # Zweryfikowane: 206 bez Referera, bez tokenu, faststart. raw={"mobile_direct_ok": True}, ) ) if not out: log.info("naughtymachinima: brak mp4 na %s", page_url) return None out.sort(key=lambda s: _QUALITY_RANK.get((s.quality or "").lower(), 99)) return out