From 7afb332fc8a1f812f9b8c8bb376a723eb7d7009a Mon Sep 17 00:00:00 2001 From: goon-foss Date: Sun, 26 Jul 2026 16:34:24 +0200 Subject: [PATCH] fix(playback+ingest): realny proxy fallback gdy CDN nieosiagalny + porntrex duration 1) eporner/phone-resolve: gdy strona parsuje sie OK, ale CDN jest nieosiagalny z sieci usera (audit: siec zglaszajacego nulluje vid-*.eporner.com -> 0.0.0.0, a www.eporner.com dziala), phone re-resolve zwracal TEN SAM URL, a lancuch fallback nie ratowal: dla phone-resolved linkow fallbackProxyUrl === url (resolver ustawia stream_url = direct_url), wiec krok proxy byl no-opem i szlo prosto do WebView = strona hostera z reklamami ('zaladowala sie reklama zamiast wideo'). Teraz po nieudanym phone-resolve bierzemy PRAWDZIWE proxy z backendu (VPS pobiera swoim DNS-em). Tylko na sciezce bledu. Eporner globalnie zdrowy (89-100%, ~100 urzadzen dziennie), wiec to fix dla userow z blokowanym CDN, nie regresja globalna. 2) porntrex zmienil markup kafelka: class="duration">MM:SS< ->
MM:SS
. Stary wzorzec przestal matchowac -> duration_sec=NULL dla ~95% swiezych scen (6479/6815 w 7 dni), a mobile domyslnie filtruje min_duration_sec=60, wiec te sceny byly NIEWIDOCZNE ('nie widze nowych scen z porntrex'). Wzorzec obsluguje oba warianty + H:MM:SS. Zweryfikowane na zywym listingu: 84/85 kafelkow, 20:45 -> 1245s. --- .../direct_scrapers/porntrex_browse.py | 10 +++++++++- mobile/src/changelog.ts | 8 ++++++++ mobile/src/screens/PlayerScreen.tsx | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/connectors/direct_scrapers/porntrex_browse.py b/app/connectors/direct_scrapers/porntrex_browse.py index 9da409a..ae39f19 100644 --- a/app/connectors/direct_scrapers/porntrex_browse.py +++ b/app/connectors/direct_scrapers/porntrex_browse.py @@ -32,7 +32,15 @@ _A_RE = re.compile( ) _ALT_RE = re.compile(r'alt="([^"]*)"') _THUMB_RE = re.compile(r'data-src="(//[^"]+\.(?:jpg|jpeg|webp|png)[^"]*)"', re.IGNORECASE) -_DUR_RE = re.compile(r'class="duration">\s*([\d]{1,2}(?:\s*:\s*[\d]{2}){1,2})\s*<') +# porntrex zmienił markup kafelka (audit 2026-07-26): `class="duration">MM:SS<` → +# `
MM:SS
`. Stary wzorzec +# przestał matchować → duration_sec=NULL dla ~95% świeżych scen, a mobile domyślnie +# filtruje `min_duration_sec=60`, więc te sceny BYŁY NIEWIDOCZNE w apce (6479 scen w +# 7 dni; user: "nie widzę nowych scen z porntrex"). Wzorzec obsługuje oba warianty: +# liczbę mnogą, opcjonalną ikonę przed wartością i H:MM:SS. +_DUR_RE = re.compile( + r'class="durations?"[^>]*>(?:\s*]*>\s*)?\s*([\d]{1,2}(?:\s*:\s*[\d]{2}){1,2})' +) def _parse_duration(text: str | None) -> int | None: diff --git a/mobile/src/changelog.ts b/mobile/src/changelog.ts index 85b88fa..b63fd19 100644 --- a/mobile/src/changelog.ts +++ b/mobile/src/changelog.ts @@ -16,6 +16,14 @@ export type ChangelogEntry = { }; export const CHANGELOG: ChangelogEntry[] = [ + { + id: '2026-07-26', + date: 'July 2026', + items: [ + 'If your network or DNS blocks a site\'s video servers (some providers do), the app now falls back to streaming through the server instead of dropping you on the site\'s page full of ads.', + 'porntrex: new videos show up again. Their site changed, so we were saving new scenes without a length, and the "minimum length" filter was hiding them.', + ], + }, { id: '2026-07-22b', date: 'July 2026', diff --git a/mobile/src/screens/PlayerScreen.tsx b/mobile/src/screens/PlayerScreen.tsx index 12ffb82..08793b9 100644 --- a/mobile/src/screens/PlayerScreen.tsx +++ b/mobile/src/screens/PlayerScreen.tsx @@ -316,6 +316,25 @@ function NativeVideoPlayer({ params }: { params: RouteParams }) { player.play(); return; // sukces → status zmieni się z 'error', łańcuch fallback nie ruszy } + // Phone-resolve zadziałał, ale dał TEN SAM URL — czyli strona parsuje się dobrze, + // a pada samo pobranie z CDN. Typowo: DNS/ISP usera blokuje hosta CDN (audit + // 2026-07-26: sieć zgłaszającego nulluje `vid-*.eporner.com` → 0.0.0.0, podczas gdy + // `www.eporner.com` działa). Wtedy łańcuch fallback NIE ratuje: dla phone-resolved + // linków `fallbackProxyUrl === url` (resolver ustawia stream_url = direct_url), więc + // krok proxy jest no-opem i lecimy prosto do WebView = strona hostera z reklamami + // ("załadowała się reklama zamiast wideo"). Bierzemy więc PRAWDZIWE proxy z backendu + // (VPS pobiera swoim DNS-em i streamuje do nas). Tylko na ścieżce błędu. + if (!cancelled && !!resolvePageUrl && sceneId && params.playbackId) { + const res = await client.resolvePlayback(sceneId, params.playbackId); + const viaProxy = (res.links || []) + .map((l) => l.stream_url) + .find((u): u is string => !!u && u !== url); + if (!cancelled && viaProxy) { + player.replace(viaProxy); + player.play(); + return; + } + } } catch { // ignore → łańcuch fallback przejmie (proxy/embed/error) } finally {