chore(scripts): scalanie tych samych odcinkow hentaimama i xanimeporn
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4233833a2b
commit
dcde8c8d66
1 changed files with 79 additions and 0 deletions
79
scripts/merge_hentai_episode_dupes.py
Normal file
79
scripts/merge_hentai_episode_dupes.py
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
"""Scala te same odcinki hentai z hentaimama i xanimeporn (2026-10-15).
|
||||||
|
|
||||||
|
Tytuly hentaimama mialy do 15.10 ogon "- Watch Online Free in HD - Hentaimama", a xanime
|
||||||
|
dokleja "[Sub-ENG]", wiec ten sam odcinek byl dwiema scenami. Para = scena tylko z
|
||||||
|
hentaimama i scena tylko z xanimeporn o tym samym title_normalized po zdjeciu
|
||||||
|
"sub eng"/"raw"/"uncensored" z konca. Scalamy wylacznie pary jeden do jednego
|
||||||
|
(scena hentaimama zostaje, ma dlugosc i miniature).
|
||||||
|
|
||||||
|
python scripts/merge_hentai_episode_dupes.py # podglad
|
||||||
|
python scripts/merge_hentai_episode_dupes.py --apply
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from app.db import session_scope
|
||||||
|
from app.resolve.scene_merge import merge_scenes
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
_PAIRS_SQL = """
|
||||||
|
with x as (
|
||||||
|
select s.id, regexp_replace(s.title_normalized, '\\s+(sub eng|eng sub|english sub|raw|uncensored)$', '') k
|
||||||
|
from scenes s
|
||||||
|
where exists (select 1 from playback_sources p where p.scene_id = s.id and p.origin = 'tube:xanimeporn')
|
||||||
|
and not exists (select 1 from playback_sources p where p.scene_id = s.id and p.origin = 'tube:hentaimama')
|
||||||
|
), h as (
|
||||||
|
select s.id, s.title_normalized k
|
||||||
|
from scenes s
|
||||||
|
where exists (select 1 from playback_sources p where p.scene_id = s.id and p.origin = 'tube:hentaimama')
|
||||||
|
and not exists (select 1 from playback_sources p where p.scene_id = s.id and p.origin = 'tube:xanimeporn')
|
||||||
|
)
|
||||||
|
select h.id as keep_id, x.id as drop_id, h.k from x join h on h.k = x.k
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def run(apply: bool) -> dict[str, int]:
|
||||||
|
with session_scope() as s:
|
||||||
|
rows = s.execute(sa.text(_PAIRS_SQL)).all()
|
||||||
|
by_keep: dict = defaultdict(list)
|
||||||
|
by_drop: dict = defaultdict(list)
|
||||||
|
for keep_id, drop_id, _k in rows:
|
||||||
|
by_keep[keep_id].append(drop_id)
|
||||||
|
by_drop[drop_id].append(keep_id)
|
||||||
|
pairs = [(k, d, t) for k, d, t in rows if len(by_keep[k]) == 1 and len(by_drop[d]) == 1]
|
||||||
|
c = {"candidates": len(rows), "one_to_one": len(pairs), "merged": 0, "errors": 0}
|
||||||
|
for keep_id, drop_id, title in pairs[:5]:
|
||||||
|
print(f"{title!r}: keep {keep_id} <- {drop_id}")
|
||||||
|
if not apply:
|
||||||
|
return c
|
||||||
|
for keep_id, drop_id, _t in pairs:
|
||||||
|
try:
|
||||||
|
with session_scope() as s:
|
||||||
|
merge_scenes(s, keep_id=keep_id, drop_id=drop_id, resolved_by="merge_hentai_episode_dupes")
|
||||||
|
s.commit()
|
||||||
|
c["merged"] += 1
|
||||||
|
except Exception as e:
|
||||||
|
c["errors"] += 1
|
||||||
|
log.warning("merge %s <- %s padl: %s", keep_id, drop_id, e)
|
||||||
|
if c["merged"] % 200 == 0 and c["merged"]:
|
||||||
|
log.info("hentai dupes %s", c)
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
p = argparse.ArgumentParser()
|
||||||
|
p.add_argument("--apply", action="store_true")
|
||||||
|
args = p.parse_args()
|
||||||
|
print(run(args.apply))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Loading…
Add table
Reference in a new issue