Commit graph

209 commits

Author SHA1 Message Date
goon-foss
bdac60f022 feat(mobile): Chromecast (0.3.0, runtime 1.3)
Zgloszenie de93ba42 ("Can't stream to Chrome cast"). Cast to natywny SDK, wiec NIE da
sie go wyslac przez OTA: to nowe APK, ktore ludzie musza pobrac sami. Klucz podpisujacy
ten sam, wiec ALLOWED_APP_SIG_HASH bez zmian i aktualizacja wchodzi na wierzch starej.

Argument, ktory przewazyl: od czerwca release ma wlaczone FLAG_SECURE, wiec zwykle
mirrorowanie ekranu na telewizor jest zablokowane. Cast jest jedyna droga na duzy ekran.

Zasieg: 77% udanych odtworzen konczy sie bezposrednim adresem, plus czesc hosterow
filmowych oddajacych gotowy plik. Okolo 13% (porndoe, mypornerleak, superporn) idzie
przez WebView i castowac sie NIE DA, tam przycisku nie ma.

Wpiete recznie, bez `expo prebuild`, bo katalog android/ jest w repo i ma reczne zmiany,
ktore prebuild by przepisal. Cztery edycje, dokladnie to co robi config plugin:
manifest (OPTIONS_PROVIDER + expanded controller), MainActivity, castFrameworkVersion
w rootProject.ext oraz JAWNA zaleznosc play-services-cast-framework w app/build.gradle.
Ta ostatnia jest konieczna, bo biblioteka deklaruje ja jako `implementation`, co nie
jest przechodnie na sciezke kompilacji, i bez niej build pada na compileReleaseKotlin.

Identyfikator odbiornika CELOWO zaden: bez wpisu biblioteka bierze domyslny odbiornik
Google. Rejestracja wlasnego wiazalaby konto Google z Goonem, a przy tresci dla
doroslych latwo o cofniecie.

Urzadzenia bez Google Play Services zabezpieczone w DWOCH miejscach, bo mamy uzytkownika
na LineageOS (GOON-3B) i sideload na zegarku (GOON-51): `getSharedInstance` w try/catch
po stronie natywnej, a po stronie JS cala obsluga w osobnym `CastControl`, montowanym
dopiero gdy `useCastAvailable` potwierdzi Play Services. To nie jest ostroznosc na
wyrost: hooki biblioteki synchronicznie subskrybuja natywne zdarzenia i bez GMS wywracaja
ekran, a hooka nie da sie wywolac warunkowo.

Chromecast pobiera plik SAM i nie wysyla naszych naglowkow, wiec zrodla wymagajace
Referera ida przez /proxy (dokłada go po stronie serwera), a reszta bezposrednio, zeby
nie obciazac VPS. Do tego proxy przestaje przekazywac CORS hostera: mixdrop oddawal
`Access-Control-Allow-Origin: https://mixdrop.my`, co odbiornik odrzucal przy HLS.

Przy okazji GOON-3B: doszedl brakujacy wpis `com.google.android.gms.version`, ktory
wywracal apke na LineageOS, gdy Chromium probowal podpiac skaner kodow.

Zweryfikowane na emulatorze na podpisanym APK: certyfikat identyczny ze starym
(3294aba5...), instalacja NA WIERZCH 0.2.2 udana, wersja 13/0.3.0, runtime 1.3 w
manifescie, aplikacja wstaje bez crasha, ExoPlayer gra (MediaCodec dla video), a SDK
Casta startuje poprawnie: dynamite sie laduje i `MediaRouterProxy` czyta NASZ CastOptions.
Logika wyboru adresu przetestowana osobno na osmiu przypadkach.

CZEGO NIE ZWERYFIKOWALEM: realnego rzutu na telewizor. W sieci emulatora nie ma zadnego
Chromecasta, wiec `loadMedia` i odtwarzanie po stronie odbiornika sa niesprawdzone.

Build wymaga SENTRY_DISABLE_AUTO_UPLOAD=true, bo sentry.properties czeka na
SENTRY_ORG/SENTRY_PROJECT/SENTRY_AUTH_TOKEN ze srodowiska (Infisical, workspace
goon-app). Skutek: slady JS z 0.3.0 beda w Sentry nieczytelne do czasu przebudowy z tymi
zmiennymi.
2026-08-24 14:27:41 +02:00
goon-foss
b7a8911441 fix(sxyprn): koniec z przypisywaniem scen po samym imieniu
Zgloszenie e28f2517: scena "Bridgette B, Gigi Rivera, Julia Ann, Phoenix Marie, ..."
miala przypisana Julie B., ktorej w tytule nie ma.

Mechanizm: scraper wola strone performera i sprawdza, czy scena naprawde go dotyczy,
porownujac czlony nazwiska z tytulem. Robil to jednak KAZDY Z OSOBNA i tylko od trzech
znakow. Dla "Julia B." czlon "b." odpadal na dlugosci, zostawalo samo "julia", i
przypisanie lapalo kazda scene z tym imieniem w tytule. Stad tez "Chloe S" przy
"Chloe Kreams", "Sharon D" przy "Sharon White", "May E" przy "Danielle Maye".

Nowa regula (`person_named_in` w `app/normalize/text.py`): czlony musza stac OBOK
SIEBIE i w tej samej kolejnosci. Od trzech znakow wystarczy zgodnosc przedrostka, zeby
przezyly warianty zapisu ("Savanna Bond" przy tytule "Savannah Bond", "Jyn Maze" przy
"Jynx Maze"). Inicjaly musza zgadzac sie dokladnie. Tytul tniemy wczesniej na segmenty
po przecinkach i myslnikach, bo bez tego smieciowy performer "Rope Bondage" dopasowywal
sie do doklejonego ogona tagow "- rope - bondage".

Swiadomy koszt: odwrocona kolejnosc ("Goldy Kim" wobec "Kim Gold") nie przejdzie, a
performer z inicjalem zamiast nazwiska nie dostanie ze sxyprn nic. Przy wyborze miedzy
pominieciem sceny a przypisaniem jej niewlasciwej osoby wolimy pominac, bo to bledne
przypisanie widac na ekranie performera i to ono jest zglaszane.

Smoke test po zmianie: Lana Rhoades, Julia Ann, Angela White i Abella Danger dalej po
30 scen ze strony performera, wiec scraper sie nie zamrozil (to sie juz raz zdarzilo
przy zbyt ostrym filtrze). "Julia B." oddaje teraz zero zamiast cudzych scen.

Dolozony `scripts/sxyprn_fix_overattribution.py`, ktory stosuje te sama regule wstecz.
Uruchomiony na produkcji: skasowane 85 379 z 239 686 przypisan (35,6%). Ruszamy tylko
sceny majace WYLACZNIE zrodlo sxyprn i tylko przypisania od scrapera; kanon
(tpdb/stashdb) nietkniety. Regula sprawdzona recznie na dwoch probkach po ~20 pozycji,
wszystkie kasowane byly faktycznie bledne.

Skutek uboczny: scen bez zadnego performera przybylo z 3 622 do 23 891. To sceny,
ktorych jedyne przypisanie bylo bledne, wiec brak jest uczciwszy niz cudze nazwisko.
2026-08-24 13:49:31 +02:00
goon-foss
5a48175a85 fix(movies): przestan podsuwac hostery z rodziny seekplayer, ktore nie maja plikow
Zgloszenia z 2026-08-24: "Easyvidplayer nie chce odpalic" (ccbc75da), "Embedseek tez
nie rusza" (d59fc396) i sasiednie. To NIE byl nasz blad parsowania.

Co ustalone: `/api/v1/video` odpowiada 200 i poprawnie sie odszyfrowuje, tylko nie ma
w odpowiedzi pola `source`. W ich wlasnym bundlu warunek jest doslownie taki sam i
konczy sie komunikatem "Video is not ready yet". Potwierdzone w przegladarce z lacza
domowego (plakat obok oddal 502), z VPS i przez brytyjskie proxy, wiec to nie blokada
po IP ani po kraju. Protokol sie nie zmienil, hoster po prostu nie ma juz plikow.

Skala na 250 losowych zrodlach: 3 zywe, 88 razy HTTP 404, 79 razy brak `source`.
Czyli okolo 2% jeszcze gra.

Dwie zmiany:
* `seekplayer_engine.extract` rzuca `HosterDead` zamiast zwracac None. Dopiero wtedy
  `resolve_movie_playback` oznacza zrodlo martwe. Zwracanie None dawalo WebView z tym
  samym komunikatem, w kolko, i wlasnie to zglaszali uzytkownicy. Katalog czysci sie
  teraz sam, w miare jak ludzie po nim chodza.
* De-ranking calej rodziny w `_movie_origin_priority`, zeby na wierzch wychodzily
  hostery, ktore graja. Nie usuwamy ich z listy, bo te 2% bywa jedynym zrodlem.

Bezpieczne: filmow zaleznych WYLACZNIE od tej rodziny jest w bazie jeden, pozostale
26 223 maja alternatywe.

Dolozony `scripts/seekplayer_reap.py` do sprzatania calosci na zadanie. NIE odpalam go
w tle: przy limitach hostera (32% odpowiedzi to 429) pelny przemial to kilkadziesiat
godzin ciaglego pukania, co grozi zablokowaniem naszego IP dla prawdziwych resolve.

Zweryfikowane na filmie ze zgloszenia: piec zrodel seekplayer oznaczonych martwymi,
zostaly mixdrop (206 video/mp4) i voe (200 m3u8), oba sprawdzone spoza serwerowni.
2026-08-24 13:39:40 +02:00
goon-foss
9fe6d5c1ed fix(galaxyporn): lap tez nowa pisownie domeny vikingfile
Regex w backendzie dopasowywal wylacznie vikingfile.com, mimo ze serwis rotuje
domena. Poszerzony na vik[i1]ngfile z dowolna koncowka. W aplikacji ten sam wzorzec
byl juz poszerzony, backend zostal w tyle.

