= htmlspecialchars($p['stop']->format('H:i')) ?>
diff --git a/export.php b/export.php index a79b8a8..4a58d45 100644 --- a/export.php +++ b/export.php @@ -156,113 +156,6 @@ function export_take_entries(array $entries, callable $filter, int $limit = 4): return $picked; } -function export_programme_label(array $programme): string { - if (export_programme_has_category($programme, ['document', 'docu', 'biopic', 'history', 'histoire'])) { - return 'Documentaire'; - } - if (export_programme_is_series($programme)) { - return 'Serie'; - } - if (export_programme_duration($programme) >= 80) { - return 'Film'; - } - return 'Selection'; -} - -function export_entry_tease(array $entry): string { - $programme = $entry['programme']; - if (!empty($programme['subtitle'])) { - return $programme['subtitle']; - } - if (!empty($programme['categories'])) { - return implode(' · ', array_slice($programme['categories'], 0, 3)); - } - if (!empty($programme['desc'])) { - return mb_strimwidth($programme['desc'], 0, 120, '…'); - } - return 'A suivre sur ' . $entry['channel_name']; -} - -function export_build_magazine(array $channels): array { - $all = []; - foreach ($channels as $channel) { - foreach ($channel['programmes'] as $programme) { - $all[] = [ - 'channel_name' => $channel['name'], - 'channel_icon' => $channel['icon'], - 'programme' => $programme, - 'weight' => export_programme_weight($programme), - ]; - } - } - - usort($all, static function ($a, $b) { - return $b['weight'] <=> $a['weight'] - ?: $a['programme']['start'] <=> $b['programme']['start'] - ?: strcmp($a['channel_name'], $b['channel_name']); - }); - - $highlights = array_slice($all, 0, 5); - $series = export_take_entries($all, static fn($entry) => export_programme_is_series($entry['programme']), 4); - $movies = export_take_entries($all, static fn($entry) => !export_programme_is_series($entry['programme']) && export_programme_duration($entry['programme']) >= 80, 4); - $late_picks = export_take_entries($all, static fn($entry) => (int) $entry['programme']['start']->format('H') >= 21, 4); - $docs = export_take_entries($all, static fn($entry) => export_programme_has_category($entry['programme'], ['document', 'biopic', 'history', 'histoire']), 4); - $premieres = export_take_entries( - $all, - static fn($entry) => export_programme_is_series($entry['programme']) && !empty($entry['programme']['subtitle']), - 4 - ); - - $by_channel = []; - foreach ($channels as $channel) { - $by_channel[] = [ - 'name' => $channel['name'], - 'icon' => $channel['icon'], - 'programmes' => array_slice($channel['programmes'], 0, 6), - ]; - } - - $sections = [ - [ - 'slug' => 'top-picks', - 'title' => 'Ce soir a la tele', - 'kicker' => 'Selection de la redaction', - 'intro' => 'Les programmes qui donnent envie de garder la tele allumee ce soir.', - 'items' => array_slice($highlights, 0, 4), - ], - [ - 'slug' => 'series', - 'title' => 'Nouvelles series diffusees', - 'kicker' => 'Episodes et rendez-vous', - 'intro' => 'Les feuilletons, rediffusions premium et lancements du moment.', - 'items' => $premieres ?: ($series ?: array_slice($highlights, 0, 4)), - ], - [ - 'slug' => 'movies', - 'title' => 'Films de la selection', - 'kicker' => 'Longs formats', - 'intro' => 'Le bloc cinema de la journee, entre classiques, blockbusters et belles surprises.', - 'items' => $movies ?: array_slice($highlights, 0, 4), - ], - [ - 'slug' => 'docs', - 'title' => 'Docs et recits de vie', - 'kicker' => 'Documentaires / biopics', - 'intro' => 'Pour les amateurs de recits, d histoires vraies et de programmes a contexte.', - 'items' => $docs ?: $late_picks ?: array_slice($highlights, 0, 4), - ], - [ - 'slug' => 'prime', - 'title' => 'Prime time', - 'kicker' => 'A partir de 21h', - 'intro' => 'Les rendez-vous les plus costauds de la tranche du soir.', - 'items' => $late_picks ?: array_slice($highlights, 0, 4), - ], - ]; - - return ['lead' => $highlights[0] ?? null, 'highlights' => $highlights, 'channels' => $by_channel, 'sections' => $sections]; -} - $sources = array_values($config['epg_sources'] ?? []); $source_index = max(0, min((int) ($_GET['source'] ?? 0), max(count($sources) - 1, 0))); $source = $sources[$source_index] ?? null; @@ -270,7 +163,7 @@ $target_day = preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) ($_GET['day'] ?? '')) $layout_input = isset($_GET['layout']) ? (string) $_GET['layout'] : 'cards'; $limit_input = isset($_GET['limit']) ? (string) $_GET['limit'] : '8'; $window_input = isset($_GET['window']) ? (string) $_GET['window'] : 'full'; -$layout = in_array($layout_input, ['cards', 'timeline', 'magazine'], true) ? $layout_input : 'cards'; +$layout = in_array($layout_input, ['cards', 'timeline'], true) ? $layout_input : 'cards'; $limit = in_array($limit_input, ['4', '8', 'all'], true) ? $limit_input : '8'; $windows = export_window_definitions($target_day); $window_key = array_key_exists($window_input, $windows) ? $window_input : 'full'; @@ -292,8 +185,7 @@ if ($limit !== 'all') { } $day_label = (new DateTimeImmutable($target_day))->format('l d F Y'); -$layout_label = $layout === 'cards' ? 'Readable cards' : ($layout === 'timeline' ? 'Dense timeline' : 'TV magazine'); -$magazine = export_build_magazine($visible_channels); +$layout_label = $layout === 'cards' ? 'Readable cards' : 'Dense timeline'; ?>
@@ -337,50 +229,6 @@ $magazine = export_build_magazine($visible_channels); .prog-title{font-size:16px;font-weight:700;line-height:1.08} .prog-sub,.prog-cats,.prog-desc{font-size:12px;color:var(--ink-soft);line-height:1.3;margin-top:2px} .prog-desc{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden} -.magazine{display:grid;gap:20px} -.mag-banner{display:grid;grid-template-columns:1.1fr .9fr;gap:18px;background:linear-gradient(135deg,#8b2d20 0,#4c2019 60%,#1f1a17 100%);color:#f7efe3;padding:18px;border:1px solid rgba(255,255,255,.14)} -.mag-banner-title{font-family:'IM Fell English',serif;font-size:48px;line-height:1.02;margin:0 0 8px} -.mag-banner-sub{font-size:15px;line-height:1.45;color:#f0dcca;max-width:540px} -.mag-banner-meta{display:flex;gap:10px;flex-wrap:wrap;align-content:flex-start;justify-content:flex-end} -.mag-banner-meta span{border:1px solid rgba(255,255,255,.22);padding:7px 10px;font-family:'Share Tech Mono',monospace;font-size:11px;letter-spacing:.08em;text-transform:uppercase} -.mag-hero{display:grid;grid-template-columns:1.3fr .9fr;gap:18px} -.mag-lead,.mag-side,.mag-channel{background:rgba(255,255,255,.35);border:1px solid var(--line);padding:16px} -.mag-kicker{font-family:'Share Tech Mono',monospace;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-2);margin-bottom:8px} -.mag-title{font-family:'IM Fell English',serif;font-size:38px;line-height:1.02;margin-bottom:10px} -.mag-meta{font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--ink-soft);letter-spacing:.04em;margin-bottom:10px} -.mag-desc{font-size:14px;line-height:1.45;color:var(--ink-soft)} -.mag-side-list,.mag-channels,.mag-sections{display:grid;gap:14px} -.mag-mini-title{font-size:18px;font-weight:700;line-height:1.08} -.mag-mini{padding-top:12px;border-top:1px dashed var(--line)} -.mag-mini:first-child{padding-top:0;border-top:none} -.mag-channels{grid-template-columns:repeat(2,minmax(0,1fr))} -.mag-channel-head{display:flex;gap:10px;align-items:center;border-bottom:2px solid var(--accent-2);padding-bottom:8px;margin-bottom:10px} -.mag-channel-head img{width:38px;height:38px;object-fit:contain;background:#fff;border:1px solid var(--line);padding:4px} -.mag-channel-name{font-size:20px;font-weight:700;line-height:1.05} -.mag-list{display:grid;gap:8px} -.mag-item{display:grid;grid-template-columns:74px 1fr;gap:10px;padding-top:8px;border-top:1px dashed var(--line)} -.mag-item:first-child{padding-top:0;border-top:none} -.mag-time{font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--accent-2)} -.mag-item-title{font-size:15px;font-weight:700;line-height:1.08} -.mag-sections{grid-template-columns:repeat(2,minmax(0,1fr))} -.mag-section{background:rgba(255,255,255,.48);border:1px solid var(--line);padding:18px;position:relative;overflow:hidden} -.mag-section::before{content:'';position:absolute;left:0;top:0;bottom:0;width:6px;background:linear-gradient(180deg,var(--accent),rgba(170,66,49,.1))} -.mag-section.featured{background:linear-gradient(180deg,rgba(170,66,49,.16),rgba(255,255,255,.48))} -.mag-section-head{padding-left:8px;margin-bottom:12px} -.mag-section-title{font-family:'IM Fell English',serif;font-size:32px;line-height:1;margin:0 0 8px} -.mag-section-intro{font-size:13px;line-height:1.45;color:var(--ink-soft);max-width:44ch} -.mag-spotlight{display:grid;grid-template-columns:110px 1fr;gap:14px;padding:14px 0;border-top:1px solid rgba(38,70,83,.15);border-bottom:1px solid rgba(38,70,83,.15);margin-bottom:12px} -.mag-spotlight-time{font-family:'Share Tech Mono',monospace;font-size:12px;color:var(--accent-2);letter-spacing:.06em} -.mag-badge{display:inline-flex;align-items:center;padding:4px 8px;background:#f1dfc2;color:#5f2e20;font-family:'Share Tech Mono',monospace;font-size:10px;letter-spacing:.08em;text-transform:uppercase;border:1px solid rgba(170,66,49,.22);margin-bottom:8px} -.mag-spotlight-title{font-size:24px;font-weight:700;line-height:1.03;margin-bottom:6px} -.mag-spotlight-tease{font-size:13px;line-height:1.45;color:var(--ink-soft)} -.mag-briefs{display:grid;gap:10px} -.mag-brief{display:grid;grid-template-columns:74px 1fr;gap:10px;padding-top:10px;border-top:1px dashed var(--line)} -.mag-brief:first-child{padding-top:0;border-top:none} -.mag-brief-time{font-family:'Share Tech Mono',monospace;font-size:11px;color:var(--accent-2)} -.mag-brief-title{font-size:16px;font-weight:700;line-height:1.08} -.mag-brief-tease{font-size:12px;color:var(--ink-soft);line-height:1.35;margin-top:2px} -.mag-footer-title{margin-top:8px} .timeline-wrap{display:grid;gap:14px} .timeline-row{display:grid;grid-template-columns:180px 1fr;gap:14px;align-items:stretch} .timeline-channel{border-top:2px solid var(--accent-2);padding-top:8px} @@ -392,7 +240,7 @@ $magazine = export_build_magazine($visible_channels); .mini-title{font-size:13px;font-weight:700;line-height:1.05} .mini-meta{font-family:'Share Tech Mono',monospace;font-size:10px;color:var(--ink-soft);margin-top:3px} @media print{body{background:#fff}.page{padding:0}.toolbar{display:none}.sheet{box-shadow:none;border:none;width:auto;margin:0}.sheet-wrap{overflow:visible}.cards-grid{grid-template-columns:1fr 1fr}} -@media (max-width:1200px){.sheet{width:100%}.cards-grid,.mag-channels,.mag-hero,.mag-sections,.mag-banner,.mag-spotlight{grid-template-columns:1fr}.timeline-row{grid-template-columns:1fr}.timeline-grid{overflow:auto}} +@media (max-width:1200px){.sheet{width:100%}.cards-grid{grid-template-columns:1fr}.timeline-row{grid-template-columns:1fr}.timeline-grid{overflow:auto}} @@ -422,14 +270,12 @@ $magazine = export_build_magazine($visible_channels); - Health Guide @@ -451,7 +297,6 @@ $magazine = export_build_magazine($visible_channels); = htmlspecialchars($window['label']) ?> = count($visible_channels) ?> channel(s) = htmlspecialchars($layout_label) ?> - Generated from XMLTV @@ -526,111 +371,9 @@ $items = array_values(array_filter($channel['programmes'], static fn($p) => $p[' - -