homelab-brain/homelab-ai-bot/savetv_rename_nas.py
Homelab Cursor 16667efbed fix(savetv): Batch-Umbenennung für Raw-Backlog und NAS-Skript
Rename lief nur beim Download-Abschluss; POST /api/rename_pending
benennt alle Titel_ID.mp4 auf Hetzner um. savetv_rename_nas.py für
bereits kopierte NAS-Dateien. __ wird zu Bindestrich im Titel.
2026-05-21 15:34:38 +02:00

60 lines
1.7 KiB
Python
Executable file

#!/usr/bin/env python3
"""Benennt Raw-MP4s auf dem NAS um (Titel_ID.mp4 -> Titel (Jahr).mp4)."""
import json
import os
import re
import urllib.parse
import urllib.request
ZIEL = os.environ.get("SAVETV_NAS_DIR", "/mnt/nas/Filme zum nachbearbeiten")
FILMINFO_API = os.environ.get("SAVETV_FILMINFO_API", "http://138.201.84.95:9443/api/filminfo")
RAW_RE = re.compile(r"^(.+)_(\d{6,9})\.mp4$")
def clean_title(raw_part):
return raw_part.replace("_-_", " - ").replace("_", " ").strip()
def filminfo(title):
url = FILMINFO_API + "?" + urllib.parse.urlencode({"title": title})
with urllib.request.urlopen(url, timeout=60) as r:
return json.loads(r.read())
def rename_one(name):
m = RAW_RE.match(name)
if not m:
return None
clean = clean_title(m.group(1))
try:
info = filminfo(clean)
year = (info or {}).get("year", "")
except Exception as e:
print(f" filminfo fehlgeschlagen fuer {clean}: {e}")
year = ""
safe = re.sub(r'[\\/:*?"<>|]', "", clean).strip()
dest = f"{safe} ({year}).mp4" if year else f"{safe}.mp4"
src = os.path.join(ZIEL, name)
dst = os.path.join(ZIEL, dest)
if os.path.exists(dst):
print(f" Ziel existiert, loesche Raw: {name}")
os.remove(src)
return dest
os.rename(src, dst)
print(f" OK: {name} -> {dest}")
return dest
def main():
if not os.path.isdir(ZIEL):
print(f"Ordner fehlt: {ZIEL}")
return 1
pending = [n for n in os.listdir(ZIEL) if RAW_RE.match(n)]
print(f"{len(pending)} Raw-Dateien auf NAS")
for n in sorted(pending):
rename_one(n)
return 0
if __name__ == "__main__":
raise SystemExit(main())