goon/scripts/revive_user_marked_last_sources.py
goon-foss e0744da8c7 fix(playback): przytrzymanie nie zabija ostatniego zrodla sceny bez potwierdzenia
W 30 dni 490 scen zostalo przez "mark as broken" bez zadnego zrodla, glownie
przez problemy sieci uzytkownika (porndoe 403, galaxyporn, perverzija).
Ostatnie zrodlo znika tylko, gdy serwer widzi 404/410 albo HosterDead.
Skrypt przywrocil 366 zrodel z pozytywnym potwierdzeniem, ze strona zyje.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:55:13 +02:00

89 lines
3 KiB
Python

"""Przywraca ostatnie zrodla scen zabite przytrzymaniem w apce, jesli strona zyje (2026-10-15).
Do 15.10 przytrzymanie "mark as broken" zabijalo zrodlo bez sprawdzenia. W 30 dni 490 scen
zostalo przez to bez zadnego zrodla i zniknelo z list (porndoe: 403 z sieci uzytkownika,
galaxyporn, perverzija, javflix...). Od 15.10 serwer sprawdza ostatnie zrodlo przed
oznaczeniem; ten skrypt cofa wczesniejsze przypadki, ale tylko z POZYTYWNYM dowodem:
- ekstraktor zwraca zrodla (strona i film istnieja),
- dla serwisow grajacych tylko w WebView (ekstraktor nic nie pobiera): strona odpowiada 200.
python scripts/revive_user_marked_last_sources.py # podglad
python scripts/revive_user_marked_last_sources.py --apply [--days 30]
"""
from __future__ import annotations
import argparse
import logging
from collections import Counter
import sqlalchemy as sa
from app.db import session_scope
from app.extractors import is_vps_blocked_fallback, try_extract
from app.extractors._fetch import browser_get
log = logging.getLogger(__name__)
def _alive(origin: str, page_url: str) -> bool:
if not origin.startswith(("tube:", "pornapp:")):
return False
sitetag = origin.split(":", 1)[1]
if is_vps_blocked_fallback(sitetag):
try:
return browser_get(page_url, timeout=20.0).status_code < 400
except Exception:
return False
try:
return bool(try_extract(sitetag, page_url))
except Exception:
return False
def run(apply: bool, days: int) -> dict:
with session_scope() as s:
rows = s.execute(
sa.text(
"""
SELECT p.id, p.origin, p.page_url
FROM playback_sources p
WHERE p.dead_reason LIKE 'user-marked dead%'
AND p.dead_at > now() - make_interval(days => :d)
AND NOT EXISTS (
SELECT 1 FROM playback_sources o
WHERE o.scene_id = p.scene_id AND o.dead_at IS NULL
)
"""
),
{"d": days},
).all()
revive: list = []
by_origin: Counter = Counter()
for pb_id, origin, url in rows:
if _alive(origin, url):
revive.append(pb_id)
by_origin[origin] += 1
print({"candidates": len(rows), "alive": len(revive)}, by_origin.most_common(8))
if apply and revive:
with session_scope() as s:
s.execute(
sa.text("UPDATE playback_sources SET dead_at = NULL, dead_reason = NULL WHERE id = ANY(:ids)"),
{"ids": revive},
)
s.commit()
print("revived", len(revive))
return {"candidates": len(rows), "revived": len(revive) if apply else 0}
def main() -> int:
logging.basicConfig(level=logging.WARNING)
p = argparse.ArgumentParser()
p.add_argument("--apply", action="store_true")
p.add_argument("--days", type=int, default=30)
args = p.parse_args()
run(args.apply, args.days)
return 0
if __name__ == "__main__":
raise SystemExit(main())