Initial TVGuide project
This commit is contained in:
Vendored
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
$xmlFile = '/var/www/epg/guide.xml';
|
||||
|
||||
function parseXmltvTime(string $value): ?DateTime {
|
||||
if (!preg_match('/^(\d{14})\s+([+-]\d{4})$/', trim($value), $m)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt = DateTime::createFromFormat('YmdHis O', $m[1] . ' ' . $m[2]);
|
||||
if (!$dt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt->setTimezone(new DateTimeZone('Europe/Vienna'));
|
||||
return $dt;
|
||||
}
|
||||
|
||||
$channels = [];
|
||||
$programmes = [];
|
||||
|
||||
if (file_exists($xmlFile)) {
|
||||
$xml = simplexml_load_file($xmlFile);
|
||||
|
||||
foreach ($xml->channel as $channel) {
|
||||
$id = (string)$channel['id'];
|
||||
$channels[$id] = [
|
||||
'id' => $id,
|
||||
'name' => (string)$channel->{'display-name'},
|
||||
'icon' => isset($channel->icon) ? (string)$channel->icon['src'] : null,
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($xml->programme as $programme) {
|
||||
$channelId = (string)$programme['channel'];
|
||||
$start = parseXmltvTime((string)$programme['start']);
|
||||
$stop = parseXmltvTime((string)$programme['stop']);
|
||||
|
||||
if (!$start || !$stop) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$programmes[$channelId][] = [
|
||||
'title' => (string)$programme->title,
|
||||
'desc' => (string)$programme->desc,
|
||||
'category' => (string)$programme->category,
|
||||
'start' => $start,
|
||||
'stop' => $stop,
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TVGuide</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: system-ui, sans-serif;
|
||||
background: #101114;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
header {
|
||||
padding: 20px;
|
||||
background: #181a20;
|
||||
border-bottom: 1px solid #2b2f3a;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 20px;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.channel {
|
||||
margin-bottom: 28px;
|
||||
background: #181a20;
|
||||
border: 1px solid #2b2f3a;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.channel-header {
|
||||
padding: 14px 18px;
|
||||
background: #20232c;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.programme {
|
||||
padding: 14px 18px;
|
||||
border-top: 1px solid #2b2f3a;
|
||||
}
|
||||
|
||||
.programme-time {
|
||||
color: #9da7bd;
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.programme-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.programme-desc {
|
||||
color: #c9ced8;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.category {
|
||||
display: inline-block;
|
||||
margin-top: 8px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 999px;
|
||||
background: #303545;
|
||||
color: #cfd6e6;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.empty {
|
||||
color: #aaa;
|
||||
background: #181a20;
|
||||
border: 1px solid #2b2f3a;
|
||||
border-radius: 16px;
|
||||
padding: 18px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>TVGuide</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<?php if (!$channels): ?>
|
||||
<div class="empty">
|
||||
Keine Sender gefunden. Prüfe <code>/opt/tvguide-docker/epg/guide.xml</code>.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ($channels as $channelId => $channel): ?>
|
||||
<section class="channel">
|
||||
<div class="channel-header">
|
||||
<?= htmlspecialchars($channel['name']) ?>
|
||||
</div>
|
||||
|
||||
<?php if (empty($programmes[$channelId])): ?>
|
||||
<div class="programme">
|
||||
<div class="programme-desc">Keine Sendungen gefunden.</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($programmes[$channelId] as $p): ?>
|
||||
<div class="programme">
|
||||
<div class="programme-time">
|
||||
<?= $p['start']->format('H:i') ?> – <?= $p['stop']->format('H:i') ?>
|
||||
</div>
|
||||
<div class="programme-title">
|
||||
<?= htmlspecialchars($p['title']) ?>
|
||||
</div>
|
||||
<?php if ($p['desc']): ?>
|
||||
<div class="programme-desc">
|
||||
<?= htmlspecialchars($p['desc']) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($p['category']): ?>
|
||||
<span class="category"><?= htmlspecialchars($p['category']) ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
<?php endforeach; ?>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user