Add recently played tracking with shows and broadcasts

- sql/schema.sql: shows, broadcasts and played_tracks tables, seeded
  with the five shows
- cli/poll_icecast.php: cron-run poller that records broadcasts and
  tracks every 15 seconds while streaming; tracks are cleared ten
  minutes after a broadcast ends
- cli/set_show.php: queue the next show, or assign one to the live
  broadcast
- recently_played.php: track history rows for live.php, with album art
  and album title linking to Last.fm
- live.php: recently played list, show name in heading, and per-show
  header background
- includes/icecast.php: Icecast parsing, album art and Last.fm helpers
  shared by now_playing.php and the poller
- includes/db.php: use UTC for the database session

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daniel MesserandClaude Opus 5.5 committed 2026-10-29 06:45:44 -05:00
1 parent 9a1e8a33a6
commit 74dfb3c146
11 files changed
+417 -50

No files matched your search

+41
View File
@@ -0,0 +1,41 @@
<?php
// Returns the recently played list for live.php as table rows. Polled alongside now_playing.php.
header('Content-Type: text/html; charset=utf-8');
require __DIR__ . '/includes/db.php';
require __DIR__ . '/includes/broadcasts.php';
function e(string $s): string {
return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
try {
$tracks = recentTracks(getDB());
} catch (Throwable $e) {
echo '<tr><td colspan="5">Unable to load recently played tracks.</td></tr>';
exit;
}
if (!$tracks) {
echo '<tr><td colspan="5">Nothing played yet. Tracks will appear here once the show is under way.</td></tr>';
exit;
}
foreach ($tracks as $t) {
// Album art and album title link to the album on Last.fm
$albumUrl = ($t['artist'] !== '' && $t['album'] !== '') ? lastfmAlbumUrl($t['artist'], $t['album']) : '';
$openLink = $albumUrl !== '' ? '<a href="' . e($albumUrl) . '" target="_blank" rel="noopener">' : '';
$closeLink = $albumUrl !== '' ? '</a>' : '';
// Stored in UTC; live.php reformats this in the listener's local time
$iso = str_replace(' ', 'T', $t['played_at']) . 'Z';
$fallback = substr($t['played_at'], 11, 5) . ' UTC';
echo '<tr>';
echo '<td class="track-art">' . ($t['art_url'] !== '' ? $openLink . '<img src="' . e($t['art_url']) . '" alt="Album art for ' . e($t['album']) . '">' . $closeLink : '') . '</td>';
echo '<td><time datetime="' . e($iso) . '">' . e($fallback) . '</time></td>';
echo '<td>' . e($t['title']) . '</td>';
echo '<td>' . e($t['artist']) . '</td>';
echo '<td>' . $openLink . e($t['album']) . $closeLink . '</td>';
echo '</tr>';
}