Od ~15.09 nowe karty maja okladke imgs4cdn.adultempire.com/movie/<id>?w=... (czesc
i.ibb.co albo bez okladki), a regex karty wymagal starego products/NN/<id>h.jpg.
33 z 40 filmow strony 1 odpadalo po cichu, ingest przez tydzien: 0 nowych.
Okladka teraz opcjonalna i w dowolnym formacie, id Adult Empire z obu wariantow.
Nadrobione: 26 nowych filmow, 6 dopietych do istniejacych.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Planer szacowal kazda fraze na 427 trafien (histogram 100 probek, dolny limit), wiec
zawsze szedl indeksem trigramow i sortowal wszystkie trafienia: "vo" 44 s (dwie
litery nie maja trigramu, indeks oddaje 4,3 mln wierszy), "mis" 6,5 s, "free" 1,9 s
(GOON-73/75).
- 0046: histogram title_normalized 1000 probek, szacunki bliskie prawdy.
- list_scenes: przy q i sorcie po dacie najpierw przejscie po indeksie sortu z
limitem 300 ms (bez bitmap, w SAVEPOINT wycofywanym zawsze), gdy probka tytulow
z pg_stats mowi, ze wystarczy przejsc do 30 tys. scen; inaczej zwykly plan.
Frazy bez trigramu zawsze przejsciem (limit 3 s, potem pusto).
115 prawdziwych wyszukiwan z logow: wyniki identyczne, najgorszy 44 s -> 0,8 s,
srednie frazy dotykaja 3-7x mniej stron ("bad" 122 tys. -> 16 tys.).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blacklisty sa per urzadzenie od 2026-06-10, a SEO dalej wycinalo sume blacklist
wszystkich urzadzen: 465 osob, 4477 tagow, z publicznych stron znikalo ~86% scen.
To samo zapytanie przy liczeniu do /sitemap.xml pisalo 3,7 GB plikow tymczasowych
i przy kilku wejsciach robota naraz zapychalo dysk (GOON-22). Teraz strony SEO
pokazuja to, co katalog nowemu urzadzeniu, a indeks sitemapy liczy sie raz na 6 h
(blokada na rownolegle zadania). Liczenie 135 MB plikow tymczasowych, indeks 13 s,
potem 0,2 s. Wykonawcy 20 tys. -> 81 tys., sceny 3,5 mln.
Na VPS dodatkowo temp_file_limit=2GB dla API w override.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
toList() na values ConcurrentHashMap przy rozmiarze 1 robi iterator().next(); gdy
sesja zniknie miedzy size() i next(), leci NoSuchElementException (0.4.2, GOON-72).
ArrayList(values) idzie przez toArray(), ktore mapa robi bezpiecznie. Natywne,
czeka na nastepne APK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
source-stats liczyl flagi tag/obsada dla 2,5 mln par serwis-scena, czyli ok. 5 mln
losowych odczytow indeksow; trwal 22-32 min i przekroczyl limit (GOON-V). Teraz
flagi z probki 3000 scen na serwis (stala, po md5), liczba scen, swiezosc i
miniatury dalej dokladnie. 1 min 51 s, gwiazdki bez zmian, procenty +-2 pkt.
Autovacuum na domyslnych 20% nie ruszal duzych tabel od tygodni (scene_performers
11% stron widocznych, statystyki scenes z 25.08). Migracja 0045 daje 2% dla
szesciu najwiekszych tabel.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Przebieg nadrabiajacy zaleglosci scalil 67 tys. scen (xnxx/xvideos, ten sam tytul, dlugosc
i obsada) i trwal 90 min, wiec przy limicie 30 min job raportowal sie jako zawieszony
(Sentry GOON-V), mimo ze pracowal. Zaleglosc wzieła sie z restartow workera, ktore ucinaly
wczesniejsze przebiegi.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"Trust anchor for certification path not found" lapal sie na "not found", wiec
odtworzenia eporner z bledem SSL szly jako "gone" (93 w tydzien): zly komunikat i zla
telemetria. Wejdzie z najblizsza paczka OTA.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Oba serwisy kasuja filmy po cichu: strona odpowiada 200 z "Post Not Found" albo "Video has
been deleted". Probka 2026-09-19: 57% zywych w bazie zrodel sxyprn w wieku 10-40 dni i 22%
eporner bylo juz usunietych; w apce to puste kafelki i "the tube removed" po kliknieciu.
- eporner: ekstraktor rozpoznaje usunieta strone i rzuca HosterDead, wiec resolve oznacza
zrodlo zamiast oddawac "blad chwilowy" (82 takie wejscia w 48 h, nic nie oznaczal).
- proxy miniatur: "Post Not Found" na sxyprn oznacza zrodlo od razu, 404 na miniaturze
eporner uruchamia w tle sprawdzenie strony (28/30 takich miniatur to usuniete filmy).
Indeks hash po thumbnail_url tylko dla eporner (0044), zeby znalezc zrodlo po obrazku.
- job dead-reap co 6 h: po 1500 zywych zrodel na serwis, polowa z ostatnich 30 dni.
Oznacza tylko przy pewnym sygnale; siec i timeouty zostawia.
Sprawdzone na produkcji: 10/10 miniatur eporner i 23/23 postow sxyprn oznaczone, 17 zywych
postow nietknietych.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"Newest ingest" bez filtrow pomija sceny z dociagania archiwum (backfill): deep-crawl
tubepornclassic dokladal 7,9 tys. scen z lat 2016-2018 dziennie, a xhamster/xnxx/xvideos/
sxyprn kolejne 3,3 tys., wszystkie na szczycie listy. Po odcieciu eporner (2 tys. anonimowych
uploadow dziennie) mial 121 ze 150 pozycji, wiec na pierwszych 8 stronach jedno zrodlo zajmuje
najwyzej 1/3 strony, dopoki sa inne; nadmiar zjezdza nizej, nic nie ginie. Pierwsze 3 strony:
eporner 51, xvideos 24, xnxx 20, youporn 20, pornxpph 15, fullporner 12.
Z filtrami i w sekcjach JAV/Anime bez zmian.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- scheduler: misfire_grace_time 1 h zamiast domyslnej 1 s. O 05:00 UTC startuje kilkanascie
zadan naraz, movie-ingest dostawal watek 1,1 s po czasie i APScheduler go pomijal, wiec
filmy nie przychodzily od 17.09 (watchdog, Sentry).
- getDeviceId: blad SecureStore ("Could not encrypt the value", Samsung A7, Android 10)
wywalal kazde zapytanie do API. Teraz id zostaje w pamieci do konca sesji. Wejdzie z
najblizsza paczka OTA.
- latka expo-modules-core 2.2.3, JNIDeallocator: watek sprzatajacy blokowal sie na sobie,
nie na deallocatorze, stad ConcurrentModificationException przy przeladowaniu JS
(Sentry GOON-48). Wejdzie z najblizszym APK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Z dwoma tagami (rough-sex + anal) lista szla stara droga po calym katalogu, 7,4 s na zimnym
cache. Teraz dolaczamy najrzadszy tag po ix_scene_tags_tag_sort, a reszta zostaje jako
EXISTS: 0,2 s. Dolaczona tabela ma alias, inaczej EXISTS po scene_tags korelowal sie z nia.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ekran tagu (jeden tag, sort=release_date, 200 scen) sortowal po dacie z `scenes`, a filtrowal
po `scene_tags`. Postgres szedl od najnowszej sceny calego katalogu i kazda sprawdzal; przy
tagach rzedu 40-60 tys. scen (`rough-sex`) to 46 tys. scen na strone, 7-15 s na zimnym cache.
Dwie przebudowy samego zapytania nie pomogly (2x albo 30 s na duzych tagach), cache tez nie,
bo wejscia rozkladaja sie na setki tagow.
`scene_tags.sort_date` (0042) trzyma ta sama date co `_effective_date_desc()`, pilnowana przez
wyzwalacze w bazie, indeks (tag_id, sort_date DESC, scene_id DESC) w 0043. Wypelnianie 23 mln
wierszy: scripts/backfill_scene_tags_sort_date.py, partiami z pauza.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zasada "dluzszy tytul wygrywa" podmieniala czysty tytul kanoniczny na tubowy z doklejonym
studiem, obsada i data ("Milfy 26 09 16 Koda Monroe Voluptuous Therapist ..."). Pierwszy
przebieg studio_title_dedup zrobil tak z 491 scenami; tytuly przywrocone z external_records.
Teraz kanon wygrywa z tubem, a dluzszy tytul liczy sie tylko miedzy scenami tego samego rodzaju.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Kazdy tube zapisuje tytul po swojemu ("[Milfy] Koda Monroe (...)", "Milfy 26 09 16 ...",
"... 4K"), a miniatury sa z innych klatek, wiec ani phash, ani title_duration_dedup
(identyczny tytul) ich nie lapaly. Jedna scena Milfy wisiala w katalogu 8 razy.
Nowy job porownuje rdzen tytulu w obrebie studia: bez nazwy studia, dat, znacznikow
jakosci i nazwisk obsady. Numery czesci zostaja ("Part 1" to nie "Part 2"). Straznicy:
dlugosc, data premiery, wspolna obsada, dluzszy rdzen gdy brak dlugosci. Kopie bez studia
dolaczaja tylko przy zgodnej co do 3 s dlugosci. Kategorie wpisane przez tube jako obsada
nie skracaja rdzenia. Cyklicznie co 12 h z oknem 30 dni.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Latka z 0.4.1 kopiowala mape sesji przed zwolnieniem playerow, ale sama kopia
tez iteruje mape, a wpisy znikaja z innego watku. Na LinkedHashMap wywalalo sie
wiec dalej, juz w toList() (Sentry GOON-6W, Redmi Note 8 Pro, Android 11).
Mapa jest teraz ConcurrentHashMap, iteracja przezyje rownolegle usuniecie.
versionCode 16 zeby posiadacze 0.4.0/0.4.1 dostali monit: runtime zostaje 1.4,
wiec sam numer kanalu ich nie rozrozni.
Sprawdzone na emulatorze: dwie sesje mediow zywe, zamkniecie z listy ostatnich
zwalnia obie, pusty bufor crashy.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Agregat po 4,1 mln zywych zrodel trwa 0,6-2 s, a cache wygasal co 5 minut, wiec co
wygasniecie ktos placil pelnym czasem (Sentry Slow DB Query list_sources, 186 zdarzen,
ostatnie dzisiaj). Teraz po wygasnieciu oddajemy stary wynik i przeliczamy w watku w tle,
a TTL idzie z 5 do 15 minut. Liczby zmieniaja sie o promile na godzine.
Pomiar na prodzie: pierwsze wejscie po restarcie 2,1 s (nieuniknione), potem 11-15 ms,
a wejscie tuz po wygasnieciu 38 ms zamiast pelnego przeliczenia.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Prosba z apki 2026-09-16 („make a tv app of this"). Tania wersja: to samo APK,
zeby dalo sie je zainstalowac, znalezc w launcherze telewizora i obslugiwac pilotem
w istniejacym interfejsie. Pelnego interfejsu 10-stopowego (podswietlenie fokusu,
wieksze napisy, obejscie WebView przy hosterach) to NIE daje.
- uses-feature leanback i touchscreen jako NIEwymagane, plus jawne
screen.portrait=false: blokada pionu sama z siebie dokladala WYMAGANIE ekranu
pionowego i telewizor uznawal apke za niezgodna
- osobne wejscie TvMainActivity z LEANBACK_LAUNCHER, bez blokady pionu
(na telefonie nic sie nie zmienia, launcher TV pyta tylko o leanback)
- banner 320x180 w res/drawable (res/drawable-*/ jest w .gitignore)
Dwie slepe uliczki, stad osobna klasa: `setRequestedOrientation` w onCreate to zmiana
konfiguracji, wiec system relaunchowal aktywnosc i na TV zostawal bialy ekran (widok
Reacta nie wracal); orientacja z values-television nie przechodzi, bo manifest czyta
zasoby bez konfiguracji (lint ManifestResource).
Sprawdzone na emulatorze android-34 android-tv (1920x1080): apka jest na liscie
leanback launchera, startuje na caly ekran poziomo, a pilotem da sie przejsc bramke
wieku (fokus chodzi po elementach, CENTER zaznacza), pominac samouczek i przewijac
siatke scen. Odtwarzania na TV nie testowalem, emulator ma software'owe kodeki.
Wersji APK nie ruszam, zmiana pojedzie z najblizszym wydaniem.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zgloszenia z apki:
- „random filter on and searching titles shows few results": przy sort=random braliśmy
okno 2000 kolejnych id (0,05% katalogu) i dopiero na nim nakladalismy filtry, wiec
szukanie w losowej kolejnosci trafialo na garstke scen. Teraz przy aktywnym filtrze
(szukanie, tag, obsada, studio, strona, jakosc, data, dlugosc) losujemy WYNIKI:
md5(id + seed) nad pula do 5000 wynikow filtra. Okno po PK zostaje tylko dla listy
bez filtra, gdzie chronilo przed skanem 2,3 mln wierszy.
- „clicking install does nothing": pobieranie 87 MB szlo bez zadnego sladu w UI. Teraz
nakladka z kreceleem na czas pobierania, „Download" obok „Install" w monicie i link
do pliku w komunikacie bledu (na repo git APK nie ma, user szukal go tam).
Sprawdzone: szukanie „massage" z sort=random daje pelne strony (50 + kolejna), ten sam
seed powtarza kolejnosc, strony sie nie nakladaja, inny seed inna kolejnosc; czasy 120-800
ms (tag anal 1,1 s), lista bez filtra bez zmian. Na emulatorze pelna sciezka aktualizacji
z 0.4.0: monit z trzema przyciskami, Install, pobieranie, systemowy dialog, versionCode 15.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zgloszenie Jana (fold): rozlozony ekran jest prawie kwadratowy, a klip byl skalowany do
wypelnienia i zostawal z niego srodek. Teraz liczymy, ile by sie ucielo: do 30 % zostaje
wypelnienie (pionowy klip na zwyklym telefonie traci ok. 20 % szerokosci i to jest OK),
powyzej cale wideo i czarne pasy. Podpis i kolumna przyciskow stoja przy krawedziach
ekranu, wiec przy pasach same wchodza na pasy zamiast na wideo. Poster pod wideo dostaje
to samo kadrowanie, zeby nie mrugalo przy starcie.
Zysk takze na zwyklym telefonie: ok. 19 % klipow RedGifs jest poziomych i do tej pory byly
rozdmuchane na caly ekran.
Zmierzone na emulatorze przez rozmiar powierzchni wideo (dumpsys activity top):
- telefon 1080x2400: pionowy klip 1242x2209 (wypelnienie, jak dotad), poziomy 1080x607
i klip 3:4 1080x1440 (pasy zamiast kadrowania)
- rozlozony fold 1768x2208: pionowy klip 1140x1947 z pasami po 314 px, poziomy 1768x1298
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zgloszenia Jana 2026-09-16:
1+3. Tapniecie serduszka przelaczalo dzwiek i przewijalo klip na poczatek. Gesty lapala
cala komorka razem z przyciskami, wiec tap w serduszko byl tez tapem w ekran, a zmiana
dzwieku restartowala odtwarzanie (efekt aktywacji strony mial soundOn w zaleznosciach).
Teraz gesty lapie tylko warstwa wideo, a wyciszenie ma osobny efekt.
2. Dwa przyciski dzwieku. Zostaje ten w kolumnie przy kciuku, w gornym pasku wchodzi stroik.
4. Za malo tagow na starcie: bylo 24 z 40, „anal" (27. co do liczby klipow) wypadal.
Teraz 60 tagow + nisze + szukanie po calym slowniku (1,7 tys. tagow, nowy param q),
wskazanie wazy 8 zamiast 5, a stroik mozna otworzyc w kazdej chwili i zmiana dziala
od nastepnego rozdania.
5. Losowe miganie przy przewijaniu: dociagniecie kolejnej strony feedu podmienialo tablice
klipow i restartowalo biezacy klip. Efekt zalezy teraz od numeru strony i adresow wideo.
Sprawdzone na emulatorze: tap w serduszko zostawia wyciszenie bez zmian i zapisuje like,
przycisk dzwieku odcisza, gorny pasek otwiera stroik, szukanie „anal" daje 8 wariantow,
a po Apply w clip_affinity siedzi anal=8.0. Edge dalej odklada zdarzenia w clip_feed_events.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Regula sklejki sasiednich czlonow (JoannaAngel, Bonnieb) nie byla pilnowana na
granicy obsady: przy martwym separatorze "Dickft" i "Paigefeat" wychodzily jako
trafienia. Trzy przypadki, ktore na starym regexie daly True, a teraz daja False.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Tapniecie nazwy tworcy otwiera jego strone: siatka wszystkich klipow, a tapniecie
kafelka gra je na pelnym ekranie z tym samym przewijaniem w pionie co Edge.
Zgloszenie z apki 2026-09-15: "cannot tap username as it's hidden behind icon tray".
- ClipPager: pionowy pager z dwoma playerami wyjety ze SwipeScreen, wspolny dla Edge
i strony tworcy; feed, telemetria i autoSwipe zostaly w ekranach
- /clips?creator= oddaje `total` (liczba klipow tworcy) do naglowka
- ze strony tworcy leca tylko like/unlike i "nie interesuje": ogladanie stad nie moze
zabetonowac feedu na jednym tworcy
Sprawdzone na emulatorze: link z Edge otwiera strone (@lilylovesyou2, 2 clips, verified),
kafelki trzymaja trzecia szerokosci takze w niepelnym rzedzie, pelny ekran gra i zamyka
sie przyciskiem pod paskiem stanu, a Edge dalej odklada zdarzenia w clip_feed_events.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0.4.0 i 0.4.1 maja ten sam runtime 1.4, a monit porownywal tylko runtime, wiec nikt
z 0.4.0 nie dostal propozycji aktualizacji i crash expo-video przy zamykaniu z ostatnich
wracal do Sentry dzien po poprawce (147164135).
- /version oddaje apk_build (versionCode 15)
- aplikacja czyta versionCode ZAINSTALOWANEGO APK przez natywny modul Sentry
(expo-constants w SDK 52 nie oddaje go wcale, expo-application wymagalby nowego APK)
- numer builda trafia tez do kontekstu zgloszen z apki: app_version jedzie z paczka OTA,
wiec nie mowil, ktore wydanie natywne ma zglaszajacy
Sprawdzone na emulatorze: 0.4.1 nie dostaje monitu i raportuje build=15, po instalacji
0.4.0 monit "Update available" pokazuje sie przy starcie.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Trzy zmiany wokol listy scen z filtrem originu, gdzie kandydatow sa dziesiatki tysiecy.
1. Kolejnosc czlonow OR w stub_exclusion_clause. Postgres liczy OR po kolei i przerywa na
pierwszym trafieniu, a sam czlonow nie przestawia. "Ma kanon" (jedyny czlon z JOIN-em do
sources) stal przed tanszym "ma performera", wiec placilismy za niego takze za sceny,
ktore performera mialy. Po zamianie ten czlon liczy sie 5146 razy zamiast 16 191.
2. Indeks scene_external_refs (scene_id, source_id), migracja 0041. Podzapytanie "ma
kanon" dociagalo source_id z heapu, bo stary indeks zna tylko scene_id. Teraz idzie
Index Only Scanem: Heap Fetches 16 191 -> 1241.
Razem: sort=title + origin=hqporner, strona 5 czyta 251 tys. blokow zamiast 294 tys.,
a na rozgrzanym cache trwa 305 ms zamiast 371 ms (mediana z 3 rund z rotowana
kolejnoscia). Zysk jest skromny. Pierwsze wykonanie na zimnym cache trwa 3-5 s i tak
zostaje, bo trzeba dotknac ~2 GB; sprawdzilem tez wariant z materializacja scen originu
i CTE, czyta wiecej blokow (302 tys.), wiec obecny plan zostaje.
3. has_playback=false RAZEM z filtrem originu to warunek sprzeczny, bo origin wymaga
zrodla z dead_at IS NULL. Wynik jest pusty z definicji, ale Postgres przemielal caly
katalog, zeby to stwierdzic: 148 s. Teraz zwarte na false(), 4,8 ms, dalej zero wynikow.
Przy has_playback=true z originem pomijamy z kolei nadmiarowe EXISTS o zywym playbacku,
bo origin sam go wymaga, a kosztowalo sonde na kazdym kandydacie.
Wyniki bez zmian: strony 1-5 dla origin=hqporner i dla glownego feedu porownane pozycja
po pozycji ze stara wersja daja zero roznic, a sam predykat stub zgadza sie na probce
200 tys. scen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ix_scenes_title_created_id_desc zaczyna sie od tej samej kolumny, wiec obsluguje wszystko,
co obslugiwal stary indeks: lookupy `title_normalized = X` z resolvera i skan zakresu przy
sortowaniu po tytule. Trzymanie obu to 367 MB na dysku i jeden indeks wiecej do utrzymania
przy kazdym zapisie do scenes, a ingest pisze tam caly czas.
Sprawdzone na produkcji przez BEGIN; DROP INDEX; EXPLAIN ANALYZE; ROLLBACK, zeby zobaczyc
wybor planera bez starego indeksu, a potem jeszcze raz po samym dropie:
exact title lookup 1,76 ms -> 0,07 ms, Index Scan po nowym indeksie
OR studio + exact title ten sam ksztalt planu (BitmapOr), 3,7 ms
OR data + exact title Seq Scan przy szerokim oknie dat, ale to decyzja o release_date:
z enable_seqscan=off BitmapOr siega po nowy indeks
trgm ILIKE bez zmian, swoj indeks GIN
W wariancie z OR planer i tak siegal juz po nowy indeks, jeszcze zanim stary znikl.
Indeksy scenes: 3544 MB -> 3177 MB. Listy scen po dropie bez zmian (tytul 22-54 ms,
studio 38-73 ms na stronach 1-5).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Obie listy chodzily na produkcji w dziesiatkach sekund, bo klucz sortu nie mial nic
wspolnego z filtrami widocznosci (zywy playback, odsiew wertykalow, odsiew stubow).
sort=studio: nazwa studia siedzi w dolaczonej tabeli, wiec zaden indeks scen jej nie
zna i planer materializowal caly przefiltrowany katalog (ponad 2 mln wierszy), po czym
sortowal go w calosci. Odwracamy zapytanie: idziemy po studiach w kolejnosci nazwy i dla
kazdego dobieramy jego sceny przez LATERAL po ix_scenes_studio_effective_date_desc.
Zewnetrzny skan jest posortowany, wiec LIMIT urywa go po kilkunastu studiach. Sceny bez
studia dobiera osobny ogon, tak jak wczesniej robilo NULLS LAST. Przy filtrze po studiach
zawezamy tez sam skan studiow, inaczej szedlby przez wszystkie 33 tys.
sort=title: nowy indeks na cale ORDER BY (title_normalized, created_at DESC, id DESC).
Sam title_normalized zostawial Incremental Sort, a ten przed oddaniem pierwszego wiersza
musi zebrac caly kubelek scen o tym samym tytule.
Pomiary na produkcji (2026-09-16, ten sam zestaw filtrow, po rozgrzewce):
studio strona 1 483 s -> 41 ms
studio strona 5 ponad 5 min -> 38 ms
studio + tag blowjob 71 s -> 226 ms
studio + min_duration 48 s -> 42 ms
studio + studio_slugs 255 ms -> 44 ms
tytul strona 1 709 ms -> 12 ms (81 wpisow indeksu zamiast 3064)
tytul + tag blowjob ponad 90 s -> 1,5 s
Wynik jest identyczny co do wiersza: pierwsze 251 pozycji pelnego katalogu porownane
pozycja po pozycji ze starym zapytaniem daje zero roznic, tak samo dwa okna alfabetyczne
studiow (w tym Brazzers, zeby sprawdzic wewnetrzny LIMIT).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
W _PERSON_SEPARATOR_RE zamiast \b staly doslowne znaki 0x08 (heredoc przy
commicie b7a8911), wiec tytul nigdy nie byl ciety na feat/ft. Regex uzywa
teraz prawdziwych granic slowa, lapie tez "featuring", a myslniki podaje
jako escape zamiast doslownych znakow.
Skutek w danych sprawdzony na prodzie: 255 701 przypisan na scenach z
sxyprn, 6530 tytulow z feat/ft, stara i nowa regula roznia sie w 0
przypadkach, bo sam czlon feat/ft i tak przerywal sasiedztwo nazwiska.
Poprawka zamyka przypadki brzegowe (smieciowy performer "Feat").
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Opisy scen szly do bazy z `"`, `<br>` i surowymi `<br />`, a apka i strona
SEO pokazuja opis jako tekst, wiec bylo to widac doslownie. clean_description
dekoduje encje, `<br>` i koniec akapitu zamienia na nowa linie, a znane znaczniki
wycina (`<3` zostaje tekstem). Wpiete w normalize_scene i normalize_movie.
bulk_rescrape_hqporner.py i repair_truncated_titles.py liczyly title_normalized
jako lower(title), przez co 6005 scen mialo interpunkcje w kluczu dopasowania.
Oba licza teraz normalize() i dekoduja encje w tytule.
Skrypty: fix_html_entity_titles.py przemianowany na fix_html_entities.py z
przebiegiem po opisach; nowy fix_title_normalized.py przelicza klucz tam, gdzie
rozjechal sie z normalize(title).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xvideos (JSON-LD) i kilka innych tubow oddaje tytuly z encjami HTML5
(`we're`, `(AI)`), czasem podwojnie zakodowane. normalize
robil z nich slowa `apos`, `lpar`, wiec tytul nie trafial w wyszukiwarke
ani w kanon.
unescape_html w app/normalize/text.py dekoduje encje zakonczone srednikiem
po slowniku HTML5, do skutku (max 3 przebiegi). Wpiete w normalize_scene i
normalize_movie oraz w parsery xvideos_browse i pornxp. Skrypt
fix_html_entity_titles.py poprawia istniejace wiersze (title,
title_normalized, slug gdy byl wyliczony z tytulu).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- SegmentTabs w ui.tsx: zakladki w wierszu narzedzi obok ikon
- Ulubione, performerka, studio, Performers i Tags: jeden wiersz pod naglowkiem
zamiast trzech-czterech (etykieta z licznikiem, zakladki, podpowiedz, sortowanie)
- gwiazdka na ekranie performerki i studia bierze /favorites?counts=false
- Edge: kolejny klip chowa pasek, cofniecie pokazuje; podpis, przyciski i postep
jada razem z paskiem; FAB zgloszen ukryty, lezal na "Not interested"
- changelog 2026-09-15c/d
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- /favorites i /favorites/studios: liczniki w cache procesu (swiezy 5 min, potem
odswiezanie w tle), mark_seen zeruje od razu; parametr counts=false dla ekranow,
ktore chca tylko stan gwiazdki
- licznik studiow idzie indeksem ix_scenes_studio_effective_date_desc (migracja 0038)
i konczy po 200 scenach na studio: 10-25 s -> kilkanascie ms
- okno licznika sortuje tak jak lista (data premiery albo dzien dodania), wczesniej
rozjechane od 0033
- similar_scenes: pula z 4 najrzadszych tagow zamiast grupowania po wszystkich
(do 5 s -> ponizej 0,4 s)
- enrich-tags: tagi jednym zapytaniem po slugach i jeden INSERT
- /scene-favorites: serializer wsadowy
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- expo-file-system jako jawna zaleznosc: zagniezdzony pod expo nie byl autolinkowany,
ExpoAsset.downloadAsync padal na AppDirectories not found (Sentry 143555436)
- app/build.gradle: create*UpdatesResources zawsze generowane; zadanie mialo same napisy
jako wejscia i od 2026-05-31 osadzalo stary app.manifest (23 assety, bez fontu ikon)
- patch-package + patches/expo-video+2.0.6.patch: cleanup() iteruje po kopii mediaSessions
(ConcurrentModificationException w onTaskRemoved, Sentry 147164135)
- versionCode 15 / 0.4.1, runtime bez zmian (1.4), /version 0.4.1, linki na stronie
Test: czysta instalacja offline na emulatorze, 0.4.0 = 0 glifow ikon + blad w Sentry,
0.4.1 = 11 glifow i brak bledu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- /watch/recent: _build_scenes_out_batch(light) zamiast 5-7 zapytan na scene (N+1 w Sentry)
- /scenes?origin=tube❌ rownosc zamiast ILIKE '%...%', 4,6 s -> 1,1 s na hdporngg z q
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nazwa od edgingu: feed krotkich klipow bez konca (wybor Jana). W kodzie zostaje
Swipe (SwipeScreen, swipeTelemetry), etykieta i teksty user-facing to Edge.
Backend /version podaje 0.4.0 / 1.4, wiec starsze APK dostaja monit o nowej
wersji; plik app-release.apk podmieniany razem z publikacja.
Nowa zakladka w dolnym pasku: react-native-pager-view (pion, natywny snap), dwie
instancje createVideoPlayer (aktywna + nastepna w buforze), komorka z posterem,
podpisem tworcy i tagami, kolumna przyciskow, pasek postepu. Gesty bez reanimated:
tap = dzwiek, double-tap = ulubione z wybuchem serca i haptyka, przytrzymanie = 2x,
przesuniecie w lewo = arkusz "show less of this" (tworca / tagi / nisze / seen it,
plus blokada tworcy). Onboarding 3 tapow z top tagow, AutoSwipe (off/5/10 s),
licznik obejrzanych, nowe rozdanie.
Telemetria: SwipeTelemetry zbiera zdarzenia i wysyla paczki co 5 s / 10 zdarzen /
w tle; przy opuszczeniu strony impression z dwell, skip (<2 s) albo complete (petla
lub >=80%). Serwer z tego uczy wagi i uklada 80% nastepnych stron.
Pager to modul natywny, wiec import jest miekki (require w try/catch) i zakladka
pokazuje sie tylko od runtime 1.4; ten sam bundle leci OTA na 1.2/1.3 z wpisem
"pobierz 0.4.0" (onlyBelowRuntime), a wpis o Swipe ma nowe pole minRuntime.
Bump: app.json 0.4.0 / runtime 1.4, versionCode 14, AndroidManifest 1.4,
publish_update RUNTIME_DEFAULT 1.4, strona goon-foss.org pod 0.4.0.
Sprawdzone na emulatorze (APK 0.4.0): zakladka widoczna, onboarding zapisany na
serwerze, feed spersonalizowany 8/2, ExoPlayer dekoduje wideo i audio, swipe daje
zdarzenia complete/impression, double-tap daje like + ulubione + wagi.
Strona feedu spadla z 310-470 ms do 50-130 ms (srednio 85 ms na 30 stronach,
0 powtorek). Postgres nie ma max(uuid): koniec okna liczony po rzutowaniu na
tekst (ten sam porzadek dla malych hex w stalym formacie).
Pierwszy backfill po niszach przy ~3 zapytaniach/s po ~65 zapytaniach wpadl
w trwale 429 (cialo: delay 1167 s, subject per IP i endpoint) i przemielil
40 kolejnych nisz w bledach. Teraz: 1/s, odstep z Retry-After albo
error.delay, powyzej 5 min RateLimited i koniec przebiegu (wznowienie --skip).
Nowy wertykal krotkich pionowych klipow tworcow, osobno od scen: inne kolumny
(tworca, audio, lajki, nisze), inny cykl zycia, inna taksonomia, brak filtra
60 s. Tabele `clips` (unikalne source+source_id) i `clip_tags` z indeksem
(tag, clip_id) pod skan po tagu od losowego uuid w przyszlym feedzie.
Zrodlo nr 1: RedGifs, oficjalne API v2 z tokenem tymczasowym (zwiazany z IP
i UA, na 401 odnowienie). Globalne `order=latest` bez search_text daje ~100
na strone, kazde zapytanie widzi maks. 10 000 wynikow, wiec katalog chodzi
sie po niszach (skrypt backfillu). Pliki media.redgifs.com sa publiczne i bez
podpisu (206 z VPS-a i z telefonu), do bazy wchodzi gotowy adres.
Scheduler: job clips-latest co godzine (5 stron), zatrzymuje sie na stronie
bez nowych. Reaper (HEAD, 403/404/410 -> dead_at) jako skrypt, upsert
odzywia klip, ktory zrodlo znow podaje. API: GET /clips i /clips/stats do
pilota; wlasciwy feed, pamiec widzianych i telemetria to etap 3.
Sprawdzone tego dnia i odlozone: nsfwswipe (lustro v.redd.it, bez audio,
stoi od 19.08), Pornhub Shorties (zrodlo nr 2, HLS z tokenem 2 h, Referer
na segmentach, 0/110 performerow z kanonu).
- DOOD_OVERLAY_JS (injectedJavaScript po zaladowaniu): fixed + z-index > 100000 bez
Cloudflare -> pointer-events none, iframe sandbox/srcdoc usuwany; co 700 ms
- diagnoza devtools: pelnoekranowy div opacity 0.01 z z 2147463647, iframe reklamowy i
pusty kwadrat 80x80 dokladnie na przycisku play; popunder u nas zablokowany, wiec
warstwa nigdy nie znikala (zgloszenia e9fc12e8, 1278eb49)
- changelog 2026-09-14c, OTA 69b27e52 na 1.3
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- random: md5(seed) -> uuid startu, okno 2000 id (8000 dla wertykalow) po pk_scenes,
filtry na oknie; bez okna planer robil Merge Anti Join po 2,3 mln wierszy (7,6 s)
- duration_desc/asc: bez NULL, do 10 h, indeks ix_scenes_duration (migracja 0035)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- ScenesFilterModal: Reset all filters stosuje domyslne i zamyka arkusz (f5193fba)
- ScenesScreen: has_playback domyslnie wlaczone nie liczy sie jako filtr, za to sort,
min. dlugosc, min. jakosc i stuby tak
- MovieFiltersSheet: rok poza 1900..2100 ignorowany zamiast 422 (2b6dbc75)
- changelog 2026-09-14a, OTA 6cca22ce na 1.3
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- _search_base: hak _thumbnail_map (mapa url -> miniatura z calej strony) przed
szukaniem <img> w oknie tekstu; xhamster mial 54% zrodel bez miniatury
- mypornerleak search: karty maja teraz src zamiast data-src; browse (REST) bez
featured media -> og:image ze strony posta
- scripts/backfill_thumbs.py: uzupelnia miniatury ze strony sceny, od najnowszych
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- screenOptions: tlo ekranu, bez cienia, tytul 17 display, tint accentText
- HeaderIconButton (star/star-outline, eye-off-outline) na 5 ekranach zamiast ★/🚫
- BottomTabsBar: 76 dp, pierscien statyczny w iconBox w spoczynku, kapsula tylko w
trakcie przejscia, srodki zaokraglone do piksela
- changelog 2026-09-08b/c, OTA 1cbb9181 i 18ba425a na 1.3