hentaimama: nowy zapis id posta i 5 playerow w admin-ajax, adresy w JSON-ie; bierzemy mp4 z gdvid (3 jakosci, bez tokenu), POST najpierw bez proxy. Ogon "Watch Online Free in HD" w tytulach ucinany. xanimeporn: przekierowanie download.php rozwiazywane na serwerze, apka dostawala .php, otwierala WebView i pobierala plik zamiast grac. Blad resolve (extractor pusty, HTTP strony) trafia do playback_events. Filmy: tytul z okruszkow (motyw dooplay losuje "Watch"/"Now Playing:"), linki nitroflare/rapidgator nie sa juz brane za wideo, sam landing idzie do WebView, a przytrzymanie w apce nie zabija ostatniego linku filmu, jesli serwer widzi, ze zyje. Skrypty naprawcze: tytuly dooplay, tytuly i miniatury hentaimama, repair_dooplay_movies dla streampornvip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
110 lines
3.8 KiB
Python
110 lines
3.8 KiB
Python
"""Hentaimama: ogon w tytulach i brakujace miniatury (2026-10-15).
|
|
|
|
1. Tytuly: od ~31.08.2026 og:title mial ogon "TYTUL - Watch Online Free in HD - Hentaimama"
|
|
i tak weszlo ok. 100 scen. Scraper juz go ucina, tu poprawiamy istniejace (title i
|
|
title_normalized).
|
|
2. Miniatury: ok. 2100 zrodel z pierwszego przebiegu (12.08) nie ma thumbnail_url, a te sceny
|
|
nie maja innego zrodla z obrazkiem. Strony maja og:image, pobieramy je po kolei.
|
|
|
|
python scripts/fix_hentaimama_titles_thumbs.py # podglad
|
|
python scripts/fix_hentaimama_titles_thumbs.py --apply [--limit N] [--sleep 0.5]
|
|
|
|
Dlugie, wiec na prodzie przez `docker compose run -d --rm worker python3 scripts/...`
|
|
(z pliku, nie przez stdin).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import html as html_mod
|
|
import logging
|
|
import time
|
|
|
|
import sqlalchemy as sa
|
|
|
|
from app.connectors.direct_scrapers.hentaimama import _OG_IMAGE_RE, _TITLE_TAIL_RE
|
|
from app.db import session_scope
|
|
from app.extractors._fetch import fetch_tube_html
|
|
from app.normalize.text import normalize
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def fix_titles(apply: bool) -> int:
|
|
n = 0
|
|
with session_scope() as session:
|
|
rows = session.execute(
|
|
sa.text("SELECT id, title FROM scenes WHERE title ~* 'hentaimama\\s*$'")
|
|
).all()
|
|
for scene_id, title in rows:
|
|
new = _TITLE_TAIL_RE.sub("", title).strip()
|
|
if not new or new == title:
|
|
continue
|
|
n += 1
|
|
if n <= 5:
|
|
print(f"{title!r} -> {new!r}")
|
|
if apply:
|
|
session.execute(
|
|
sa.text("UPDATE scenes SET title=:t, title_normalized=:n WHERE id=:id"),
|
|
{"t": new[:512], "n": normalize(new)[:512], "id": scene_id},
|
|
)
|
|
if apply:
|
|
session.commit()
|
|
return n
|
|
|
|
|
|
def fix_thumbs(apply: bool, limit: int, sleep: float) -> dict[str, int]:
|
|
c = {"checked": 0, "filled": 0, "no_image": 0, "fetch_fail": 0}
|
|
with session_scope() as session:
|
|
rows = session.execute(
|
|
sa.text(
|
|
"SELECT id, page_url FROM playback_sources WHERE origin='tube:hentaimama' "
|
|
"AND thumbnail_url IS NULL AND dead_at IS NULL ORDER BY id LIMIT :lim"
|
|
),
|
|
{"lim": limit},
|
|
).all()
|
|
for pb_id, page_url in rows:
|
|
c["checked"] += 1
|
|
try:
|
|
page = fetch_tube_html(page_url, timeout=30.0)
|
|
except Exception as e:
|
|
c["fetch_fail"] += 1
|
|
log.info("fetch %s: %s", page_url, e)
|
|
time.sleep(sleep)
|
|
continue
|
|
m = _OG_IMAGE_RE.search(page)
|
|
if not m:
|
|
c["no_image"] += 1
|
|
else:
|
|
img = html_mod.unescape(m.group(1)).strip()
|
|
if apply:
|
|
with session_scope() as session:
|
|
session.execute(
|
|
sa.text("UPDATE playback_sources SET thumbnail_url=:u WHERE id=:id"),
|
|
{"u": img[:2048], "id": pb_id},
|
|
)
|
|
session.commit()
|
|
c["filled"] += 1
|
|
if c["filled"] <= 3:
|
|
print(page_url, "->", img)
|
|
if c["checked"] % 100 == 0:
|
|
log.info("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=5)
|
|
p.add_argument("--sleep", type=float, default=0.5)
|
|
p.add_argument("--skip-titles", action="store_true")
|
|
args = p.parse_args()
|
|
if not args.skip_titles:
|
|
print("titles:", fix_titles(args.apply))
|
|
print("thumbs:", fix_thumbs(args.apply, args.limit, args.sleep))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|