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.
This commit is contained in:
parent
6b034c53e2
commit
cacf40526c
2 changed files with 81 additions and 1 deletions
|
|
@ -661,7 +661,7 @@ setInterval(load,30000);
|
||||||
return
|
return
|
||||||
raw_title_part = m.group(1)
|
raw_title_part = m.group(1)
|
||||||
|
|
||||||
clean_title = raw_title_part.replace('_-_', ' - ').replace('_', ' ').strip()
|
clean_title = raw_title_part.replace('__', ' - ').replace('_-_', ' - ').replace('_', ' ').strip()
|
||||||
|
|
||||||
cache = _load_filminfo_cache()
|
cache = _load_filminfo_cache()
|
||||||
matched = _find_cache_match(cache, clean_title)
|
matched = _find_cache_match(cache, clean_title)
|
||||||
|
|
@ -700,6 +700,26 @@ setInterval(load,30000);
|
||||||
import logging
|
import logging
|
||||||
logging.getLogger("savetv").warning(f"Rename fehlgeschlagen {raw_filename}: {e}")
|
logging.getLogger("savetv").warning(f"Rename fehlgeschlagen {raw_filename}: {e}")
|
||||||
|
|
||||||
|
def _rename_all_pending():
|
||||||
|
import re as _re
|
||||||
|
renamed, skipped = [], []
|
||||||
|
for fp in sorted(SAVETV_DIR.glob("*.mp4")):
|
||||||
|
m = _re.match(r"^(.+)_(\d{6,9})\.mp4$", fp.name)
|
||||||
|
if not m:
|
||||||
|
continue
|
||||||
|
old = fp.name
|
||||||
|
tid = m.group(2)
|
||||||
|
_rename_to_jellyfin(old, tid)
|
||||||
|
if (SAVETV_DIR / old).exists():
|
||||||
|
skipped.append(old)
|
||||||
|
else:
|
||||||
|
renamed.append(old)
|
||||||
|
return {"renamed": renamed, "skipped": skipped}
|
||||||
|
|
||||||
|
@app.route("/api/rename_pending", methods=["POST"])
|
||||||
|
def api_rename_pending():
|
||||||
|
return jsonify(_rename_all_pending())
|
||||||
|
|
||||||
@app.route("/health")
|
@app.route("/health")
|
||||||
def health():
|
def health():
|
||||||
from tools import savetv
|
from tools import savetv
|
||||||
|
|
|
||||||
60
homelab-ai-bot/savetv_rename_nas.py
Executable file
60
homelab-ai-bot/savetv_rename_nas.py
Executable file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/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())
|
||||||
Loading…
Add table
Reference in a new issue