Multiple Provider, Rytec Import

This commit is contained in:
Gogs
2026-07-08 13:46:33 +02:00
parent 6d4189730f
commit 7ad81baab6
5 changed files with 2048 additions and 108 deletions
+2
View File
@@ -1,3 +1,5 @@
FROM php:8.4-apache
RUN echo "memory_limit=512M" > /usr/local/etc/php/conf.d/tvguide.ini
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
+51 -29
View File
@@ -8,47 +8,69 @@ $config = new Config(
);
$epg = $config->get('epg', []);
$url = $epg['url'] ?? null;
$urls = $epg['urls'] ?? [];
if (!$url) {
fwrite(STDERR, "Keine epg.url in config.json gesetzt.\n");
if (!$urls && !empty($epg['url'])) {
$urls = [$epg['url']];
}
if (!$urls) {
fwrite(STDERR, "Keine epg.urls in config.json gesetzt.\n");
exit(1);
}
$workDir = '/var/www/epg/work';
$target = '/var/www/epg/guide.xml';
$xzFile = $target . '.xz';
$tmpXml = $target . '.tmp';
echo "Lade EPG: {$url}\n";
if (!is_dir($workDir)) {
mkdir($workDir, 0775, true);
}
$data = file_get_contents($url);
$xmlFiles = [];
if ($data === false || trim($data) === '') {
fwrite(STDERR, "Download fehlgeschlagen oder leer.\n");
foreach ($urls as $index => $url) {
$base = $workDir . '/source-' . $index;
$xzFile = $base . '.xz';
$xmlFile = $base . '.xml';
echo "Lade EPG: {$url}\n";
$data = file_get_contents($url);
if ($data === false || trim($data) === '') {
fwrite(STDERR, "Download fehlgeschlagen oder leer: {$url}\n");
continue;
}
file_put_contents($xzFile, $data);
echo "Entpacke XZ...\n";
$command = 'xz -dc ' . escapeshellarg($xzFile) . ' > ' . escapeshellarg($xmlFile);
exec($command, $output, $code);
if ($code !== 0 || !file_exists($xmlFile) || filesize($xmlFile) === 0) {
fwrite(STDERR, "XZ konnte nicht entpackt werden: {$url}\n");
continue;
}
if (!@simplexml_load_file($xmlFile)) {
fwrite(STDERR, "XML ungültig: {$url}\n");
continue;
}
$xmlFiles[] = $xmlFile;
}
if (!$xmlFiles) {
fwrite(STDERR, "Keine gültigen XMLTV-Dateien geladen.\n");
exit(1);
}
file_put_contents($xzFile, $data);
echo "Merge XMLTV...\n";
echo "Entpacke XZ...\n";
$command = 'xz -dc ' . escapeshellarg($xzFile) . ' > ' . escapeshellarg($tmpXml);
exec($command, $output, $code);
if ($code !== 0 || !file_exists($tmpXml) || filesize($tmpXml) === 0) {
fwrite(STDERR, "XZ konnte nicht entpackt werden.\n");
exit(1);
}
$xml = @simplexml_load_file($tmpXml);
if (!$xml) {
unlink($tmpXml);
fwrite(STDERR, "XML ungültig.\n");
exit(1);
}
rename($tmpXml, $target);
$merge = new XmlTvMergeService();
$merge->merge($xmlFiles, $target);
echo "guide.xml aktualisiert.\n";
+1926 -78
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -7,6 +7,10 @@
"default_view": "today",
"epg": {
"provider": "rytec",
"url": "http://www.xmltvepg.nl/rytecDE_Common.xz"
"urls": [
"http://www.xmltvepg.nl/rytecAT_Basic.xz",
"http://www.xmltvepg.nl/rytecDE_Common.xz",
"http://www.xmltvepg.nl/rytecDE_SportMovies.xz"
]
}
}
+64
View File
@@ -0,0 +1,64 @@
<?php
class XmlTvMergeService
{
public function merge(array $files, string $target): void
{
$merged = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><tv></tv>');
$seenChannels = [];
$seenProgrammes = [];
foreach ($files as $file) {
if (!file_exists($file)) {
continue;
}
$xml = simplexml_load_file($file);
if (!$xml) {
continue;
}
foreach ($xml->channel as $channel) {
$id = (string)$channel['id'];
if ($id === '' || isset($seenChannels[$id])) {
continue;
}
$this->appendXml($merged, $channel);
$seenChannels[$id] = true;
}
foreach ($xml->programme as $programme) {
$channel = (string)$programme['channel'];
$start = (string)$programme['start'];
$stop = (string)$programme['stop'];
$title = trim((string)$programme->title);
$key = md5($channel . '|' . $start . '|' . $stop . '|' . $title);
if (isset($seenProgrammes[$key])) {
continue;
}
$this->appendXml($merged, $programme);
$seenProgrammes[$key] = true;
}
}
$dom = dom_import_simplexml($merged)->ownerDocument;
$dom->formatOutput = true;
$dom->save($target);
}
private function appendXml(SimpleXMLElement $target, SimpleXMLElement $source): void
{
$targetDom = dom_import_simplexml($target);
$sourceDom = dom_import_simplexml($source);
$imported = $targetDom->ownerDocument->importNode($sourceDom, true);
$targetDom->appendChild($imported);
}
}