From dde21f2e6e3774789ae61afd1dac5ad8058daec6 Mon Sep 17 00:00:00 2001 From: goon-foss Date: Thu, 13 Aug 2026 15:34:40 +0200 Subject: [PATCH] fix(thumbs): degraduj chwiejne hosty miniaturek zamiast zerowac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zgloszenie "Jakis problem z miniaturkami z fullporner" (36c33200). fullporner NIE jest winowajca: pomiar 2026-08-13 dal 40/40 poprawnych JPEG-ow i 0 z 68 414 zrodel bez URL-a. Winna byla KOLEJNOSC WYBORU. Miniaturke wygrywal pierwszy origin alfabetycznie, a `tube:fullmoviesxxx` sortuje sie PRZED `tube:fullporner`, wiec chwiejny host przykrywal zdrowy. Pomiar (20-25 losowych URL-i na host): img.fullmovies.xxx 12/20 ok (5x ReadTimeout, 3x 502) 54 019 zrodel img.hdporn.gg 16/20 ok (3x 502, 1x ReadTimeout) 54 267 zrodel imgs.xiaoshenke.net 20/20 ok (fullporner) 68 406 zrodel freshporno.org 20/20 ok Nowy predykat `_is_flaky_thumb`: degraduje do tieru fallback w LISCIE, ale w odroznieniu od `_is_rotting_thumb` NIE zeruje w SceneDetail. Zerowanie powtorzyloby wpadke z sierpnia, gdzie sceny majace tylko fullporner tracily obrazek calkowicie. Dwie iteracje, obie z pomiaru, nie z zalozenia: 1. Degradacja samego fullmovies przesunela wybor na hdporn (44 z 60), czyli PRZENIOSLA problem. Stad hdporn dopisany. 2. Po zdegradowaniu obu fullmovies WROCIL (38 z 60): sceny majace tylko te dwa hosty laduja w fallbacku, a `setdefault` bral pierwszy alfabetycznie, czyli gorszy z dwoch. Stad `_FLAKY_RANK` — w obrebie fallbacku wybieramy mniejsze zlo. Po zmianie w dwoch niezaleznych losowaniach fullmovies nie wygrywa nigdzie, a sceny majace WYLACZNIE chwiejne hosty dostaja hdporn (40/40, zero bez miniatury), wiec nic nie traci obrazka. --- app/api/scenes.py | 54 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/app/api/scenes.py b/app/api/scenes.py index ec46e5b..5bfb892 100644 --- a/app/api/scenes.py +++ b/app/api/scenes.py @@ -712,6 +712,49 @@ def _is_rotting_thumb(url: str) -> bool: return "fastpic.org" in url +def _is_flaky_thumb(url: str) -> bool: + """Host, który działa BYWA, ale zbyt często pada, żeby wygrywać wybór miniaturki. + + W odróżnieniu od `_is_rotting_thumb` NIE zerujemy takiej miniatury w SceneDetail: + to nie jest martwy URL, tylko niepewny. Zerowanie powtórzyłoby wpadkę z fullpornerem + z sierpnia 2026, gdzie sceny mające tylko to źródło traciły obrazek całkowicie. + + Problem był w kolejności wyboru: miniaturkę wygrywał pierwszy origin alfabetycznie, + a `tube:fullmoviesxxx` sortuje się PRZED `tube:fullporner`, więc chwiejny host + przykrywał zdrowy. 51 799 z 52 758 takich scen (98%) ma alternatywę, więc degradacja + niemal zawsze ma czym zastąpić. + + Pomiar 2026-08-13, po 20-25 losowych URL-ach na host: + + img.fullmovies.xxx 12/20 ok (5× ReadTimeout, 3× 502) 54 019 źródeł + img.hdporn.gg 16/20 ok (3× 502, 1× ReadTimeout) 54 267 źródeł + imgs.xiaoshenke.net 20/20 ok (fullporner) 68 406 źródeł + freshporno.org 20/20 ok + + `img.hdporn.gg` dopisany po sprawdzeniu efektu pierwszej wersji: degradacja samego + fullmovies przesunęła wybór na hdporn (44 z 60 scen), czyli przeniosłaby problem + zamiast go rozwiązać. Po dopisaniu obu wygrywają hosty ze 100% skutecznością. + """ + return "img.fullmovies.xxx" in url or "img.hdporn.gg" in url + + +#: Im niżej, tym gorzej. Używane TYLKO wewnątrz tieru fallback, czyli gdy scena nie ma +#: żadnej zdrowej miniatury i trzeba wybrać mniejsze zło. Bez tego decydowała kolejność +#: alfabetyczna originu, przez co scena mająca fullmovies + hdporn dostawała fullmovies, +#: czyli host o 40% awaryjności zamiast tego o 20%. +_FLAKY_RANK = ( + ("img.hdporn.gg", 1), # 16/20 ok + ("img.fullmovies.xxx", 2), # 12/20 ok +) + + +def _flaky_rank(url: str) -> int: + for host, rank in _FLAKY_RANK: + if host in url: + return rank + return 0 # nie-chwiejny (martwy rotting-thumb) — bez preferencji + + def _needs_proxy(url: str) -> bool: """Wszystkie thumbnaile z playback_sources są proxowane przez backend. Większość CDN-ów porn-tube'ów wymaga Refera (hqporner, mypornerleak/58img, @@ -847,8 +890,15 @@ def _build_scenes_out_batch( # Też tier fallback: statyczna miniatura z innego źródła jest tańsza. thumb_fallback.setdefault(sid, (yp, page_url)) elif thumb: - if _is_rotting_thumb(thumb): - thumb_fallback.setdefault(sid, (thumb, page_url)) + if _is_rotting_thumb(thumb) or _is_flaky_thumb(thumb): + # Martwe ORAZ chwiejne lądują w tierze fallback: użyte tylko wtedy, + # gdy scena nie ma stabilniejszej miniatury z innego źródła. W obrębie + # samego fallbacku wybieramy mniejsze zło wg `_FLAKY_RANK`, bo inaczej + # decydowałaby kolejność alfabetyczna originu i scena z fullmovies + + # hdporn dostawała gorszy z dwóch (pomiar: 38 z 60 takich scen). + prev = thumb_fallback.get(sid) + if prev is None or _flaky_rank(thumb) < _flaky_rank(prev[0]): + thumb_fallback[sid] = (thumb, page_url) elif sid not in thumb_by_scene: thumb_by_scene[sid] = (thumb, page_url) if sid not in anim_by_scene and anim: