Hallo
Ich habeSie müssen registriert sein, um Links zu sehen.genauso in Tivimate epg quelle eingetragen
und zur Wiedergabeliste hinzugefügt.
Nach Aktualisierung bekomme ich immer die Meldung, Stelle sicher dass die epg-url korrekt ist.
Was mache ich falsch?
welche channels meinst denn genau?Magenta Sport und Magenta Musik wären noch nett
import os
import re
import requests
import xml.etree.ElementTree as ET
from xml.dom import minidom
from datetime import datetime, timezone
import warnings
TARGET_CHANNELS = [
"NBA TV", "NFL Network", "Unbeaten", "MLB Network", "PLL Network",
"PowerSports World", "Boxing TV", "Matchroom Boxing", "PDC Darts",
"Billiard TV", "ACL Cornhole TV"
]
def sanitize_id(name: str) -> str:
base = name.strip().split(".", 1)[0]
base_clean = re.sub(r'[^A-Za-z0-9]', '', base)
return f"{base_clean}.de"
def format_xmltv_time(iso_str: str) -> str:
try:
dt = datetime.fromisoformat(iso_str.replace("Z", "+00:00"))
if dt.tzinfo is not None:
dt = dt.astimezone(timezone.utc)
else:
dt = dt.replace(tzinfo=timezone.utc)
return dt.strftime("%Y%m%d%H%M%S") + " +0000"
except Exception:
return ""
def extract_target_tiles(epg_data):
found = {}
def match_title(title):
return any(title.strip().lower() == ch.lower() for ch in TARGET_CHANNELS)
if isinstance(epg_data, dict):
if "Tiles" in epg_data and isinstance(epg_data["Tiles"], list):
for tile in epg_data["Tiles"]:
title = (tile.get("Title") or tile.get("Name") or "").strip()
if title and match_title(title):
found[title] = tile
for val in epg_data.values():
if isinstance(val, list):
for entry in val:
if not isinstance(entry, dict):
continue
title = (entry.get("Title") or entry.get("Name") or "").strip()
if title and match_title(title):
found[title] = entry
elif isinstance(epg_data, list):
for entry in epg_data:
if not isinstance(entry, dict):
continue
title = (entry.get("Title") or entry.get("Name") or "").strip()
if title and match_title(title):
found[title] = entry
return list(found.values())
f'https://rail-router.discovery.indazn.com/eu/v10/Rail'
f'?platform=web&id=Livetvschedule&country={country}&languageCode={country}'
)
resp = requests.get(url, headers=headers, proxies=proxies, verify=False, timeout=10)
resp.raise_for_status()
return resp.json()
def build_xmltv(epg_data):
tiles = extract_target_tiles(epg_data)
if not tiles:
print("No matching target channels found in EPG JSON.")
return
tv = ET.Element("tv", {"generator-info-name": "dazn_epg_from_json"})
channel_map = {}
for tile in tiles:
title = (tile.get("Title") or tile.get("Name") or "").strip()
if not title:
continue
ch_id = sanitize_id(title)
channel_map[title] = ch_id
ch_elem = ET.SubElement(tv, "channel", {"id": ch_id})
dn = ET.SubElement(ch_elem, "display-name")
dn.text = title
desc = tile.get("Description") or tile.get("LongDescription") or tile.get("ShortDescription")
if desc:
d = ET.SubElement(ch_elem, "desc")
d.text = desc
for tile in tiles:
title = (tile.get("Title") or tile.get("Name") or "").strip()
ch_id = channel_map.get(title)
if not ch_id:
continue
linear = tile.get("LinearSchedule", {}) or {}
programs = []
if linear.get("Now"):
programs.append(linear["Now"])
if linear.get("Next"):
programs.append(linear["Next"])
if isinstance(linear.get("Later"), list):
programs.extend(linear["Later"])
if not programs:
for key in ("Programs", "Programmes", "Items", "Entries"):
alt = tile.get(key)
if isinstance(alt, list):
programs.extend(alt)
for prog in programs:
if not isinstance(prog, dict):
continue
prog_title = (prog.get("Title") or "").strip()
episode = (prog.get("EpisodeTitle") or "").strip()
full_title = prog_title if not episode else f"{prog_title} - {episode}"
desc = (prog.get("Description") or "").strip()
start = prog.get("Start")
end = prog.get("End")
if not start or not end:
continue
start_fmt = format_xmltv_time(start)
end_fmt = format_xmltv_time(end)
if not start_fmt or not end_fmt:
continue
p_attrib = {"start": start_fmt, "stop": end_fmt, "channel": ch_id}
p_elem = ET.SubElement(tv, "programme", p_attrib)
t_elem = ET.SubElement(p_elem, "title")
t_elem.text = full_title or prog_title or "Unknown"
if desc:
d_elem = ET.SubElement(p_elem, "desc")
d_elem.text = desc
genres = prog.get("Genre") or prog.get("Genres") or []
if isinstance(genres, list):
for g in genres:
if isinstance(g, dict):
name = g.get("name") or g.get("Name")
else:
name = str(g)
if name:
c = ET.SubElement(p_elem, "category")
c.text = name
elif isinstance(genres, str) and genres.strip():
c = ET.SubElement(p_elem, "category")
c.text = genres.strip()
year = prog.get("EventYear") or prog.get("Year")
if year:
y = ET.SubElement(p_elem, "year")
y.text = str(year)
rough = ET.tostring(tv, encoding="utf-8")
reparsed = minidom.parseString(rough)
pretty = reparsed.toprettyxml(indent=" ")
try:
base_dir = os.path.dirname(os.path.abspath(__file__))
target_dir = os.path.abspath(os.path.join(base_dir, "..", "manager", "temp"))
os.makedirs(target_dir, exist_ok=True)
target_path = os.path.join(target_dir, "daznepg.xml")
with open(target_path, "w", encoding="utf-8") as f:
f.write(pretty)
try:
import pwd, grp
uid = pwd.getpwnam("http").pw_uid
gid = grp.getgrnam("http").gr_gid
os.chown(target_path, uid, gid)
except Exception as e:
print(f"Warning: could not chown to http:http: {e}")
try:
os.chmod(target_path, 0o755)
except Exception as e:
print(f"Warning: could not chmod 755: {e}")
print(f"Written XMLTV EPG to {target_path} (owner http:http, mode 755 attempted)")
except Exception as e:
print(f"Failed writing XMLTV: {e}")
def main():
if __name__ == "__main__":
main()
Wir verwenden Cookies und ähnliche Technologien für folgende Zwecke:
Akzeptieren Sie Cookies und diese Technologien?
Wir verwenden Cookies und ähnliche Technologien für folgende Zwecke:
Akzeptieren Sie Cookies und diese Technologien?