fix(movies): rozwiazuj przekierowanie hostera na serwerze, zanim embed trafi do WebView

Zgloszenia 3b75cb54/11d7b17b/d3af0813: "Myvidplay nie dziala", czarny ekran.

Mechanizm to powtorka z galaxyporn (vikingfile -> vik1ngfile), tylko w drugiej galezi,
ktorej wtedy nie sprawdzilem: myvidplay.com i doply.net odpowiadaja 30x na playmogo.com,
a WebView w apce blokuje top-frame skok na inna domene (ochrona przed popunderami).
Telefon dostawal surowy adres myvidplay, przekierowanie bylo blokowane i zostawala czern.
Lekcja "sprawdz te sama pulapke w pozostalych galeziach" byla zapisana w pamieci po
galaxyporn; ta galaz wlasnie ja potwierdzila.

`resolve_movie_playback` rozwiazuje teraz przekierowanie po stronie serwera i UTRWALA
koncowy adres w `embed_url`, wiec kazdy adres kosztuje jeden fetch raz w zyciu, a po
utrwaleniu regex przestaje pasowac i krok jest darmowy. Fetch odpala sie WYLACZNIE dla
rodziny DoodStream (znanej ze zmiany szyldu co pare miesiecy); zwykle embedy ida bez
dotykania sieci. Blad hostera (5xx) nie jest utrwalany, zeby nie zabetonowac chwilowej
awarii jako nowego adresu.

Easyvidplayer z tych samych zgloszen NIE wymagal zmian: zrodla juz sa oznaczone
martwymi przez niedzielny mechanizm HosterDead, czyli samoleczenie dziala.

Zweryfikowane na wszystkich trzech zgloszonych filmach: resolve oddaje
https://playmogo.com/e/..., baza utrwalona, telefon rozpoznaje playmogo natywnie
(DOOD_HOSTS), a strona playmogo z tymi sciezkami byla sprawdzona 2026-08-24 (200,
markery Turnstile). Deploy backendu, bez OTA.
This commit is contained in:
goon-foss 2026-08-26 14:00:56 +02:00
parent 2c92fab2a9
commit 360af9fabc

View file

@ -65,6 +65,38 @@ _TIME_BOUND_CDN_RE = re.compile(
re.IGNORECASE, re.IGNORECASE,
) )
# Hostery znane z przekierowywania całej domeny na następcę (rodzina DoodStream
# zmienia szyld co kilka miesięcy). TYLKO dla nich rozwiązujemy przekierowanie przed
# oddaniem embedu, bo to kosztuje jeden fetch; zwykłe embedy idą bez dotykania sieci.
_REDIRECTING_EMBED_RE = re.compile(
r"//(?:[a-z0-9-]+\.)?(?:myvidplay|doply|doodstream|dood|d0+d|dooood|do0od|do7go"
r"|ds2play)\.[a-z]{2,6}/",
re.IGNORECASE,
)
def _resolve_embed_redirect(url: str) -> str:
"""Zwraca końcowy adres po przekierowaniach albo oryginał, gdy nic się nie zmienia.
Wynik trafia do `embed_url` w bazie, więc każdy adres jest rozwiązywany najwyżej
raz; po utrwaleniu regex przestaje pasować i ta funkcja robi się darmowa.
"""
if not _REDIRECTING_EMBED_RE.search(url):
return url
from app.extractors import browser_get
try:
res = browser_get(url, timeout=15.0, follow_redirects=True)
final = str(getattr(res, "url", "") or "")
# Utrwalamy tylko realny skok na inny adres http(s); błąd hostera (5xx itp.)
# zostawia oryginał, żeby nie zabetonować chwilowej awarii jako "nowego" adresu.
if final.startswith("http") and final != url and res.status_code < 400:
return final
except Exception as e:
log.info("embed redirect resolve padl dla %s: %s", url, e)
return url
# IP-BOUND CDN signature, token bind do requester IP, cross-IP fetch = 403. # IP-BOUND CDN signature, token bind do requester IP, cross-IP fetch = 403.
# Wymaga mobile WebView fallback (mobile extract z phone session, nie VPS). # Wymaga mobile WebView fallback (mobile extract z phone session, nie VPS).
# Shared KVS infrastructure across multiple hosters (luluvid movies, mypornerleak, # Shared KVS infrastructure across multiple hosters (luluvid movies, mypornerleak,
@ -248,6 +280,21 @@ def resolve_movie_playback(
) )
# Zawsze dorzucamy embed jako fallback, mobile WebView może wyłapać URL z JS-a # Zawsze dorzucamy embed jako fallback, mobile WebView może wyłapać URL z JS-a
if pb.embed_url: if pb.embed_url:
# Hoster potrafi zostać atrapą przekierowującą na następcę (myvidplay i
# doply odpowiadają 30x na playmogo). WebView w apce blokuje top-frame
# skok na inną domenę (ochrona przed popunderami), więc surowy adres
# kończy się czarnym ekranem: zgłoszenia 3b75cb54/11d7b17b/d3af0813,
# wcześniej identyczny mechanizm w galaxyporn (vikingfile → vik1ngfile).
# Rozwiązujemy przekierowanie TUTAJ i utrwalamy wynik, żeby telefon
# dostał adres, na którym wolno mu zostać.
final_embed = _resolve_embed_redirect(pb.embed_url)
if final_embed != pb.embed_url:
log.info(
"movie playback %s: embed %s przekierowuje na %s, utrwalam",
pb.id, pb.embed_url, final_embed,
)
pb.embed_url = final_embed[:2048]
session.commit()
links.append( links.append(
StreamLink( StreamLink(
stream_url=None, stream_url=None,