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>
This commit is contained in:
parent
6da817dc79
commit
e0744da8c7
2 changed files with 128 additions and 0 deletions
|
|
@ -374,12 +374,51 @@ def mark_playback_dead(
|
|||
raise HTTPException(status_code=404, detail="playback source not found for scene")
|
||||
if pb.dead_at is None:
|
||||
tag = _requester_tag(request)
|
||||
others_alive = session.scalar(
|
||||
select(func.count())
|
||||
.select_from(PlaybackSource)
|
||||
.where(
|
||||
PlaybackSource.scene_id == scene_id,
|
||||
PlaybackSource.id != pb.id,
|
||||
PlaybackSource.dead_at.is_(None),
|
||||
)
|
||||
)
|
||||
if not others_alive and not _scene_source_confirmed_dead(pb):
|
||||
log.info(
|
||||
"user mark-dead na ostatnim zrodle sceny %s odrzucone, serwer go nie potwierdzil (%s)",
|
||||
pb.id, tag,
|
||||
)
|
||||
return
|
||||
pb.dead_at = datetime.now(UTC)
|
||||
pb.dead_reason = f"user-marked dead (mobile long-press) {tag}"[:512]
|
||||
session.commit()
|
||||
log.info("user marked playback %s dead (origin=%s %s)", pb.id, pb.origin, tag)
|
||||
|
||||
|
||||
def _scene_source_confirmed_dead(pb: PlaybackSource) -> bool:
|
||||
"""Czy serwer sam widzi, ze zrodlo sceny nie zyje. Uzywane, gdy przytrzymanie w apce
|
||||
zabiloby OSTATNIE zywe zrodlo sceny (scena znika wtedy z list).
|
||||
|
||||
W 30 dni do 2026-10-15 z 617 zrodel oznaczonych w apce 490 zostawilo scene bez zadnego
|
||||
zrodla, glownie porndoe (403 z sieci uzytkownika), galaxyporn, perverzija, javflix
|
||||
(zgloszenie cbb87c8e: strona zyje, ekstraktor daje voe i doodstream). Martwe tylko,
|
||||
gdy strona daje 404/410 albo ekstraktor mowi wprost, ze film usuniety; kazda
|
||||
niepewnosc zostawia zrodlo.
|
||||
"""
|
||||
origin = pb.origin or ""
|
||||
if not origin.startswith(("tube:", "pornapp:")):
|
||||
return False
|
||||
try:
|
||||
try_extract(origin.split(":", 1)[1], pb.page_url)
|
||||
except HosterDead:
|
||||
return True
|
||||
except TubePageError as e:
|
||||
return e.status_code in (404, 410)
|
||||
except Exception:
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
def _movie_source_confirmed_dead(pb: Any) -> bool:
|
||||
"""Czy serwer sam widzi, ze link filmu nie zyje. Uzywane, gdy przytrzymanie w apce
|
||||
zabiloby OSTATNI link filmu.
|
||||
|
|
|
|||
89
scripts/revive_user_marked_last_sources.py
Normal file
89
scripts/revive_user_marked_last_sources.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
"""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())
|
||||
Loading…
Add table
Reference in a new issue