Na 20 losowych scenach: 16 oddaje vik1ngfile.site, 4 nie maja zadnego zrodla (stary
player padl, a linku do vikingfile na stronie nie ma wcale). Te 4 to uczciwe 503, nie
awaria po naszej stronie.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 21:10:40 +02:00
goon-foss
612558c880 fix(galaxyporn): rozwiazuj przekierowanie TAKZE w galezi z iframem
Wczorajsza poprawka objela tylko galaz zapasowa (link vikingfile w tresci strony), a
nie te, ktora obsluguje nowsze sceny, gdzie vikingfile JEST iframem. Polowa katalogu
dalej dostawala wiec stary adres vikingfile.com, ktory oddaje 302 na inna domene,
WebView to blokowal i zostawal czarny ekran.

Znalezione dopiero, gdy sprawdzilem KONKRETNA scene zglaszana przez uzytkownika
("Stella Cox passes on tennis") zamiast losowej probki: resolve oddawal
vikingfile.com, mimo ze losowe sceny testowane wczesniej oddawaly juz vik1ngfile.site.

Po poprawce na 10 losowych scenach: 9 oddaje vik1ngfile.site, 1 bez zrodla.
Kontrola pliku: 2,93 GB, nazwa zgodna ze scena.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:45:31 +02:00
goon-foss
46e7839fb2 fix(galaxyporn): czarny ekran to zablokowane przekierowanie na druga domene
Trzecia proba i tym razem z dowodem z emulatora, a nie ze zgadywania. vikingfile.com
oddaje 302 na INNA domene (dzis vik1ngfile.site). WebView w aplikacji celowo blokuje
przejscie top-frame na inny eTLD+1, zeby popundery nie przejmowaly ekranu, wiec to
przekierowanie bylo odrzucane i zostawal czarny ekran. Z serwera tego nie widac, bo
httpx sledzi przekierowanie po cichu; widac dopiero w przegladarce na urzadzeniu,
gdzie w pasku adresu stoi vik1ngfile.site.

Poprawki:
- ekstraktor oddaje adres DOCELOWY (rozwiazuje 302 przy kazdym resolve, bo domena
  zapasowa rotuje), wiec aplikacja od razu otwiera wlasciwa domene i zadna zmiana
  domeny w ogole nie zachodzi
- wzorzec hosta we wstrzykiwanym skrypcie obejmuje obie pisownie (vik[i1]ngfile.),
  wczesniej dopasowywal tylko vikingfile.com, wiec po przekierowaniu w ogole sie nie
  uruchamial

Przy okazji z emulatora widac, ze zabezpieczenie to CHECKBOX "Verify you are human",
czyli wymaga kliniecia. Dlatego strona musi byc widoczna i uzywalna, a nie schowana.

Opublikowane OTA na 1.2 i 1.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:03:54 +02:00
goon-foss
95c51f78d2 fix(galaxyporn): stary katalog NIE jest martwy, tylko iframe zwietrzal
Korekta mojej wczorajszej diagnozy. Twierdzilem, ze stary katalog galaxyporn padl po
stronie hostera: player wypisuje "Video is not ready yet", a /api/v1/video oddaje
payload BEZ jakiegokolwiek adresu wideo (75% probki 16 scen). Objawy sie zgadzaly,
wniosek byl zly.

Na TYCH SAMYCH stronach jest link do vikingfile, tylko nie w iframie, lecz w zwyklym
<a href>, wiec go nie widzielismy. Pliki tam zyja: sprawdzone trzy, 890 MB, 742 MB i
2,5 GB, nazwy zgodne ze scenami. Zwietrzaly byl iframe (news.upns.pro,
sport.seekplays.com, galaxy.4meplayer.pro), zostawiony po migracji.

Szukamy wiec vikingfile po calym HTML. Kolejnosc celowa: seekplayer PIERWSZY, bo
resolwuje sie po naszej stronie i gra bez CAPTCHA, vikingfile jako ratunek, ktory
kosztuje usera przejscie Turnstile w WebView. Martwy player potrafi RZUCIC
(HosterDead przy 404), nie tylko oddac pustke, wiec lapiemy tez wyjatek, inaczej
ratunek nigdy sie nie wykonuje.

Na 12 losowych scenach: bylo 0 rozwiazanych, jest 11. ZADNYCH scen nie kasujemy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 12:00:30 +02:00
goon-foss
83a6092d89 fix(pornbusy): probuj generycznego hostera zamiast od razu poddawac
Zgloszenie 3b03a744 ("Pornbusy pisze ze temporary problem with the host"). Wbrew
mojej pierwszej diagnozie to NIE byla awaria rodziny seekplayera: pornbusy w ogole
juz jej nie uzywa. Probka 10 najswiezszych scen (2026-08-21): morencius.com 4,
cdn.loadvid.com 4, playmate.to 1, upload18 1.

Morencius to zwykly JWPlayer z P.A.C.K.E.R.-em i HLS-em, bez Turnstile, wiec radzi
sobie z nim nasz generyczny rozpakowywacz BEZ zadnych zmian (oddaje gotowy
master.m3u8). Zamiast wiec zwracac None dla kazdego nieznanego hostera, najpierw
podajemy embed generycznemu: najgorszy przypadek to None, czyli stan sprzed zmiany.

Bylo 0/5, jest 3/5. Zostaja playmate.to (rozpakowywacz go nie zna) oraz upload18,
ktory pomijamy swiadomie, bo ma token zwiazany z IP.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 11:51:04 +02:00
goon-foss
ae5f2aa7ac fix(extractors): vjav przechodzi wyzwanie 429, galaxyporn oddaje vikingfile telefonowi
Znalezione w nocnym smoke tescie (9 ostrzezen, w tym trzy ekstraktory po 0/3).

vjav: /api/videofile.php oddaje z serwerowni 429 i 343-bajtowa strone, ktora w JS
ustawia JEDNO ciasteczko i sie przeladowuje. Wartosc jest wprost w tej odpowiedzi,
wiec czytamy ja i powtarzamy zapytanie, bez wykonywania JS. Sprawdzone: druga proba
oddaje 200 i poprawny JSON. Bylo 0/3, jest 5/5.

galaxyporn: serwis przenosi NOWE wgrania na vikingfile.com. Probka: 12/12 najnowszych
scen na vikingfile, 12/12 najstarszych dalej na rodzinie seekplayera. Vikingfile chowa
wideo za RENDEROWANYM Cloudflare Turnstile (turnstile.render, bez trybu invisible), a
<video> jest puste i ukryte, dopoki wyzwanie nie padnie. Serwerowo nie do obejscia,
wiec oddajemy embed jako type=hoster i telefon otwiera go w WebView z domowego IP.
Rozroznienie po hoscie, bo seekplayer jako SPA w WebView pokazuje pusty player.
Najnowsze sceny: bylo 0/3, jest 3/3.

ZOSTAJE OTWARTE: rodzina seekplayera zmienila format odpowiedzi /api/v1/video. Stary
klucz AES dalej odszyfrowuje poprawnie, ale w miejsce sources sa teraz pola pk,
streamingConfig i hlsVideoTiktok ze SCIEZKA wzgledna. Zlozenie jej z hostem playera
daje 404, a z domenami z streamingConfig 403, wiec URL jest podpisywany po stronie
klienta z pola pk. Dotyczy starego katalogu galaxyporn ORAZ pornbusy (0/5).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 11:35:05 +02:00
goon-foss
5065df6220 fix(ingest): odrzucaj daty premiery odlegle w przyszlosc
Zgloszenie de732da2 ("porndish jakby zaprzestal ingestu"). Ingest dziala, 106 nowych
zrodel w 7 dni i 12-18 scen dziennie z poprawnymi datami. Problem byl na samej gorze
listy: dwie sceny porndish z datami 2026-12-02 i 2026-09-04, dodane jeszcze w maju,
stoja przy sortowaniu po premierze nad wszystkim, wiec pierwsze, co user widzi, nigdy
sie nie zmienia.

Data odlegla o miesiace to literowka w roku albo blad parsera, nie zapowiedz.
Przyjmujemy do 14 dni w przod, dalej odrzucamy, czyli scena sortuje sie po dacie
dodania. Wyczyszczone tez wstecz: 10 wierszy w calej bazie, po tym porndish ma na
gorze sceny z 2026-08-19.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:45:03 +02:00
goon-foss
e26c78df24 fix(ingest,proxy): pusta strona to nie koniec katalogu + miniaturki blokowane po IP
naughtymachinima (zgloszenie 83eb300d, "tylko 148 scen"): deep-crawl uznal katalog
za wyczerpany na stronie 8, bo trafil na pusta strone. Listing ma 1770 stron po 30
filmow, a ponowne wejscie na strone 9 oddalo 13 scen i ZERO bledow pobrania, czyli
tamto zero bylo chwilowym dlawieniem. Pusta strona bywa tez calkiem legalna, bo
bramka odrzuca klipy < 180 s, a to 2/3 tego katalogu. Konczymy wiec dopiero po trzech
pustych stronach pod rzad. Kursor odblokowany, kontrolny run przeszedl strony 9-14:
49 scen, 7 nowych, bez oznaczenia exhausted.

fullvideosporn (zgloszenie f4995691, "brak miniaturek"): adresy w bazie sa poprawne,
ale tn.sextu.com odrzuca nasz adres serwerowni: 429 przy kazdej probie, takze po
przerwie, a przez residential proxy 200 i 26 kB. Proxy obrazkow po odmowie
(401/403/429) ponawia teraz raz przez to proxy. Obrazek ma kilkadziesiat kB i klient
cachuje go dobe, wiec to nie jest proxowanie wideo. Sprawdzone: 6/6 miniaturek
laduje sie (15-116 kB), wczesniej 0/6.

Uwaga na przyszlosc: helper wladowal sie przy pierwszym podejsciu MIEDZY dekorator
trasy a proxy_image, wiec @router.get udekorowal jego, a /proxy/img/ oddawalo URL
proxy z loginem i haslem jako JSON. Naprawione, w docstringu ostrzezenie.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:43:29 +02:00
goon-foss
fa7fb668b6 fix(sites): sortuj po dacie premiery z fallbackiem na date dodania + napraw miniaturki
Zgloszenie 1df50de3 ("hqporner: brak nowych scen ze strony, brak miniaturek").
Oba objawy mialy inne przyczyny i oba sie potwierdzily.

