Save.TV: Film-Download auf pve-hetzner Festplatte (HD, werbefrei, /mnt/savetv Bind-Mount)
This commit is contained in:
parent
6c7872bb96
commit
ff11575d4c
1 changed files with 105 additions and 1 deletions
|
|
@ -1,15 +1,17 @@
|
|||
"""Save.TV Online-Videorecorder — EPG Scanner + Film-Tipps + Aufnahme-Steuerung.
|
||||
"""Save.TV Online-Videorecorder — EPG Scanner + Film-Tipps + Aufnahme + Download.
|
||||
|
||||
Architektur:
|
||||
- EPG-Daten von Save.TV: TvProgrammFilm.cfm (3 Tage) + TvProgrammFilmHighlights.cfm (4 Wochen)
|
||||
- Nur TVCATEGORYID 1 (Spielfilm), Spam-Genres rausgefiltert
|
||||
- Seen-Cache: Nur neue Filme werden gemeldet (nicht erneut bei jedem Scan)
|
||||
- Aufnahmen per tcJWriteRecord.cfm
|
||||
- Downloads per croGetDownloadUrl2.cfm -> /mnt/savetv/ (Bind-Mount auf 2.7 TB Platte)
|
||||
"""
|
||||
|
||||
import re
|
||||
import json
|
||||
import logging
|
||||
import subprocess
|
||||
import requests
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
|
@ -34,6 +36,10 @@ EPG_PAGES = [
|
|||
SEEN_CACHE = Path("/tmp/savetv_seen_ids.json")
|
||||
SEEN_MAX_AGE_DAYS = 30
|
||||
|
||||
DOWNLOAD_DIR = Path("/mnt/savetv")
|
||||
DOWNLOAD_FORMAT_HD = 6
|
||||
DOWNLOAD_FORMAT_SD = 5
|
||||
|
||||
AUTO_RECORD_SCORE = 80
|
||||
SUGGEST_SCORE = 60
|
||||
|
||||
|
|
@ -94,18 +100,38 @@ TOOLS = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "savetv_download",
|
||||
"description": "Save.TV Film downloaden auf Hetzner-Festplatte (HD, werbefrei). "
|
||||
"Nutze wenn User sagt 'download', 'runterladen', 'sichern', 'speichern'. "
|
||||
"Filme landen auf pve-hetzner /var/lib/vz/savetv/ (2.7 TB frei).",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"telecast_id": {"type": "number", "description": "TelecastId der Sendung"},
|
||||
"title": {"type": "string", "description": "Filmtitel fuer den Dateinamen"},
|
||||
},
|
||||
"required": ["telecast_id"],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
SYSTEM_PROMPT_EXTRA = """TV / Save.TV Tools:
|
||||
- get_savetv_tipps: Zeigt sehenswerte Spielfilme der naechsten Tage/Wochen
|
||||
- get_savetv_archive_filme: Bewertet alle fertigen Aufnahmen im Archiv nach Qualitaet
|
||||
- savetv_record: Nimmt einen Film per TelecastId auf
|
||||
- savetv_download: Laedt fertigen Film auf pve-hetzner Festplatte (HD, werbefrei, 2.7 TB frei)
|
||||
- get_savetv_status: Zeigt Archiv und geplante Aufnahmen
|
||||
Wenn der User nach Archiv-Filmen/Bewertung fragt, nutze get_savetv_archive_filme.
|
||||
WICHTIG bei Archiv-Bewertung: Das Tool liefert KINO-HIGHLIGHTS (echte Kinofilme, Klassiker,
|
||||
preisgekroente Filme) getrennt von deutschem Fernsehprogramm. Praesentiere dem User die
|
||||
KINO-HIGHLIGHTS zuerst und erklaere kurz warum jeder Film sehenswert ist (Regisseur, Preise,
|
||||
Stars). Hebe DRINGEND ablaufende Kino-Highlights besonders hervor — die muss er schnell sichern.
|
||||
Download: Wenn User einen Film sichern/downloaden will, nutze savetv_download mit der TelecastId.
|
||||
Dateien landen auf pve-hetzner (/var/lib/vz/savetv/) und koennen spaeter manuell geholt werden.
|
||||
"""
|
||||
|
||||
|
||||
|
|
@ -364,6 +390,54 @@ def _record_telecast(telecast_id):
|
|||
return "Fehler: " + str(e)
|
||||
|
||||
|
||||
def _get_download_url(telecast_id, fmt=DOWNLOAD_FORMAT_HD, adfree=True):
|
||||
"""Holt die temporaere Download-URL fuer eine fertige Aufnahme."""
|
||||
s = _get_session()
|
||||
if not s:
|
||||
return None, "Login fehlgeschlagen"
|
||||
try:
|
||||
r = s.get(
|
||||
SAVETV_URL + "/STV/M/obj/cRecordOrder/croGetDownloadUrl2.cfm",
|
||||
params={
|
||||
"TelecastId": telecast_id,
|
||||
"iFormat": fmt,
|
||||
"bAdFree": str(adfree).lower(),
|
||||
},
|
||||
headers={"X-Requested-With": "XMLHttpRequest"},
|
||||
timeout=15,
|
||||
)
|
||||
data = r.json()
|
||||
if data.get("SUCCESS"):
|
||||
return data["DOWNLOADURL"], None
|
||||
return None, data.get("ERROR", "Unbekannter Fehler")
|
||||
except Exception as e:
|
||||
return None, str(e)
|
||||
|
||||
|
||||
def _download_film(telecast_id, title="film"):
|
||||
"""Startet HD-Download im Hintergrund nach /mnt/savetv/."""
|
||||
url, err = _get_download_url(telecast_id)
|
||||
if err:
|
||||
url, err = _get_download_url(telecast_id, fmt=DOWNLOAD_FORMAT_SD)
|
||||
if err:
|
||||
return None, f"Download-URL Fehler: {err}"
|
||||
|
||||
DOWNLOAD_DIR.mkdir(parents=True, exist_ok=True)
|
||||
safe_title = re.sub(r'[^\w\-.]', '_', title)[:80]
|
||||
filename = f"{safe_title}_{telecast_id}.mp4"
|
||||
target = DOWNLOAD_DIR / filename
|
||||
|
||||
try:
|
||||
subprocess.Popen(
|
||||
["wget", "-q", "-O", str(target), url],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
return filename, None
|
||||
except Exception as e:
|
||||
return None, f"wget Fehler: {e}"
|
||||
|
||||
|
||||
def _format_film(f, with_tid=True):
|
||||
"""Formatiert einen Film als Text."""
|
||||
title = f.get("STITLE", "?")
|
||||
|
|
@ -669,9 +743,39 @@ def handle_savetv_record(telecast_id=0, **kw):
|
|||
return "Save.TV: " + result + "\nSendung: " + title
|
||||
|
||||
|
||||
def handle_savetv_download(telecast_id=0, title="", **kw):
|
||||
"""Film von Save.TV auf pve-hetzner Festplatte downloaden."""
|
||||
if not telecast_id:
|
||||
return "Keine TelecastId angegeben."
|
||||
tid = int(telecast_id)
|
||||
|
||||
if not title:
|
||||
entries = _get_full_archive()
|
||||
for e in entries:
|
||||
tc = e.get("STRTELECASTENTRY", {})
|
||||
if int(tc.get("ITELECASTID", 0)) == tid:
|
||||
title = tc.get("STITLE", f"film_{tid}")
|
||||
break
|
||||
if not title:
|
||||
title = f"film_{tid}"
|
||||
|
||||
filename, err = _download_film(tid, title)
|
||||
if err:
|
||||
return f"Download fehlgeschlagen: {err}"
|
||||
|
||||
return (
|
||||
f"Download gestartet: {title}\n"
|
||||
f"Datei: /var/lib/vz/savetv/{filename}\n"
|
||||
f"Format: H.264 HD (werbefrei)\n"
|
||||
f"Server: pve-hetzner (2.7 TB frei)\n"
|
||||
f"Hinweis: Download laeuft im Hintergrund (1-3 GB, ca. 5-15 Min)."
|
||||
)
|
||||
|
||||
|
||||
HANDLERS = {
|
||||
"get_savetv_status": handle_get_savetv_status,
|
||||
"get_savetv_tipps": handle_get_savetv_tipps,
|
||||
"get_savetv_archive_filme": handle_get_savetv_archive_filme,
|
||||
"savetv_record": handle_savetv_record,
|
||||
"savetv_download": handle_savetv_download,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue