119 lines
2.8 KiB
Python
Executable file
119 lines
2.8 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""SaveTV Auto-Download — Lädt fertige Aufnahmen automatisch herunter.
|
|
|
|
Cronjob: */30 * * * * (alle 30 Minuten)
|
|
Prüft das Save.TV-Archiv auf fertige Aufnahmen die noch nicht auf Hetzner liegen
|
|
und startet den Download im Hintergrund.
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
import os
|
|
import re
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
sys.path.insert(0, "/opt")
|
|
|
|
from tools import savetv, savetv_country_filter
|
|
|
|
log = logging.getLogger("savetv_auto_download")
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s %(levelname)s %(message)s",
|
|
datefmt="%H:%M:%S",
|
|
)
|
|
|
|
DOWNLOAD_DIR = Path("/mnt/savetv")
|
|
DOWNLOAD_LOG = DOWNLOAD_DIR / ".download_log.json"
|
|
MAX_PARALLEL = 3
|
|
MIN_SCORE = 80
|
|
|
|
|
|
def _load_download_log():
|
|
if DOWNLOAD_LOG.exists():
|
|
try:
|
|
return json.loads(DOWNLOAD_LOG.read_text())
|
|
except Exception:
|
|
pass
|
|
return {}
|
|
|
|
|
|
def _save_download_log(dl_log):
|
|
try:
|
|
DOWNLOAD_LOG.write_text(json.dumps(dl_log, ensure_ascii=False, indent=2))
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def _normalize(s):
|
|
return re.sub(r"\s+", " ", re.sub(r"[^\w\s]", " ", s)).strip().lower()
|
|
|
|
|
|
def _already_stored(title):
|
|
norm = _normalize(title)
|
|
for fp in DOWNLOAD_DIR.iterdir():
|
|
if fp.suffix == ".mp4" and fp.stat().st_size > 1_000_000:
|
|
raw = fp.stem.rsplit(" (", 1)[0]
|
|
if _normalize(raw) == norm:
|
|
return True
|
|
return False
|
|
|
|
|
|
def run():
|
|
log.info("Starte Auto-Download Check...")
|
|
|
|
entries = savetv._get_full_archive()
|
|
if not entries:
|
|
log.info("Kein Archiv-Zugriff oder leeres Archiv")
|
|
return
|
|
|
|
dl_log = _load_download_log()
|
|
filminfo_cache = savetv_country_filter.load_filminfo_cache()
|
|
started = 0
|
|
|
|
for e in entries:
|
|
tc = e.get("STRTELECASTENTRY", {})
|
|
tid = str(int(float(tc.get("ITELECASTID", 0))))
|
|
title = tc.get("STITLE", "")
|
|
|
|
if not title or not tid or tid == "0":
|
|
continue
|
|
|
|
if tc.get("SFOLGE", ""):
|
|
continue
|
|
|
|
if savetv._is_excluded(title):
|
|
continue
|
|
|
|
if savetv_country_filter.should_exclude_production_country(title, filminfo_cache):
|
|
continue
|
|
|
|
if tid in dl_log:
|
|
continue
|
|
|
|
if _already_stored(title):
|
|
dl_log[tid] = "done"
|
|
continue
|
|
|
|
if started >= MAX_PARALLEL:
|
|
break
|
|
|
|
log.info(f"Starte Download: {title} (TID {tid})")
|
|
filename, err = savetv._download_film(int(float(tid)), title)
|
|
if err:
|
|
log.warning(f"Download-Fehler {title}: {err}")
|
|
continue
|
|
|
|
dl_log[tid] = "done"
|
|
started += 1
|
|
time.sleep(2)
|
|
|
|
_save_download_log(dl_log)
|
|
log.info(f"Fertig: {started} neue Downloads gestartet")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|