1. Kolejnosc. Sceny byly i ingest dzialal (91 nowych w 7 dni, ostatnia tego dnia),
ale tuby daty premiery zwykle NIE podaja: xhamster 99,2% scen bez daty, xnxx 97,7%,
porntrex 95,8%, hqporner 93,5%, sxyprn 85,7%. Przy release_date DESC NULLS LAST
wszystkie bezdatowe ladowaly ZA datowanymi, wiec 82 z tych 91 scen siedzialy za
3,4 tys. starszych pozycji. Teraz sortujemy po dacie premiery, a gdy jej brak, po
dniu trafienia do katalogu; sceny z prawdziwa data (kanon) bez zmian. Wyrazenie jest
immutable (jawne AT TIME ZONE 'UTC'), wiec wchodzi do indeksu, migracja 0033.

2. Miniaturki. Kafelki bez obrazka byly podpisane FULLPORNER, nie HQPORNER. Picker
bral pierwsze zrodlo alfabetycznie, a tube:fullporner < tube:hqpornercom. Dwie wady
naraz: czesc miniaturek fullporner to 153-bajtowa atrapa oddawana z kodem 200, a
czesc wskazuje CDN hqporner, ktory odrzuca Referer fullporner.com (ten sam plik:
Referer fullporner.com 403, wlasny host obrazka 200, 30 kB). Wiec: przegladany
serwis wygrywa wybor miniaturki, a proxy obrazkow po 403 ponawia raz z wlasnym
originem obrazka.

Pomiar na 40 kafelkach hqporner: przed 38 ladowalo i 1 nie, po 39 ladowalo i 0 nie,
wszystkie podpisane wlasciwym serwisem. Glowny feed bez zmian.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:25:53 +02:00
goon-foss
34276afb71 fix(scenes): min_duration_sec=0 znaczy bez progu, nie duration_sec >= 0
Zgloszenie 2ec95be5 ("Hentaimama dalej 0 scen") bylo trafne, mimo ze drill-downy
juz wysylaly min_duration_sec=0. Backend tlumaczyl to na duration_sec >= 0, a w SQL
NULL nie przechodzi ZADNEGO porownania, wiec scena o nieznanej dlugosci wypadala
dokladnie tak samo jak dziesieciosekundowy smiec. Serwisy, ktore dlugosci nie podaja
w ogole (hentaimama, javflix, supjav, hentaigasm, hentaiplay, xanimeporn to 100%
NULL), oddawaly PUSTA liste.

Teraz 0 znaczy brak progu i filtr w ogole sie nie naklada, a prog > 0 dalej odcina
NULL-e swiadomie, bo tam chodzi o smieci w glownym feedzie. To samo rozroznienie w
scieszce "pure default", zeby jawne 0 nie gubilo taniego liczenia.

Zweryfikowane na produkcji: hentaimama, javflix, supjav, hentaigasm i xanimeporn
oddaja sceny, glowny feed z progiem 60 bez zmian.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:03:51 +02:00
goon-foss
8f6fa8c732 perf(scenes): indeks pod sortowanie serwisu po dacie premiery + fix wyscigu zapisu wyszukiwania
Zgloszenie 4cccc70f: sxyprn na liscie sites ladowal sie ok 18 sekund. Odtworzone:
/scenes?origin=tube:sxyprncom&sort=release_date schodzilo 19,23 s, a to samo z
sort=created_at 0,08 s. Ekran serwisu sortuje po dacie premiery, czyli
release_date DESC NULLS LAST, created_at DESC, id DESC, a istniejacy
ix_scenes_release_date jest ROSNACY: czytany od tylu daje NULL-e na poczatku i nie
obsluguje kluczy rozstrzygajacych. Planner leial wiec pelnym skanem scenes (3,9 mln)
i playback_sources (3,7 mln). Po zalozeniu pasujacego indeksu strumieniuje w
docelowej kolejnosci i konczy po 25 trafieniach: sxyprn 19,23 s -> 0,11 s,
hqporner 7,99 s -> 0,87 s. Drugi indeks po originie, bo playback_sources nie mial
zadnego.

