From fcb87cf881f9da281c60a4b3c861a13ec1e268d1 Mon Sep 17 00:00:00 2001 From: sandro Date: Fri, 2 Oct 2026 06:46:35 +0200 Subject: [PATCH] plex und threadfin --- aktualisiere_epg.py | 115 ++++++++++++++++++++++++++----------- aktualisiere_epg_backup.py | 85 +++++++++++++++++++++++++++ epg_create.py | 15 ++++- last_provider_id.txt | 2 +- push.sh | 26 +++++++++ sky_epg.xml | 6 +- sky_epg_serve.py | 16 ++++++ 7 files changed, 223 insertions(+), 42 deletions(-) create mode 100755 aktualisiere_epg_backup.py create mode 100755 push.sh create mode 100644 sky_epg_serve.py diff --git a/aktualisiere_epg.py b/aktualisiere_epg.py index 6f82f85..8c475ae 100755 --- a/aktualisiere_epg.py +++ b/aktualisiere_epg.py @@ -1,6 +1,7 @@ import requests import json import os +import time # --- KONFIGURATION --- JELLYFIN_URL = "http://localhost:8096" # Oder 192.168.188.124 @@ -9,7 +10,7 @@ EPG_PATH = "/home/sandro/m3u/sky_epg.xml" ID_FILE = "last_provider_id.txt" # Lokaler Cache für die ID HEADERS = { - "X-Emby-Token": API_KEY, + "Authorization": 'Mediabrowser Token="' + API_KEY + '"', "Content-Type": "application/json" } @@ -17,9 +18,9 @@ def get_provider_id(): """Versucht die ID des XMLTV-Providers von Jellyfin zu holen.""" try: # Liste aller Live-TV Provider abfragen - response = requests.get(f"{JELLYFIN_URL}/LiveTv/ListingProviders", headers=HEADERS) + response = requests.get(f"{JELLYFIN_URL}/System/Configuration/livetv", headers=HEADERS) response.raise_for_status() - providers = response.json().get("Listings", []) + providers = response.json().get("ListingProviders", []) # Suche den Provider, der unseren Pfad nutzt for p in providers: @@ -38,6 +39,7 @@ def sync_jellyfin_epg(): # 1. ID finden (aus API oder Cache) provider_id = get_provider_id() + # 2. Wenn ID vorhanden, alten Provider löschen if provider_id: print(f"Lösche Provider mit ID: {provider_id}") @@ -46,40 +48,83 @@ def sync_jellyfin_epg(): except Exception as e: print(f"Löschen fehlgeschlagen (evtl. schon weg): {e}") - # 3. Provider neu anlegen - print(f"Lege Provider neu an für: {EPG_PATH}") - payload = { - "Type": "xmltv", - "Path": EPG_PATH, - "MoviePrefix": None, - "UserAgent": None, - "MovieCategories": [], - "KidsCategories": [], - "NewsCategories": [], - "SportsCategories": ["sports"], - "EnableAllTuners": True, - "EnabledTuners": [] - } + with open("/home/sandro/m3u/sky_epg.xml","r") as epg_file: + epg_file_content = epg_file.read() + if "None" not in epg_file_content: + # 3. Provider neu anlegen + print(f"Lege Provider neu an für: {EPG_PATH}") + payload = { + "Type": "xmltv", + "Path": EPG_PATH, + "MoviePrefix": None, + "UserAgent": None, + "MovieCategories": [], + "KidsCategories": [], + "NewsCategories": [], + "SportsCategories": ["sports"], + "EnableAllTuners": True, + "EnabledTuners": [] + } + + try: + response = requests.post(f"{JELLYFIN_URL}/LiveTv/ListingProviders?ValidateListings=true", + headers=HEADERS, json=payload) + response.raise_for_status() + + # Die neue ID aus der Antwort holen und zwischenspeichern + new_data = response.json() + new_id = new_data.get("Id") + + if new_id: + with open(ID_FILE, "w") as f: + f.write(new_id) + print(f"Erfolgreich! Neue ID {new_id} im Cache gespeichert.") + + # 4. Optional: Sofortigen Refresh der Daten triggern + requests.post(f"{JELLYFIN_URL}/LiveTv/Refresh?api_key={API_KEY}") + + except Exception as e: + print(f"Fehler beim Neuerstellen: {e}") + +def sync_threadfin_epg(): + url = "http://192.168.189.116:34400/api/" + payload = {"cmd": "update.xmltv"} + + print("🚀 Sende EPG-Update-Befehl an Threadfin...") + try: + # Das requests-Modul wandelt das dict mit 'json=' automatisch in ein sauberes JSON-Payload um + response = requests.post(url, json=payload, timeout=10) + response.raise_for_status() # Wirft einen Fehler bei HTTP-Codes wie 4xx oder 5xx + + print(f"✅ Erfolgreich! Status: {response.status_code}") + print(f"Antwort: {response.text}") + # Kommandozeilen-Parameter definieren + time.sleep(10) + print(f"Wartezeit für Threadfin vorbei, weiter gehts") + + except requests.exceptions.RequestException as e: + print(f"❌ Fehler beim API-Aufruf: {e}") + sys.exit(1) + +def sync_plex_epg(): + PLEX_IP = "192.168.188.124" + PLEX_PORT = "32400" + PLEX_DVR_ID = "16" # Deine DVR-ID (aus der XML) + PLEX_TOKEN = "xnxczzsEyHyTN1BAveeq" # Dein Plex-Token + + plex_url = f"http://{PLEX_IP}:{PLEX_PORT}/livetv/dvrs/{PLEX_DVR_ID}/reloadGuide?X-Plex-Token={PLEX_TOKEN}" try: - response = requests.post(f"{JELLYFIN_URL}/LiveTv/ListingProviders?ValidateListings=true", - headers=HEADERS, json=payload) - response.raise_for_status() - - # Die neue ID aus der Antwort holen und zwischenspeichern - new_data = response.json() - new_id = new_data.get("Id") - - if new_id: - with open(ID_FILE, "w") as f: - f.write(new_id) - print(f"Erfolgreich! Neue ID {new_id} im Cache gespeichert.") - - # 4. Optional: Sofortigen Refresh der Daten triggern - requests.post(f"{JELLYFIN_URL}/LiveTv/Refresh?api_key={API_KEY}") - - except Exception as e: - print(f"Fehler beim Neuerstellen: {e}") + print("Sende Guide-Reload-Befehl an Plex...") + res_plex = requests.post(plex_url, timeout=10) + res_plex.raise_for_status() + print(f"Plex erfolgreich getriggert (Status: {res_plex.status_code})") + except requests.exceptions.RequestException as e: + print(f"Fehler beim API-Aufruf von Plex: {e}") + + if __name__ == "__main__": sync_jellyfin_epg() + sync_threadfin_epg() + sync_plex_epg() diff --git a/aktualisiere_epg_backup.py b/aktualisiere_epg_backup.py new file mode 100755 index 0000000..6f82f85 --- /dev/null +++ b/aktualisiere_epg_backup.py @@ -0,0 +1,85 @@ +import requests +import json +import os + +# --- KONFIGURATION --- +JELLYFIN_URL = "http://localhost:8096" # Oder 192.168.188.124 +API_KEY = "5ba10da6cca145feb8feff8f6b4b5e55" # Hier den API Key eintragen +EPG_PATH = "/home/sandro/m3u/sky_epg.xml" +ID_FILE = "last_provider_id.txt" # Lokaler Cache für die ID + +HEADERS = { + "X-Emby-Token": API_KEY, + "Content-Type": "application/json" +} + +def get_provider_id(): + """Versucht die ID des XMLTV-Providers von Jellyfin zu holen.""" + try: + # Liste aller Live-TV Provider abfragen + response = requests.get(f"{JELLYFIN_URL}/LiveTv/ListingProviders", headers=HEADERS) + response.raise_for_status() + providers = response.json().get("Listings", []) + + # Suche den Provider, der unseren Pfad nutzt + for p in providers: + if p.get("Path") == EPG_PATH: + return p.get("Id") + except Exception as e: + print(f"Fehler beim Abrufen der Provider-Liste: {e}") + + # Falls in der API nicht gefunden, schau im lokalen Cache nach + if os.path.exists(ID_FILE): + with open(ID_FILE, "r") as f: + return f.read().strip() + return None + +def sync_jellyfin_epg(): + # 1. ID finden (aus API oder Cache) + provider_id = get_provider_id() + + # 2. Wenn ID vorhanden, alten Provider löschen + if provider_id: + print(f"Lösche Provider mit ID: {provider_id}") + try: + requests.delete(f"{JELLYFIN_URL}/LiveTv/ListingProviders?id={provider_id}", headers=HEADERS) + except Exception as e: + print(f"Löschen fehlgeschlagen (evtl. schon weg): {e}") + + # 3. Provider neu anlegen + print(f"Lege Provider neu an für: {EPG_PATH}") + payload = { + "Type": "xmltv", + "Path": EPG_PATH, + "MoviePrefix": None, + "UserAgent": None, + "MovieCategories": [], + "KidsCategories": [], + "NewsCategories": [], + "SportsCategories": ["sports"], + "EnableAllTuners": True, + "EnabledTuners": [] + } + + try: + response = requests.post(f"{JELLYFIN_URL}/LiveTv/ListingProviders?ValidateListings=true", + headers=HEADERS, json=payload) + response.raise_for_status() + + # Die neue ID aus der Antwort holen und zwischenspeichern + new_data = response.json() + new_id = new_data.get("Id") + + if new_id: + with open(ID_FILE, "w") as f: + f.write(new_id) + print(f"Erfolgreich! Neue ID {new_id} im Cache gespeichert.") + + # 4. Optional: Sofortigen Refresh der Daten triggern + requests.post(f"{JELLYFIN_URL}/LiveTv/Refresh?api_key={API_KEY}") + + except Exception as e: + print(f"Fehler beim Neuerstellen: {e}") + +if __name__ == "__main__": + sync_jellyfin_epg() diff --git a/epg_create.py b/epg_create.py index 031624d..bf6bbb6 100755 --- a/epg_create.py +++ b/epg_create.py @@ -2,6 +2,7 @@ import subprocess from flask import Flask, request, jsonify from lxml import etree from datetime import datetime, timedelta +from zoneinfo import ZoneInfo app = Flask(__name__) @@ -12,11 +13,19 @@ def update_sky(): data = request.json channel_name = data.get('channel', 'Unbekannt') content_title = data.get('content', 'Keine Information') + skyq_media_type = data.get('type', 'Keine Information') + + if skyq_media_type == 'app': + content_title = "App-TV" # Zeitstempel für XMLTV (Start jetzt, Ende in 1 Std als Platzhalter) - now = datetime.now() - start_time = now.strftime("%Y%m%d%H%M%S +0100") - stop_time = (now + timedelta(hours=12)).strftime("%Y%m%d%H%M%S +0100") + tz = ZoneInfo("Europe/Berlin") + now = datetime.now(tz) + + start_time = now.strftime("%Y%m%d%H%M%S %z") + stop_time = (now + timedelta(hours=12)).strftime("%Y%m%d%H%M%S %z") + print(start_time) + print(stop_time) # XML Struktur aufbauen root = etree.Element("tv") diff --git a/last_provider_id.txt b/last_provider_id.txt index cefcf38..18392a5 100644 --- a/last_provider_id.txt +++ b/last_provider_id.txt @@ -1 +1 @@ -ba629a20463c446085ff4ebcf7845269 \ No newline at end of file +0a1b1777aefb4c4fb861ecae7ae88aae \ No newline at end of file diff --git a/push.sh b/push.sh new file mode 100755 index 0000000..205df0d --- /dev/null +++ b/push.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Falls du das Skript von überall ausführen willst, +# wechsle hier in dein Repo-Verzeichnis: +# cd /home/sandro/dein-repo-pfad || exit + +# 1. Alle Änderungen stagen +git add . + +# 2. Commit-Nachricht festlegen +# Wenn ein Argument übergeben wurde, nimm das, sonst Zeitstempel +if [ -z "$1" ]; then + MSG="Update vom $(date '+%Y-%m-%d %H:%M:%S')" +else + MSG="$1" +fi + +# 3. Committen +git commit -m "$MSG" + +# 4. Zum Gitea-Server pushen +# Wir gehen davon aus, dass der Remote 'origin' heißt und der Branch 'main' +git push origin main + +echo "---------------------------------------" +echo "✅ Änderungen wurden erfolgreich zu Gitea gepusht!" diff --git a/sky_epg.xml b/sky_epg.xml index 9cfe6b3..e8753be 100644 --- a/sky_epg.xml +++ b/sky_epg.xml @@ -3,8 +3,8 @@ cftv - - Bundesliga 25/26: Borussia M'gladbach - FC St. Pauli - + + App-TV + diff --git a/sky_epg_serve.py b/sky_epg_serve.py new file mode 100644 index 0000000..6055225 --- /dev/null +++ b/sky_epg_serve.py @@ -0,0 +1,16 @@ +import http.server +import socketserver + +PORT = 8889 +FILE_NAME = "sky_epg.xml" # Trage hier den Namen deiner Datei ein + +class SingleFileHandler(http.server.SimpleHTTPRequestHandler): + def do_GET(self): + # Leitet jede Anfrage zwingend auf diese eine Datei um + self.path = '/' + FILE_NAME + return super().do_GET() + +with socketserver.TCPServer(("", PORT), SingleFileHandler) as httpd: + print(f"Server läuft: http://localhost:{PORT}") + print(f"Stellt ausschließlich '{FILE_NAME}' bereit. Zum Beenden STRG+C drücken.") + httpd.serve_forever()