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
4c39f51ec3
commit
16667efbed
2 changed files with 81 additions and 1 deletions
|
|
@ -661,7 +661,7 @@ setInterval(load,30000);
|
|||
return
|
||||
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()
|
||||
matched = _find_cache_match(cache, clean_title)
|
||||
|
|
@ -700,6 +700,26 @@ setInterval(load,30000);
|
|||
import logging
|
||||
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")
|
||||
def health():
|
||||
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