goon/scripts/fix_latestpornvideo_thumbs.py
goon-foss 97bca096e6
Some checks are pending
Backend tests / test (push) Waiting to run
Build Android APK / build (push) Waiting to run
feat: alarm na serwis bez udanych odtworzen, miniatury latestpornvideo z plakatu lulu
Watchdog odtwarzania: origin z >= 300 zywymi zrodlami i zerem udanych
odtworzen w 7 dni (hentaimama i xanime padly tak, ze nic nie alarmowalo).
latestpornvideo: link podgladu pixhost zamieniany na obrazek, usuniety
obrazek i brak miniatury -> plakat odtwarzacza lulu; skrypt dla starych.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 12:41:11 +02:00

94 lines
3.2 KiB
Python

"""latestpornvideo: odzyskanie miniatur, ktore nie dzialaja (2026-10-15).
Scraper od dzis sam poprawia nowe wpisy (`better_thumb`), tu poprawiamy istniejace:
- brak miniatury,
- `pixhost.to/show/...` (strona podgladu zamiast obrazka),
- obrazek pixhost usuniety (przekierowanie na /image/removed.png),
- z `--imgds`: miniatury imgds.net (dawne ticdn.net), ktore daja 404.
W kazdym z tych przypadkow zapasem jest plakat odtwarzacza lulu z wpisu.
python scripts/fix_latestpornvideo_thumbs.py # podglad 20 wierszy
python scripts/fix_latestpornvideo_thumbs.py --apply --limit 20000 [--imgds]
Dlugie, na prodzie przez `docker compose run -d --rm worker python3 /srv/scripts/...`.
"""
from __future__ import annotations
import argparse
import logging
import time
import httpx
import sqlalchemy as sa
from app.connectors.direct_scrapers.latestpornvideo import better_thumb
from app.db import session_scope
log = logging.getLogger(__name__)
def _imgds_missing(url: str) -> bool:
try:
r = httpx.head(url, headers={"User-Agent": "Mozilla/5.0"}, timeout=10.0, follow_redirects=True)
except Exception:
return False
return r.status_code == 404
def run(apply: bool, limit: int, imgds: bool, sleep: float) -> dict[str, int]:
c = {"checked": 0, "changed": 0, "unchanged": 0, "lost": 0}
cond = (
"thumbnail_url IS NULL OR thumbnail_url LIKE '%pixhost%'"
+ (" OR thumbnail_url LIKE 'https://imgds.net/snaps/%'" if imgds else "")
)
with session_scope() as s:
rows = s.execute(
sa.text(
"SELECT id, page_url, thumbnail_url FROM playback_sources "
"WHERE origin='tube:latestpornvideocom' AND dead_at IS NULL "
f"AND ({cond}) ORDER BY id LIMIT :lim"
),
{"lim": limit},
).all()
for pb_id, page_url, thumb in rows:
c["checked"] += 1
candidate = thumb
if thumb and thumb.startswith("https://imgds.net/snaps/") and _imgds_missing(thumb):
candidate = None
new = better_thumb(candidate, page_url, timeout=30.0)
if new == thumb:
c["unchanged"] += 1
elif not new:
c["lost"] += 1
else:
c["changed"] += 1
if c["changed"] <= 5:
print(f"{page_url}: {thumb} -> {new}")
if apply:
with session_scope() as s:
s.execute(
sa.text("UPDATE playback_sources SET thumbnail_url=:u WHERE id=:id"),
{"u": new[:2048], "id": pb_id},
)
s.commit()
if c["checked"] % 200 == 0:
log.info("lpv thumbs %s", c)
time.sleep(sleep)
return c
def main() -> int:
logging.basicConfig(level=logging.INFO)
p = argparse.ArgumentParser()
p.add_argument("--apply", action="store_true")
p.add_argument("--limit", type=int, default=20)
p.add_argument("--imgds", action="store_true")
p.add_argument("--sleep", type=float, default=0.2)
args = p.parse_args()
print(run(args.apply, args.limit, args.imgds, args.sleep))
return 0
if __name__ == "__main__":
raise SystemExit(main())