GOON-4Y: add_saved_search sprawdzal istnienie i wstawial w dwoch krokach, wiec dwa
rownolegle zapisy tego samego zapytania (podwojne tapniecie, ponowienie po
timeoucie) oba widzialy pusto i drugi dostawal 500 na uq_saved_searches_device_query.
Teraz IntegrityError konczy sie oddaniem istniejacego wiersza. Test: 6 rownoleglych
zapisow -> 6x200 i jeden wiersz.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:00:58 +02:00
goon-foss
65f768cf8a chore(movies): wylacz pandamovies, serwis padl
Zostal im tylko zapamietany fronton. Strona glowna oddaje 291 kB i wypisuje 56
filmow, ale KAZDA inna sciezka to 404: listing /movies/ (ten, ktory czytal
konektor), /movies/page/2/ linkowana przez ich wlasny szablon, /genre/* i
/release-year/* z ich menu, sitemapa, a przede wszystkim same strony filmow,
0 na 6 dzialajacych. To nie blokada na nasze IP, bo przez residential proxy
wychodzi identyczne 404 (te same 796 bajtow).

Konektor konczyl runy jako success z zerem rekordow, wiec falszowal obraz w
monitoringu. Watchdog filmowy czyta te sama liste, wiec alert tez cichnie, i
slusznie, bo przestajemy to ingestowac.

Playback tego, co juz mamy, dziala dalej: zrodla wskazuja na hostery (doply,
luluvid, seekplayer), nie na ten serwis. Klasa zostaje w dooplay.py dla
backrefu origins pandamovies:*.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 12:51:41 +02:00
goon-foss
17601fd0b8 fix(javflix): czytaj /new/, bo strona glowna to staly zestaw
javflix stal 89h bez nowosci, mimo ze scraper chodzil i widzial sceny. Powod:
listing szedl ze strony glownej, a ta pokazuje staly zestaw 16 postow, ktory mamy
w calosci. Audyt 2026-08-20: /new/ ma 7 nieznanych scen z 9, strona glowna 0 z 16.

Przy okazji paginacja: WordPress ja tu tylko udaje. /page/2/ i /page/3/ oddaja
identyczna tresc co strona glowna, a /new/page/2/ to samo co /new/, wiec
browse-latest mielil ten sam zestaw piec razy na run. Teraz strona 1 to /new/,
strona 2 to strona glowna, dalej pusto.

Zweryfikowane na zywo: run oddal seen=25, new=7.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 12:30:58 +02:00
goon-foss
544de9c5ba feat(ingest): backfill brakujacej dlugosci scen
1 755 421 scen nie ma dlugosci ani na scenie, ani na zrodle, wiec wypadaja z
feedu: w SQL "duration_sec >= 60" nie jest prawda dla NULL, przez co scena o
nieznanej dlugosci znika tak samo jak dziesieciosekundowy smiec. Filtr zostaje,
bo odcina smieci, uzupelniamy dane.

Swiadomie waskie originy. Uniwersalny regex trafia w smieci: porntrex ma w HTML
"duration: 5" reklamy, mypornerleak dlugosc ciastka 720, a xhamster i porntrex
wypisuja dlugosci filmow z paska obok (naiwne dopasowanie dalo 198s zamiast 240s).
Zla dlugosc jest gorsza niz brak, bo dedup opiera sie na niej najmocniej.

- xvideos, xnxx: VideoObject LD-JSON, 5/5 na probce
- xhamster: videoEntity z kontrola zgodnosci id z URL-a
- porntrex pominiety: strona szczegolow nie podaje wlasnej dlugosci

Kolejka jak przy phashu (plan raz, mielenie paczkami, przezywa restart):
845 899 scen, 500 stron co 5 min, czyli ok. 6 dni. Plan powtarza sie co 24h,
zeby swieze sceny bez dlugosci tez trafialy do kolejki.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 12:10:22 +02:00
goon-foss
cddf60acc2 fix(perverzija): powrot na natywny HLS + passthrough manifestu
Zmiana z 18.08 przestawila perverzije na embed-iframe na podstawie jednej
strony, ktora akurat miala mixdrop. Probka 30 stron: 90% dalej stoi na
xtremestream, a xs1.php oddaje poprawny #EXTM3U (8/8 na szesciu rotujacych
subdomenach). Bledy "Input does not start with #EXTM3U" braly sie ze zlego
Referera, ktory zwraca 403 z HTML-em, nie ze zmiany protokolu.

- registry: perverzijacom wraca na natywny ekstraktor
- brak xtremestream -> fallback na embed-iframe (mixdrop, playhydrax)
- mobile_direct_ok: przez VPS idzie sam manifest, segmenty telefon ciagnie
  prosto z CDN (zweryfikowane cross-IP: 200, sync 0x47 z domowego lacza)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:55:08 +02:00
goon-foss
bbc2059728 feat(ui): badge jakosci i nazwa serwisu na kafelku sceny
Kierunek A z makiet (miniaturki niosa ekran, chrome cichy) + jeden element z C:
jakosc i zrodlo widoczne wprost na kafelku.

Backend musial to najpierw WYSTAWIC, bo lista jedzie w trybie `light`, ktory okrawa
playback_sources do samej miniatury:
  - `SceneOut.max_quality_p` (kolumna z migracji 0029, dotad uzywana tylko jako filtr),
  - slim wpis niesie PRAWDZIWY `origin` zrodla wybranej miniatury zamiast "".

Kafelek: badge jakosci w LEWYM dolnym rogu (czas zostaje w prawym, ten sam ciezar
wizualny), a w linii meta studio + przygaszona nazwa serwisu. Badge pokazujemy TYLKO
gdy jakosc jest znana (6,5% scen), bo ma byc faktem, nie zgadywaniem.

Zweryfikowane na emulatorze na PRAWDZIWYCH danych: zeby to bylo mozliwe, zbudowalem
build debugowy podpisany kluczem release (przechodzi kontrole X-App-Signature, a jako
debug nie ma FLAG_SECURE, wiec da sie zrobic zrzut). Widac "4K" i "1280p" w rogu oraz
"ONLY FANS  SXYPRN" w linii meta. Tymczasowa zmiana podpisu w build.gradle cofnieta.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 12:41:16 +02:00
goon-foss
0fed952c5c feat(filtr): minimalna jakosc w filtrze scen (720p/1080p/4K)
Prosba uzytkownika (zgloszenie 17376139). Backend mial juz parametr `min_quality_p`,
ale w praktyce byl NIEUZYWALNY i to zajelo wiekszosc pracy.

Wydajnosc, mierzona na produkcji przez EXPLAIN ANALYZE, prog 1080p:

  EXISTS na playback_sources (stan zastany)   32 s   3 556 612 odwiedzonych scen
  + indeks funkcyjny per-scena                24 s
  JOIN z DISTINCT po jakosci                   1,1 s W IZOLACJI
  ten sam JOIN + reszta filtrow feedu         52 s   planer wraca do skanu po dacie
  kolumna scenes.max_quality_p (0029)          2,0-2,6 s
  + indeksy czesciowe pod progi (0030)         0,09-0,11 s

Wniosek, ktory kosztowal najwiecej: ksztaltem zapytania sie tego NIE dalo zalatwic.
Koszt to LICZBA odwiedzonych scen, nie pojedynczy test, a przy `ORDER BY created_at
DESC LIMIT 24` planer i tak wracal do przechodzenia scen po dacie, gdy tylko doszly
pozostale filtry (bramka wertykalow, heurystyka szkieletow, prog dlugosci). Stad
denormalizacja + indeksy czesciowe z predykatem progu, ktore daja gotowe sortowanie.

Semantyka SUROWA, swiadomie: `quality` zapisujemy oportunistycznie, zna ja 6,5% scen
(210 302 z 3 236 368), najlepsze zrodlo ma 26% pokrycia. Wariant lagodny, przepuszczajacy
sceny o nieznanej jakosci, odrzucony po zmierzeniu: odsiewalby 88 647 z 3,2 mln, czyli
nie realizowalby intencji "nie chce ogladac ziemniaka". Filtr pokazuje wiec tylko jakosc
POTWIERDZONA, a UI mowi to wprost podpisem pod przelacznikiem, bo inaczej gwaltowny
spadek liczby wynikow wyglada na zepsuta aplikacje.

Warianty tekstowe 4K/UHD usuniete z warunku: 0 wystapien na 238 452 zywe zrodla,
a `OR ilike` blokowal uzycie indeksu.

Odswiezanie w taxonomy_counts (co 3h), z czyszczeniem do NULL gdy scena traci zrodlo
z jakoscia. Backfill: 210 302 sceny w 2m56s.

Zweryfikowane na emulatorze: sekcja MIN QUALITY renderuje sie z podpisem ostrzegawczym.
Lista wyszla pusta, ale to build debugowy dostajacy 403 (podpis debug spoza allowlisty),
nie blad filtra: ten sam URL z poprawnym podpisem oddaje 50 wynikow w 0,12 s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 11:06:34 +02:00
goon-foss
085c0c1dd6 fix(playback): perverzija na nowy hoster, naughtymachinima re-resolve na reset
Dwa zgloszenia z apki, dwa rozne pierwotne powody.

perverzija (zgloszenie af9be63a, 520 bledow "Input does not start with #EXTM3U",
ZERO sukcesow): strona porzucila player xtremestream/xs1.php i osadza teraz mixdrop.
Stare URL-e xs1.php oddaja HTML zamiast manifestu HLS, stad kazdy playback padal.
Rejestr przelaczony z natywnego perverzija.extract na _embed_iframe.extract, ktory
wyluskuje mixdrop i oddaje type='hoster' -> telefon resolwuje w WebView. Natywny
ekstraktor zostaje w drzewie, gdyby xtremestream wrocil.

UWAGA co do weryfikacji: mixdrop gejtuje odtwarzanie za adsco.re (antybot). Sprawdzone
w prawdziwym Chrome na IP residential - MDCore.wurl zostaje null, zero requestu wideo,
bo brama celuje w AUTOMATYZACJE. Dla realnego usera w WebView player mixdrop gra
normalnie (to caly biznes mixdropa), ale nie dalo sie tego zautomatyzowac end-to-end.
To i tak scisle lepsze niz obecny stan 100% martwy.

naughtymachinima (zgloszenie ef728604 "od razu fallbackuje do strony, 502/429"):
ekstraktor SPRAWNY, direct mp4 bez tokenu, IP-bound do residential (403 z datacenter,
telefon gra). Telemetria 64 sukcesy / 19 bledow, blad to przejsciowy Connection reset
z CDN na dzialajacym URL-u. Bez re-resolve pojedynczy reset od razu spychal na WebView,
ktory ladowal zdlawiona strone tube'a - stad 502/429 w zgloszeniu. Dopisany do
BACKEND_RERESOLVE_ORIGINS: przy bledzie odswieza polaczenie zamiast uciekac do WebView.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 10:23:05 +02:00
goon-foss
f48fbbd4ad fix(performers): wlasna obsada dla JAV, brak przycisku dla animacji
Domkniecie tej samej rodziny bledu co przy tagach i studiach. Pomiar rozstrzygnal,
ze oba wertykaly wymagaja INNEGO rozwiazania, wiec nie ma tu jednego filtra:

  animacja   12 698 scen ->     0 performerow
  JAV        54 888 scen -> 1 392 performerow

JAV: /performers dostaje parametr `vertical`, liczony na zywo, bo zdenormalizowany
`performers.scene_count` z zalozenia opisuje wylacznie glowny feed (job taxonomy_counts
wyklucza originy wertykalowe). Bez tego zakladka pokazywala zachodnia obsade, a wlasne
nazwiska mialy licznik 0 i ladowaly na koncu listy. Po zmianie: Satomi Suzuki (137),
Kei Mizushima (128), yui hatano (68).

Animacja: przycisk Performers jest chowany. Zero obsady to nie brak danych, tylko
wlasciwosc tresci: dla postaci rysowanych nie istnieje kanon (TPDB/StashDB ich nie maja),
wiec zaden scraper nie ma czego przypisac i zaden nigdy nie bedzie mial. Filtrowanie
dawaloby gwarantowanie pusta liste, czyli dokladnie ten sam objaw, ktory naprawiamy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 12:51:39 +02:00
goon-foss
8c8f22d388 feat(tags): zdejmij znaczniki jakosci + przytnij ogon tagow rule34video
Znaczniki jakosci (hd, 4k, 720p, HD Videos, wzorzec ^\d{3,4}p$) trafiaja na stoplist
i znikaja z katalogu: 323 379 przypisan, 16 tagow. Powod: apka ma osobny filtr jakosci
liczony ze ZRODEL ODTWARZANIA, ktory jest wiarygodny, a tag jest deklaracja tuba i bywa
falszywy. Dwa rownolegle sygnaly o tym samym, z ktorych jeden klamie, sa gorsze niz jeden.

Ogon rule34video: 356 scen wnosilo 1112 roznych tagow do WSPOLNEJ listy uzywanej przez
caly katalog, z czego 602 wystepowaly dokladnie raz (nazwy postaci i serii, tagowanie
w stylu booru). Nowy job co 24h zostawia tagi z >=3 scen i najwyzej 15 na scene,
uporzadkowane po czestosci w obrebie serwisu.

Wazny szczegol reguly, wychwycony dopiero w symulacji: ochrona tagow wspolnych dotyczy
TYLKO progu, nie limitu. Pierwsza wersja wylaczala tagi wspolne rowniez z limitu i przez
to prawie nie dzialala, rekord spadal 161 -> 147 zamiast do 15, bo najbardziej obsypana
scena skladala sie glownie z tagow wspolnych.

Wynik na produkcji: srednia na scenie rule34video 13,5 -> 9,1, rekord 161 -> 15, zadna
scena nie zostala bez tagow. Usuniete 1554 przypisania i 2475 osieroconych tagow.
VACUUM ANALYZE po obu operacjach.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 12:28:47 +02:00
goon-foss
38a2724963 feat(tags): odrzucaj tagi marketingowe zamiast opisujacych tresc
Zgloszenie 778cd5be: "cos za duzo tych tagow, one sa faktycznie na stronie czy to
over attribution?". Sprawdzone u zrodla: tytul posta na sxyprn ma dokladnie te 28
hashtagow, wiec to NIE nasza over-atrybucja, tylko uploader wklejajacy ten sam blok
do kazdego wideo (stad #France i #french przy amerykanskiej scenie).

Statystycznie tego nie da sie odsiac: blok jest inny u kazdego uploadera, a najczestszy
tag na sxyprn (Hardcore) ma 47% udzialu, wiec zaden prog nie oddziela spamu od prawdy.
Da sie za to wyciac slowa, ktore nigdy nie opisuja tresci. Tylko to robi ta zmiana.

Filtr wpiety w resolve_tag, czyli jedno miejsce, przez ktore ida wszystkie tagi
z kazdego zrodla, wiec nie wroca przy re-scrape. Retroaktywnie skasowane 137 861
przypisan scen i 247 filmow, 29 tagow. Sprawdzone przed kasowaniem: tylko 270 scen
zostaje bez tagow i ZERO userow ma ktorykolwiek z nich na liscie ukrytych. Srednia
liczba tagow na scene 7,7 -> 7,3. VACUUM ANALYZE odpalony od razu.

Swiadomie zostawione: onlyfans (realny typ tresci, 72 tys. przypisan) oraz 4k/hd/720p
(niosa informacje, choc apka ma juz wiarygodny filtr jakosci ze zrodel odtwarzania,
wiec to decyzja produktowa, nie sprzatanie smieci).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 12:00:45 +02:00
goon-foss
a1f604a7a4 fix(verticals): przenos wertykal przy przejsciu do tagu/studia/performera
Zgloszenia 195ae42e i e9de414c: klikniecie studia w anime nic nie robilo, a tag
kliniety w anime pokazywal sceny spoza anime.

Jedna przyczyna: TagScenes/StudioScenes/PerformerScenes wolaly listScenes BEZ
parametru vertical, a backend bez niego wyklucza wszystkie wertykaly. Studio
animacyjne mialo wiec zero scen (pusty ekran = wyglada na martwy klik), a tag
zwracal wylacznie sceny glownego katalogu.

SceneOut dostaje pole "vertical" liczone z originow zrodel, czyli jedno zrodlo
prawdy w app/verticals.py zamiast dublowania listy originow w apce. W trybie
light dociagamy origin z tego samego wiersza co miniaturka, wiec zero dodatkowych
zapytan. SceneDetail przekazuje wartosc dalej w paramach nawigacji.

Dotyczy tak samo sekcji JAV, ktora miala ten sam blad.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 11:42:47 +02:00
goon-foss
f70082e7de chore(seekplayer): przestan przekazywac martwy cf_fallback
Zadanie bylo "podpiac albo usunac". Sprawdzone i NIE DA SIE podpiac.

Fallback za Cloudflare (svb.professionalvisibility.cyou/...cf-master.<ts>.txt)
oddaje 403 w szesciu wariantach:

    httpx + Referer hostera        httpx + Referer galaxyporn.net
    curl_cffi chrome120 z Ref      curl_cffi bez Ref (oddaje strone CF)
    znacznik czasu biezacy         znacznik z linku glownego

I to samo 403 z lacza RESIDENTIAL, wiec to nie blokada datacenter. Adres
jest najpewniej zwiazany z sesja tego samego wywolania /api/v1/video,
a my siegamy po niego osobno i po czasie (znacznik w nazwie pliku bywa
5 dni stary). Podpiecie dokladaloby request, ktory ZAWSZE pada, na
sciezce bledu — czyli opoznienie zamiast ratunku.

Cel, ktoremu mial sluzyc (przezyc padniety nod CDN), jest juz osiagniety
inaczej: ponowny resolve wraca z innym adresem CDN (47547fe).

`proxy_no_verify` ZOSTAJE mimo ze nic go nie czyta: zapisuje realne
ryzyko (cert niepasujacy do golego IP), a jego usuniecie skasowaloby te
informacje. Falszywy komentarz o istniejacej galezi `verify=False` juz
poprawiony.

Wszystkie szesc prob zapisane w docstringu, zeby nikt ich nie powtarzal.
Kontrola po zmianie: extractor oddaje m3u8, proxy 200.
2026-08-14 10:29:02 +02:00
goon-foss
47547fe694 fix(playback): galaxyporn re-resolwuje sie po bledzie zamiast poddawac
Zgloszenie 7f2234eb: "samo wideo dziala, a aplikacja zglasza problem
z hostem". Ekstraktor NIE jest zepsuty:

  - try_extract oddaje dzialajacy manifest w 0,4 s
  - z Refererem ekstraktora (galaxy.4meplayer.pro) link daje 200; bez
    niego 403, wiec naglowek jest ustawiany poprawnie
  - pobranie przez nasze /proxy oddaje 200 i playliste z wariantem 1080p
  - telemetria 14 dni: 1140 udanych, 25 bledow (2,1%)

Padal POJEDYNCZY nod CDN. Kolejne wywolania resolve tej samej sceny
wracaja z ROZNYMI adresami (185.237.107.133, potem 203.188.166.163), a
token ma ~2,8 h TTL i nie jest IP-bound. Czyli ponowny resolve po prostu
laduje na zywym wezle — dokladnie wzorzec, ktory dziala juz dla watchporn.
Stad `tube:galaxyporncom` w BACKEND_RERESOLVE_ORIGINS.

Po drodze skorygowany FALSZYWY komentarz w seekplayer_engine.py: twierdzil,
ze stream_proxy.py ma galaz `verify=False` dla hostow pod golym IP. Nie ma
jej — slowo `verify` nie wystepuje w tym pliku ani razu. `proxy_no_verify`
i `cf_fallback` sa ustawiane przez trzy ekstraktory i przez NIC nieczytane.
cf_fallback jest o tyle bolesny, ze to gotowy zapasowy URL, ktory uratowalby
wlasnie ten przypadek. Osobne zadanie.

Blad diagnostyczny po drodze, dla potomnosci: pierwszy test dal 404, bo
przetestowalem URL uciety wlasnym printem [:70], bez /master.m3u8.
2026-08-14 10:22:08 +02:00
goon-foss
f3f16b5c67 feat(favorites): ulubione studia licza takze filmy
Studio bywa WYLACZNIE filmowe: Jonathan Jordan XXX 0 scen / 654 filmy,
Kink Clips 0/616, EAGLE 0/523. Lista ulubionych pokazywala wtedy samo
"0 scenes", czyli wygladala na pusta, mimo ze badge "+N" liczyl filmy
juz od 2026-07-28 (_merged_new_counts).

Backend: `FavoriteStudioOut.movie_count`, liczony NA ZYWO. Ulubionych
studiow jest kilkaset na urzadzenie, a filmow o rzedy wielkosci mniej niz
scen, wiec agregat jest tani i nie trzeba kolejnej zdenormalizowanej
kolumny do utrzymania.

Apka pokazuje oba liczniki, a gdy jednego nie ma, pomija go, zeby nie
robic z tego "0 scenes · 654 movies".

Domyka to temat zaczety zakladka Movies na ekranie studia: dodanie do
ulubionych od strony filmu juz dzialalo (gwiazdka w StudioMoviesScreen).
2026-08-13 20:30:17 +02:00
goon-foss
1a75433281 fix(proxy): rozdziel wygasly podpis od awarii CDN + ponow przejsciowe 5xx
Zgloszenie 7f2234eb: "Cos nie tak z ekstraktorem? Bo samo wideo dziala a
aplikacja zglasza problem z hostem" (scena galaxyporn).

Ekstraktor jest SPRAWNY. Sprawdzone end-to-end: resolve 200, master m3u8,
wariant, 525 segmentow, 60/60 pobranych. Telemetria 30 dni dla tego
zrodla: 1310 sukcesow, 25 bledow (1,9%).

Ale przy okazji wyszlo cos wiekszego. Wszystkie te bledy to "502", a
mapowanie w `_upstream_error_response` sklejalo w ten kod DWIE rozne
awarie: upstream 5xx (CDN padl) ORAZ kazde inne 4xx, w tym 403. Test
syntetyczny: upstream oddaje 403, nasze proxy oddawalo 502.

To bolalo podwojnie. `playback_events.error_detail` bierze sie z komunikatu
ExoPlayera, wiec w telemetrii nie dalo sie odroznic "CDN padl" od "wygasl
podpisany token" — a to zupelnie inne naprawy (pierwsze: czekac, drugie:
odswiezyc resolve). Do tego 403 szedl przez raise jako "moze nasz bug" i
zasmiecal Sentry, choc wygasanie tokenow na tych CDN-ach jest NORMALNE.

Zmiany:
1. 401/403 przepuszczane z prawdziwym kodem (+ log INFO, bez wyjatku).
   Cache i tak byl juz invalidowany na 401/403/404/410, wiec kolejny
   resolve dostaje swiezy URL.
2. Przejsciowe 502/503/504 ponawiane RAZ (tylko GET/HEAD, idempotentne).
   Te CDN-y stoja na wielu wezlach (galaxyporn: 3 rozne IP w jednej
   sesji), wiec druga proba zwykle trafia w zdrowy. 4xx nie ponawiamy.

Zweryfikowane: 403 wychodzi teraz jako 403 (bylo 502), normalne
odtwarzanie bez zmian (60/60 segmentow 200).

Uwaga: sciezka ponowienia nie zostala odpalona end-to-end, bo 502 nie da
sie wywolac na zadanie. Widac ja w logu ("proxy: upstream N, ponawiam").
2026-08-13 18:16:54 +02:00
goon-foss
dde21f2e6e fix(thumbs): degraduj chwiejne hosty miniaturek zamiast zerowac
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.
2026-08-13 15:34:40 +02:00
goon-foss
276fb4c24d fix(dedup): samozlaczenie po phashu odsiewa zdegenerowane wartosci
`_pairs_exact_phash` laczylo scene_fingerprints po wartosci BEZ zadnego
ograniczenia. Do tej pory uchodzilo, bo zdegenerowanych wartosci bylo
malo i blacklista je kasowala. Zmienia to backfill: dokladamy ~240 tys.
odciskow z xvideos/xnxx/epornera, a te serwuja zaslepki przy usunietych
filmach.

Dwa problemy naraz:

1. Blacklista odswieza sie RAZ NA DOBE, wiec swiezo powstala zaslepka ma
   pelna dobe okna na wpuszczenie do potoku tysiecy niepowiazanych scen.
2. Samozlaczenie jest KWADRATOWE po liczbie scen dzielacych wartosc:
   zaslepka przy 5 tys. scen to 12,5 mln par i job pada na pamieci,
   zanim cokolwiek zdazy ja zablacklistowac.

Teraz zapytanie samo odsiewa wartosci dzielone przez >=10 scen (ten sam
prog co phash_blacklist) ORAZ te juz zablacklistowane, wiec dziala
natychmiast, nie po dobie.

NIE jest to atrapa: 4% w backfill jedna taka wartosc juz istnieje
(12 scen) i blacklista jej jeszcze nie widziala. Po zmianie samozlaczenie
daje 23 555 par w 8,3 s.
2026-08-13 14:50:46 +02:00
goon-foss
5217d07222 fix(search): nazwa performera musi byc w slugu SPOJNA FRAZA
Zgloszenie 2026-08-13: strona Tiffani Time pelna scen o Tiffany Tatum,
Tiffani Madison i Victorii Tiffani.

Przyczyna: `_search_base.search` dokleja szukanego performera do KAZDEJ
sceny bezwarunkowo (`all_performers = [RawPerformer(name=query), ...]`),
wiec cala poprawnosc obsady wisi na filtrze tokenow. A filtr testowal
PODCIAG na luznych tokenach, wiec:

  "tiffany" ⊂ "lp-s-tiffany-love-first-time-gonzo"   (inna osoba)
  "time"    ⊂ "adult-time", "first-time", "multiple-times"  (pospolite slowo)

Historia tej linijki to trzy poziomy: any() -> all() -> (teraz) fraza.
`all()` naprawil "Ava Koxxx na scenach Avy Devine", ale zostawil oba
powyzsze. Teraz slug musi zawierac CALA nazwe jako ciag, z granica slowa
po bokach, z dowolnym separatorem miedzy czlonami.

Dozwolone koncowe "s": slug gubi apostrof, wiec "TiffaniTime's" zapisuje
jako "tiffanitimes". Nie luzuje bramki, bo przed tym "s" stoi cala fraza.

hqporner mial WLASNA kopie tego filtru (i wlasny zestaw dziur) - podpiety
pod ta sama funkcje, zeby sie nie rozjezdzalo.

12 przypadkow testowych z realnych danych, w tym te ktore MUSZA przejsc
(tiffani-time-*, tiffanitimes-*, mia-li-* z czlonem <3 znaki).

Do tego skrypt czyszczacy juz istniejace pomylki. Kryterium zawezone po
obejrzeniu probki: samo "brak nazwy w tytule" kasowalo MESKICH performerow
(tuby nie wypisuja ich w tytule, a przypisanie szlo z listy obsady, nie
z searcha). Dolozony warunek "inny performer sceny ma dowod I dzieli
czlon" - probka 14/14 to realne pomylki.
2026-08-13 11:17:43 +02:00
goon-foss
a16883d2f3 feat(dedup): backfill phasha z zapisanych miniaturek
Root cause zgloszenia 9d272101 ("5 duplikatow, czemu nie zmergowane?"):
phash mialo tylko 37,8% grywalnych scen. Licza go WYLACZNIE niektore
konektory w momencie ingestu, wiec najwieksze zrodla maja miniaturke dla
~100% scen, a odcisk dla 1-2% (xvideos 1,8%, xnxx 1,4%, eporner 1,0%).
Material jest zapisany, brakowalo tylko obliczenia.

W zglaszanym przypadku 7 wierszy o identycznej dlugosci 2324 s, a dwa
kafelki z IDENTYCZNA okladka nie mialy phasha wcale, wiec jedyny sygnal,
ktory by je sklail, nigdy nie powstal.

Zakres CELOWANY, nie caly katalog: sceny w klastrze (performer, dokladna
dlugosc) o licznosci >1, bez phasha, ale z zapisana miniaturka = 238 704
pozycje (wobec ~1,4 mln scen bez phasha). Reszta nie ma sie z czym skleic.

Kolejka jako TABELA, nie zapytanie w locie: wyznaczenie kandydatow to
ciezki agregat po calym katalogu, ktorego nie chcemy powtarzac przy kazdej
paczce, a kolejka przezywa restart workera i widac z niej postep.

Weryfikacja end-to-end na zglaszanej scenie: ce81a110 dostal phash
85c1bac2f8c60ecf, czyli DOKLADNIE ten sam, ktory mial juz 8373bbb5 (dwa
z kafelkow uzytkownika) -> istniejacy phash_exact je teraz sklei.

Nie zapisujemy wartosci z phash_blacklist (zaslepki dzielone przez setki
scen). Throttling swiadomy: 800 co 15 min, ~3 dni na nadrobienie.

Dwie pulapki SQL zapisane w kodzie: `referer` ma 255 znakow wiec origin
wycinamy w SQL (pelny page_url wywalal planowanie), a rzutowanie musi isc
przez CAST() bo text() SQLAlchemy nie podstawia parametru za ktorym stoi
`::`.
2026-08-13 10:49:12 +02:00
goon-foss
ff898b0783 feat(verticals): animacja odgrodzona od glownego feedu + filmy na ekranie studia
1. WERTYKALY. Hentai i 3D szly do glownego feedu wymieszane z zachodnim
katalogiem, mimo ze argument za odgrodzeniem byl ten sam co przy JAV.
Zamiast drugiej kopii mechanizmu JAV wprowadzam wspolne pojecie wertykalu
(app/verticals.py): mapa nazwa -> originy, jeden predykat, `?vertical=`.

Brama po originie jest DOKLADNA, zmierzone: 9507 scen animowanych, ZERO
z originem spoza listy (nie maja sie z czym zdeduplikowac). Dlatego osobna
baza nie jest potrzebna, rozdzielam logicznie.

Tagi to samodzielny powod: z 3116 tagow przy scenach animowanych tylko 452
wystepuja tez poza animacja, czyli 85% to slownictwo wylacznie animacyjne.
`/tags?vertical=` liczy je NA ZYWO (male zbiory, zero migracji), a
zdenormalizowany Tag.scene_count opisuje juz WYLACZNIE glowny feed.

Przy okazji naprawione zasmiecenie JAV-em istniejace od lipca:
taxonomy_counts wliczal wertykaly do licznikow, ktore opisuja feed ich
nie pokazujacy. Refresh: 1476 tagow, 1402 performerow, 154 studia.

Stary `?jav=true` DZIALA dalej (instalacje sprzed sierpnia go wysylaja).

2. FILMY NA EKRANIE STUDIA. Zgloszenie: polubione studio od filmow nie
pokazuje nowych filmow i nie ma "+1". Backend liczyl je poprawnie
(_merged_new_counts scala sceny i filmy od 2026-07-28). Blad byl w apce:
tap na ulubione studio ZEROWAL licznik (markStudioSeen) i wchodzil na
ekran wylacznie ze scenami, wiec "+N" z nowych filmow znikalo, a filmy
nie mialy sie gdzie pokazac. StudioMoviesScreen istnial, ale wchodzilo
sie do niego tylko z detalu filmu. StudioScenes dostaje zakladki
Scenes/Movies, jak PerformerScenes.

Pasek zakladek w headerze przewija sie w poziomie, bo piata pozycja
(Anime) nie miescila sie na waskich telefonach.
2026-08-13 10:31:54 +02:00
goon-foss
1c1e46130a feat(3d): konektor naughtymachinima - szoste zrodlo wertykalu
Machinima i animacje SFM/Blender. Kanon nie istnieje tak samo jak przy
hentai i rule34video, wiec kazda pozycja jest orphanem i to poprawne.

Najzdrowsza jednostka tresci calego wertykalu 3D: mediana 289 s, ZERO
pozycji ponizej minuty, 18/25 powyzej progu potoku. Dla porownania
rule34video ma mediane 68 s i traci ~70% katalogu.

Playback najprostszy z serii: jawne <source> w trzech jakosciach, bez
tokenu, bez AJAX-a, bez CF. Zweryfikowane z VPS: 206, ftypisom, 140 MB,
dziala bez Referera, wiec mobile_direct_ok i zero pracy po stronie apki
(inaczej niz rule34video, gdzie token byl IP-bound).

Szosty niezalezny host wertykalu (videos.naughtymachinima.com), zadna
z szesciu stron nie re-hostuje pozostalych.

Odsiewamy pusty <source src=""> (placeholder playera) i preroll
/images/preroll/NMintro.mp4, ktory pasuje do naiwnego \.mp4.

Bramka dlugosci zestrojona z min_ingest_duration_sec, jak przy
rule34video. Pilot 3 strony: seen 48, new 48, skipped 0, errors 0.
2026-08-13 09:06:24 +02:00
goon-foss
2939e03d59 feat(3d): konektor rule34video - piate zrodlo wertykalu, pierwsze 3D
Animacje SFM/Blender. Kanon nie istnieje tak samo jak przy hentai, wiec
kazda pozycja jest orphanem i to poprawne.

Playback: KVS z jawnymi flashvars (4 jakosci, bez license_code), ale
`v-acctoken` jest ZWIAZANY Z IP tego, kto pobral strone. Test krzyzowy:
URL wygenerowany przez proxy i pobrany z VPS = 403, ten sam URL z IP
generujacego = 206 ftypisom 70 MB. Po zdekodowaniu tokenu adresu nie
widac wprost (inaczej niz fpoxxx), wiec samo ogladanie nie wystarcza.

Dlatego bez mobile_direct_ok: telefon resolwuje sam, UPFRONT, istniejaca
sciezka isGetFileUrl()/resolveGetFilePage z SceneDetailScreen. Rozszerzam
getfileResolver o flashvars, bo dotad umial tylko <source> (hdporn.gg,
fullmovies.xxx). Zweryfikowane end-to-end z residential IP: strona ->
flashvars 720p -> 302 na boomio-cdn -> 206 ftypisom 39,8 MB.

Bramka dlugosci zestrojona z `min_ingest_duration_sec` (prod 180 s)
zamiast wlasnej liczby: pierwsza wersja miala 60 s i liczniki klamaly
(seen 57, new 31, skipped 26). Po zestrojeniu seen 20, new 20, skipped 0.
Krotka tresc wycina ~70% katalogu (mediana 68 s).

Tagi TYLKO z class=tag_item. `class=button` wyglada na wlasciwe, a jest
chmura "Top Tags": przy filmie o Lux siedzialy tam "cell (dbz)" i
"queen of pain (dota)". Autor animacji zapisany jako studio.
2026-08-13 08:47:04 +02:00
goon-foss
fcfac697cf feat(hentai): konektor hentaiplay.net - czwarte zrodlo wertykalu
CZWARTY niezalezny host: pliki na hentaiplanet.info, podczas gdy hentaimama ma
gdvid.info, xanimeporn download.xanimeporn.com, a hentaigasm hgasm<N>.com. Cztery
strony, cztery osobne pule plikow - zadna nie re-hostuje pozostalych, mimo ze katalogi
odcinkow mocno sie pokrywaja.

Metadane z RSS-a, tak jak przy hentaigasm i z tego samego powodu: /genre/ w HTML strony
to 2084 linki, najwieksza chmura z sidebara w calym wertykale (hentaigasm mial 38,
hentaimama 118). Feed daje date, tytul i realne kategorie. Odsiewamy przy tym pozycje
czysto techniczne (Hentai Anime, New Hentai, English Subbed) oraz rocznik, bo to nie sa
tagi tresci. /page/2/ nie zwraca odcinkow, /feed/?paged=N stronicuje chronologicznie.

Playback: mp4 wprost w HTML (video.js), bez AJAX-a i bez Cloudflare. Pulapka: serwis
nazywa miniaturki od pliku wideo (…-RAW.mp4_snapshot_07.59.jpg), wiec naiwne szukanie
.mp4 lapie zarowno wideo, jak i obrazek. Wymagamy URL-a KONCZACEGO sie na .mp4 i
odrzucamy wp-content/uploads.

Druga pulapka, zlapana dopiero testem: og:image na tej stronie NIE ISTNIEJE, miniaturka
jest tylko w JSON-LD i z escapowanymi ukosnikami. Pierwsza wersja dawala 12/12 odcinkow
bez miniaturki.

Zweryfikowane z VPS: 206 na Range, ftypmp42, 78 MB, dziala BEZ Referera i bez tokenu.
Serwer oddaje content-type application/octet-stream, ale sciezka konczy sie .mp4, wiec
ExoPlayer wybierze Mp4Extractor po rozszerzeniu.

Pilot: seen 48, new 48, errors 0. Komplet dat i miniaturek.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 15:31:21 +02:00
goon-foss
a5295be10e feat(hentai): konektor hentaigasm.com - trzecie zrodlo wertykalu
TRZECI niezalezny host w wertykale. Te same odcinki co hentaimama i xanimeporn, ale
znowu inne pliki: tutaj hgasm<N>.com/<Tytul Ze Spacjami>.mp4, tam gdvid.info/N/... i
download.xanimeporn.com/videos/1080p/[1080p]<id>.mp4. Zadna z trzech stron nie
re-hostuje pozostalych.

Metadane w CALOSCI z RSS-a i to nie skrot tylko koniecznosc:
- strona odcinka NIE MA daty publikacji w zadnym standardowym miejscu (ani JSON-LD,
  ani article:published_time, ani <time>), a feed ma pubDate
- /genre/ w HTML to 38 linkow, czyli kolejna chmura z sidebara; feed daje 5 realnych
  kategorii, gdzie pierwsza to nazwa serii
- /page/2/ nie zwraca odcinkow w ogole, a /feed/?paged=N stronicuje chronologicznie

Playback najprostszy z calej trojki: konfiguracja JWPlayera z gotowym file: wprost w
HTML, bez AJAX-a i bez Cloudflare. Sciezka zawiera SPACJE, wiec kodujemy sama sciezke,
zostawiajac schemat i host. Host ROTUJE miedzy odcinkami (hgasm1/hgasm3), wiec czytamy
go ze strony zamiast wpisywac na sztywno.

Zweryfikowane z VPS: 206 na Range, ftypisom, 198 MB, dziala BEZ Referera i bez tokenu,
wiec URL nie wygasa. mobile_direct_ok.

Pilot: seen 107, new 107, errors 0. Metadane: 100 procent z data, miniaturka i tagami.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 14:57:28 +02:00
goon-foss
7a8e10c175 feat(hentai): konektor xanimeporn.com - drugie zrodlo wertykalu
NIE jest re-hostem hentaimamy i to bylo pierwsze, co sprawdzilem. Wspolny odcinek
(Shoujo Ramune 7) lezy na obu stronach, ale to zupelnie inne pliki: hentaimama serwuje
gdvid.info/S/shoujo-ramune-7.mp4 w jednej jakosci bez etykiety, a tutaj jest
download.xanimeporn.com z jawnym wyborem 1080p (222 MB) i 720p (84 MB).

Listing idzie z RSS-a i to jedyna droga, ktora dziala. Sprawdzone trzy inne:
- /page/2/ i /page/3/ oddaja ten sam zestaw co strona 1 (28 z 32 wspolnych),
  czyli paginacja zepsuta jak przy 8kporner
- /uncensored/ i /censored/ stronicuja poprawnie, ale NIE sa chronologiczne: pierwsze
  pozycje z 2024, zakres 2015-2026. Browse-latest nigdy nie zobaczylby nowego odcinka,
  czyli pulapka z freshporno. Pierwsza wersja konektora wlasnie tak dzialala i dopiero
  test na danych to pokazal
- /hentai-list/ ma caly katalog (1048) na jednej stronie, ale nie jest chronologiczny

Drugi filtr tez wymuszony przez dane: slugi gatunkow (/futanari/, /big-tits/) sa takimi
samymi slugami najwyzszego poziomu jak odcinki i wchodzily jako pozycje bez daty i
miniaturki. _parse_detail wymaga teraz postid w klasie body, ktory maja tylko
pojedyncze wpisy. Ten sam identyfikator jest potrzebny extractorowi.

Playback: Fluid Player z PUSTYM <source src=''>, wideo wstrzykiwane w runtime, wiec w
HTML nie ma zadnego linku. Wyjsciem jest zakladka Downloads:
videos.xanimeporn.com/download.php?id=<postId>&quality=. Oddajemy download.php, NIE
docelowy plik, zeby token generowal sie przy odtwarzaniu i nie wietrzal (lekcja z
watchporn). Bez Cloudflare i bez proxy, w odroznieniu od hentaimamy.

Pilot: seen 50, new 50, errors 0. Metadane: 100 procent z data, miniaturka, kategoria
i seria jako tagi.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 14:48:13 +02:00
goon-foss
85ee42d5a3 feat(hentai): konektor hentaimama.io - pierwsze zrodlo wertykalu hentai
Jednostka tresci to ODCINEK (/episodes/<seria>-episode-N/), mapowany na scene tak samo
jak w wertykale JAV, bez zmian w schemacie. Seria ladue jako tag, wiec odcinki daja sie
grupowac.

KRYTERIUM JEST TU INNE I TO CELOWE. Dla animacji nie istnieje kanon - TPDB i StashDB
nie maja rysowanych postaci - wiec kazda scena stad jest technicznie orphanem i to
jest POPRAWNE. Nie stosujemy ani bramki na obsade (nie ma obsady), ani miary canonical
match, ktora sluzyla nam do oceny tubow z zywymi aktorami. Jakosc mierzymy kompletem
seria + odcinek + gatunki.

Motyw jest z rodziny Dooplay, ale DooplayConnector NIE pasuje: brak data-fl-source i
data-post, na ktorych stoi tamten parser. Player idzie w trzech krokach: id posta ze
strony odcinka, POST /wp-admin/admin-ajax.php z action=get_player_contents, potem
strona wlasnego playera, ktora oddaje bezposredni mp4. Sam POST jest za Cloudflare
(GET-y przechodza), wiec wymaga Bright Data, dokladnie jak POST /api/video-info w sexu.

Playback najlepszy z mozliwych: preferujemy gdvid.info, bo oddaje plik BEZ tokenu,
wiec URL nie wygasa. Zweryfikowane z VPS: 206 na Range, ftypisom (faststart), dziala
BEZ Referera, stad mobile_direct_ok.

Pulapka obeszla: /genre/ w calym HTML to 118 linkow (chmura w sidebarze, ten sam wzorzec
co przy sexu i yourdailypornmovies). Gatunki bierzemy tylko z div.sgeneros, co daje 5-10
realnych pozycji na odcinek.

Pilot: seen 90, new 90, errors 0. W bazie 90 odcinkow, 100 procent z data i tagami,
zakres 2025-12-29 do 2026-07-31.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 13:35:10 +02:00
goon-foss
a4486980a4 style: myslniki em/en z komentarzy i docstringow (calosc repo)
1745 wystapien w 291 plikach (backend, scripts, mobile). Dominowal jeden ksztalt,
' — ' laczace zdania, wiec poszedl przecinek; myslnik otwierajacy mysl zdjety;
zakresy 0–5 i A–Z na dywiz.

Podzial komentarz/kod robil skaner stanow, nie regex, zeby nie ruszyc myslnika
stojacego w stringu albo w wyrazeniu regularnym. Potwierdzone maszynowo: po wycieciu
komentarzy z wersji HEAD i z dysku obie sa identyczne we wszystkich 291 plikach,
czyli poza komentarzami nie zmienilo sie nic. 233 pliki .py parsuja sie bez bledu,
tsc ma te same 11 bledow w tych samych 3 plikach co przed zmiana.

Dwie rzeczy wymagaly poprawki po automacie: wyrownane listy definicji, gdzie myslnik
byl separatorem kolumny (37 miejsc, kolumna przywrocona), i trzy przeniesienia mysli
do nowej linii, gdzie zostawal wiszacy przecinek na poczatku (poprawione recznie).

Bundla nie republikuje: Hermes i tak nie niesie komentarzy, wiec dla uzytkownika
to zero zmiany.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 11:51:57 +02:00
goon-foss
635017c993 release: /version na 0.2.2
Wgrane razem z APK. Bez tego stary dialog Update available wyskakuje z mylacym
Server 0.2.1 / App 0.2.2 (bundle OTA niesie app.json, wiec APP_VERSION raportuje
juz 0.2.2 nawet na starym APK).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 09:57:48 +02:00
goon-foss
72b7b561e5 fix(thumbs): odblokuj miniaturki fullporner (atrapa byla przejsciowa)
Pomiar na 300 losowych URL-ach z bazy: 298 prawdziwych JPEG-ow (5-25 kB),
tak samo z VPS jak i z lacza domowego. Wpis w _is_rotting_thumb zerowal
miniature w SceneDetail, wiec sceny majace tylko fullporner traciły ja
calkowicie (53 tys. zrodel).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 09:10:13 +02:00
goon-foss
4fd94de72d fix: cofnij obietnice keep-awake (modul nie jest w APK) + martwe miniatury fastpic
Some checks are pending
Backend tests / test (push) Waiting to run
1) Changelog obiecywal 'screen no longer turns off', ale to NIE dziala. Audyt APK
v0.2.1: nazwa 'ExpoKeepAwake' NIE wystepuje w zadnym classes*.dex - jest tylko
KeepAwakeManager z expo-modules-core (wewnetrzny interfejs). Czyli expo-keep-awake
nie zostal wkompilowany, requireNativeModule rzuca, a moj try/catch cicho polyka
blad. Blad w moim wczesniejszym rozumowaniu: obecnosc w node_modules/expo/
node_modules NIE oznacza, ze autolinking wciagnal modul do konkretnego builda.
Keep-awake WYMAGA nowego APK (OTA dowozi tylko JS), wiec wpis usuniety zamiast
obiecywac cos, czego nie ma. Zgloszenie 9d5618dd.

2) fastpic.org (galaxyporn) zrywa polaczenie zamiast oddac obraz -> dopisany do
_is_rotting_thumb. Bonus: scena bez miniatury odpala w apce auto-enrich, ktory
sciaga swieza ze strony tube'a. Zgloszenie c2f1dd41, 240 z 20213 zrodel.
2026-08-05 21:58:06 +02:00
goon-foss
81f0074d34 fix(vjav): bramka jakosci tytulu + wlasna iteracja stron
Po naprawie dostepu vjav ruszyl, ale zaczal sypac smieciem: pomiar na 295 scenach z
doby po fixie dal 78,6 proc. tytulow slug-concat i ZERO przypisanej obsady. Takie
sceny sa w apce nieodnajdywalne - nie maja ani tytulu, ani performera.

Bramka odrzuca cztery wzorce: prefiks id_JAV, hash x1x..., kod typu
QCT062-KPUDYLMLBL913295279 oraz ciagi bez samoglosek/spacji (walniecie w klawiature).
Zmierzone na probce 6000 tytulow: odrzuca 80 proc. swiezych i 27 proc. starych, przy
39 przepuszczonych na 200 obejrzanych - zrodlo nie jest wyzerowane.

WAZNE, znalezione przy pomiarze pierwszej wersji: str.isalpha() jest prawdziwe dla
kana i kanji, a japonski nie stawia spacji, wiec reguly "za malo samoglosek" i "brak
spacji" odrzucalyby PRAWDZIWE tytuly na serwisie JAV - 708 z 708 tytulow CJK z probki.
Stad jawny wyjatek _has_cjk. Kontrola jednostkowa: 8/8 przypadkow, w tym dwa CJK.

Drugi blad, wprowadzony przez sama bramke i zlapany dopiero pilotem: strona 1 jest w
100 proc. smieciowa, wiec po odsianiu zwracala [], a bazowe latest_scenes traktuje
pusta strone jako koniec katalogu i konczylo caly run. Zrodlo dawalo seen: 0 mimo 39
dobrych scen na stronach 2-5. Wlasna iteracja rozstrzyga wyczerpanie po dlugosci listy
id, nie po liczbie scen po filtrze. To ta sama pulapka co w _load_ids.

Pilot po obu poprawkach: seen 39 (wszystkie skipped - weszly przed bramka).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 14:25:00 +02:00
goon-foss
6199577ae7 revert(watchdog): usuniecie integracji ze Slackiem
Na zyczenie uzytkownika. Alerty zostaja wylacznie w Sentry - z eskalacja poziomu i
kubelkami wieku w fingerprincie z poprzedniego commita, wiec sama poprawa
powiadamiania zostaje nienaruszona.

Usuniete: app/notify/ (caly pakiet), job watchdog-digest, parametr to_slack w
run_ingest_freshness_watchdog oraz klucze konfiguracji sched_watchdog_digest_hours,
slack_bot_token i slack_channel. Zadna wartosc SLACK nigdy nie trafila do .env ani do
compose, wiec nic nie bylo wysylane.

Po usunieciu watchdog dalej sprawdza 41 zrodel (sceny + filmy), scheduler rejestruje
juz tylko ingest-watchdog.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 15:12:17 +02:00
goon-foss
6e056b81c2 feat(watchdog): pokrycie filmow, eskalacja poziomu i dobowy digest na Slacka
Watchdog dzialal poprawnie - vjav i superporn wypisywal co 6h przez caly czas ich
ciszy. Zawiodlo POWIADOMIENIE, w trzech miejscach naraz.

1. Filmy nie byly pokryte w ogole. Watchdog skanowal tylko origins tube:<sitetag> ze
scen, wiec streamporn.vip stal 23 dni i zaden automat nie mial jak tego zauwazyc.
Doszlo 6 konektorow filmowych (35 -> 41 sprawdzanych zrodel), prog 72h. Zweryfikowane
przez celowe obnizenie progu do 1h: wszystkie 6 matchuje realne liczby pozycji, a nie
zwraca cicho zera - bo to dokladnie ta klasa bledu, ktora naprawiamy.

2. Stabilny fingerprint per origin tworzyl JEDNO issue przy pierwszym wystapieniu i
potem tylko licznik. Sentry powiadamia o nowych i regresjach, nie o kolejnych
wystapieniach otwartego issue. Teraz fingerprint zawiera kubelek wieku (2d+/7d+/30d+),
wiec przekroczenie kazdego progu zaklada nowe issue, ale w obrebie kubelka nadal nie
ma spamu co 6h.

3. Poziom byl zawsze warning, a reguly alertow celuja w error. Od 7 dni ciszy idzie
error. Sprawdzone: vjav i superporn eskaluja teraz do error, pornbusy/youperv/porndish
zostaja na warning.

Plus kanal, ktory czlowiek realnie czyta: dobowy digest na Slacka (osobny job, zeby
nie wysylac tej samej listy 4x dziennie). Domyslnie NO-OP - bez GOON_SLACK_BOT_TOKEN
i GOON_SLACK_CHANNEL nic nie probuje wysylac, kanalu nie zgadujemy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 15:03:27 +02:00
goon-foss
532c7e2bb4 fix(vjav): 429 parsowany jako XML, zrodlo stalo 12 dni bez zadnego bledu
Audyt po fixie streamporn.vip. vjav (77 tys. zrodel) nie dodal nic od 2026-07-22 i
NIE zglaszal bledu - crawl_page oddawal 0 scen, licznik pokazywal errors: 0.

Przyczyna: vjav odcial IP VPS-a. Sprawdzone 2026-08-03 - sitemap, strona glowna i
/latest-updates/ daja 429 przy trzech probach z rzedu, a przez Bright Data 200 od
pierwszej. Kod tego nie widzial, bo browser_get NIE rzuca na 4xx, wiec 343-bajtowa
tresc bledu byla parsowana jako XML: zero sitemap, zero id.

Drugi blad, ktory to ukryl: przy niepowodzeniu _load_ids ustawialo _sorted_ids = [],
a crawl_page tlumaczy [] na "koniec katalogu" (poprawny stan), nie na awarie. Teraz
przy bledzie zostaje None, ktore crawl_page zwraca jako transient-fail.

Fix: proxy Bright Data na sitemap i API metadanych (ten sam host, ten sam 429), jawne
sprawdzanie statusu, [] tylko dla realnie pustego katalogu.

Po fixie crawl_page oddaje 120 scen zamiast 0. Nowej podazy to jeszcze nie dalo
(wszystkie 120 to pozycje sprzed blokady, skipped na niezmienionym hashu) - sitemap
vjav nie przesunal sie od czasu odciecia. Do obserwacji. Uwaga na jakosc: w tej
partii 58 proc. tytulow to slug-concat typu 0008363_JAV_..., przy 2,9 proc. w calym
katalogu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 14:36:25 +02:00
goon-foss
3f8f38202a fix(movies): streamporn.vip czytal zly listing, stal od 23 dni
Zrodlo nie dodalo nic nowego od 2026-07-11. Strona jednak ZYLA, a konektor parsowal
poprawnie - problem byl w tym, ze `/movies/` na tym motywie NIE jest sortowane po
dacie i oddaje stary katalog. Zmierzone na tych samych 8 pozycjach: `/movies/` dalo
roczniki 2012-2015, strona glowna wylacznie 2026, po 10-11 zrodel playbacku kazda.
`?orderby=date` motyw ignoruje (odpowiedz identyczna z domyslna).

To ta sama klasa bledu co przy freshporno: wlasciwa strona, zly endpoint listingu.
Diagnoza po licznikach per zrodlo (ostatni nowy film + nowe w 30d/7d), nie po tym,
czy konektor rzuca wyjatkiem - bo nie rzucal.

Fix: `_listing_path` na `/` + `/page/N/`. Strony 1 i 2 wspoldziela ~44 linki
(sidebar/widgety), ale dedup po URL w fetch_movies je odsiewa.

Pilot po zmianie: seen 40, new 18, updated 10, skipped 12, errors 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 10:56:13 +02:00
goon-foss
c586a8ad32 feat(movies): konektor yourdailypornmovies.ws
Sprawdzony NA DUPLIKAT przed budowa, bo poprzedni kandydat (speedporn.net) okazal sie
kolejna nakladka na pandanetwork.club - 49/49 miniaturek z tego samego hosta co nasze
pandamovies, 0 nowych filmow. Tutaj z 40 pozycji ze strony glownej 13 mielismy po
tytule, 9 po id produktu Adult Empire, a 18 bylo nowych. Inna pula tresci: okladki DVD
z imgs1cdn.adultempire.com, nie re-hosty.

Pilot na 40: seen 40, new 22, updated 18, errors 0. W bazie 36 filmow, z tego 34 z
obsada, 36 ze studiem, 14 dopielo sie do pozycji, ktore juz mielismy.

WordPress z wlasnym motywem, wiec nie da sie podpiac pod DooplayConnector.

Pulapka, ktora trzeba bylo obejsc: /tag/ w calym HTML to 2177 linkow, czyli chmura
tagow w sidebarze (ten sam wzorzec co przy sexu). Obsada, tagi i studio czytane
WYLACZNIE z blokow div.xmll - efekt to 5-14 tagow na film zamiast 2177.

Druga rzecz: /director/ trzyma w praktyce STUDIO (New Sensations, VIXEN, Zero
Tolerance Films), nie rezysera. Bierzemy to jako studio, bo tak jest uzyte.

Playback: voe i mixdrop maja gotowe moduly hosterow i zweryfikowalem, ze resolwuja
(voe m3u8, mixdrop mp4). vidara.to nieznana, leci jako zwykly embed do WebView.
Katalog min. 8000 pozycji, siega 2003. Brak dlugosci filmu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 10:38:18 +02:00