- Shows get a description and an icon upload; broadcasts get a scheduled_at start time. schema.sql adds the columns to existing databases and seeds the descriptions from the old hand-written sidebar. - The dashboard and cli/set_show.php take an optional date and Eastern start time when queuing; index.php shows it with the UTC conversion. - liveBroadcast() and currentShow() ignore broadcasts unseen for longer than the grace period, so a stopped poller can't leave a show stuck as live. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
104 lines
6.3 KiB
SQL
104 lines
6.3 KiB
SQL
-- Radio Free Elsewhere database schema.
|
||
-- Apply with: mysql -u <user> -p <database> < sql/schema.sql
|
||
-- All DATETIME values are stored in UTC (includes/db.php sets the session time zone).
|
||
|
||
CREATE TABLE IF NOT EXISTS shows (
|
||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||
slug VARCHAR(64) NOT NULL UNIQUE,
|
||
name VARCHAR(255) NOT NULL,
|
||
-- Plain text shown on index.php when the show is queued; blank lines separate paragraphs
|
||
description TEXT NULL,
|
||
-- Filename in images/backgrounds/ of the square show logo shown next to the description
|
||
icon_image VARCHAR(255) NULL,
|
||
-- Filename in images/backgrounds/ used as the live.php header background; NULL keeps the default
|
||
background_image VARCHAR(255) NULL,
|
||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
|
||
-- One row per streaming session.
|
||
-- Pending (queued from the dashboard or cli/set_show.php): started_at IS NULL
|
||
-- Live: started_at set, ended_at IS NULL
|
||
-- Ended: ended_at set
|
||
CREATE TABLE IF NOT EXISTS broadcasts (
|
||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||
show_id INT UNSIGNED NULL,
|
||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
-- Advertised start time of a queued show; the broadcast still starts when the stream comes online
|
||
scheduled_at DATETIME NULL,
|
||
started_at DATETIME NULL,
|
||
last_seen_at DATETIME NULL,
|
||
ended_at DATETIME NULL,
|
||
INDEX (started_at),
|
||
INDEX (ended_at),
|
||
FOREIGN KEY (show_id) REFERENCES shows (id) ON DELETE SET NULL
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
|
||
-- Columns added after the first release, for databases created before them
|
||
ALTER TABLE shows ADD COLUMN IF NOT EXISTS description TEXT NULL AFTER name;
|
||
ALTER TABLE shows ADD COLUMN IF NOT EXISTS icon_image VARCHAR(255) NULL AFTER description;
|
||
ALTER TABLE broadcasts ADD COLUMN IF NOT EXISTS scheduled_at DATETIME NULL AFTER created_at;
|
||
|
||
-- Tracks are cleared ten minutes after their broadcast ends.
|
||
CREATE TABLE IF NOT EXISTS played_tracks (
|
||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||
broadcast_id INT UNSIGNED NOT NULL,
|
||
played_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
title VARCHAR(255) NOT NULL,
|
||
artist VARCHAR(255) NOT NULL DEFAULT '',
|
||
album VARCHAR(255) NOT NULL DEFAULT '',
|
||
art_url VARCHAR(512) NOT NULL DEFAULT '',
|
||
INDEX (broadcast_id, played_at),
|
||
FOREIGN KEY (broadcast_id) REFERENCES broadcasts (id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
|
||
-- Admin accounts are created and reset from the command line with cli/create_admin.php
|
||
CREATE TABLE IF NOT EXISTS admins (
|
||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||
username VARCHAR(64) NOT NULL UNIQUE,
|
||
password_hash VARCHAR(255) NOT NULL,
|
||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
last_login_at DATETIME NULL
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
|
||
-- Failed admin logins, used to throttle password guessing
|
||
CREATE TABLE IF NOT EXISTS login_attempts (
|
||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||
ip_address VARCHAR(45) NOT NULL,
|
||
attempted_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
INDEX (ip_address, attempted_at)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
|
||
INSERT IGNORE INTO shows (slug, name) VALUES
|
||
('omorains-pub', 'O''Morain''s Pub'),
|
||
('cosmoeuphoria', 'Cosmoeuphoria'),
|
||
('bisexual-surfers', 'Bisexual Surfers From the Twilight of Time'),
|
||
('the-bollocks', 'The Bollocks'),
|
||
('the-spin', 'The Spin');
|
||
|
||
-- Starting descriptions, taken from the old hand-written index.php. Only fills in blanks, so edits made
|
||
-- on the admin pages survive re-running this file.
|
||
UPDATE shows SET description = 'Sit back, have a pint (or two) and listen in on personally curated Celtic folk. Classics, new favourites, and new takes on old songs from all over the world of Celtic music. Cross the Atlantic from Scotland to Nova Scotia, Ireland to Appalachia, and Brittany to Cape Breton – O’Morain’s Pub has your ticket for fantastic music across the Celtic experience.
|
||
|
||
So raise your glass, you’ve found something a little different from the norm. Sláinte!'
|
||
WHERE slug = 'omorains-pub' AND description IS NULL;
|
||
UPDATE shows SET description = 'Take a trip without leaving your seat.
|
||
|
||
Cast your consciousness across the vastness of the cosmos or explore your own inner space. You need nothing more than a set of speakers or your headphones.
|
||
|
||
Welcome to the worlds of Cosmoeuphoria, where we’ll cross the galactic divides to visit places beyond imagination. Though the magic of space and ambient music, classics and new tracks from the masters of the genres, you’ll never have to worry about flashbacks or passing a drug test.
|
||
|
||
So close your eyes, but maybe open up your third one. Let’s take a journey.'
|
||
WHERE slug = 'cosmoeuphoria' AND description IS NULL;
|
||
UPDATE shows SET description = 'Surf''s up, dude!
|
||
|
||
They came from the darkness of space and time, beautiful surfers with shiny waxed boards to match their shiny waxed bodies. No one knows what they truly want but, for now, we can take solace in the knowledge that they are here to party... and surf. Falling under their spell, we''ll spin surf rock from across the spectrum, horror to rockabilly, instrumental to vocal. We''ll shoot the curve through the pipeline and only god knows what we''ll find on the other side.
|
||
|
||
Beyond the wild waves lies the tempest of spacetime, and they''ll take anyone they please.'
|
||
WHERE slug = 'bisexual-surfers' AND description IS NULL;
|
||
UPDATE shows SET description = 'Punk rock bangers from the well-known to the deep cuts you don''t hear every day.'
|
||
WHERE slug = 'the-bollocks' AND description IS NULL;
|
||
UPDATE shows SET description = 'New (to me) music that I (somewhat) recently found while wandering around the Net or around the airwaves. I''ll drop those new tunes in a playlist and give them a full listen through before adding them to my library. And the name of that playlist?
|
||
|
||
The Spin. Join me, and let''s discover some new tunes!'
|
||
WHERE slug = 'the-spin' AND description IS NULL;
|