Add API documentation and underground station importer

- Introduced a new HTML documentation page for the oradio API, including a JavaScript file to handle dynamic content and API requests.
- Added a CSS file for styling the documentation page.
- Implemented an underground station importer script that fetches data from Radio-Browser and writes it to a JSON file.
- Created a stats module to compute and manage vote and play statistics for radio stations.
- Added a polyfill for modulepreload to ensure compatibility with older browsers.
This commit is contained in:
Marco Mooren
2026-05-11 02:06:48 +02:00
parent e0a60f7b64
commit 00246389bc
52 changed files with 6280 additions and 2475 deletions

View File

@@ -78,3 +78,23 @@ CREATE TABLE IF NOT EXISTS play_history (
);
CREATE INDEX IF NOT EXISTS idx_history_user ON play_history(user_id, started_at DESC);
CREATE INDEX IF NOT EXISTS idx_history_station ON play_history(station_id);
-- One vote per user per station. value is +1 (up) or -1 (down). Row is
-- deleted entirely when the user clears their vote, so the COUNT is exact.
CREATE TABLE IF NOT EXISTS station_votes (
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
station_id INTEGER NOT NULL REFERENCES stations(id) ON DELETE CASCADE,
value INTEGER NOT NULL CHECK (value IN (-1, 1)),
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, station_id)
);
CREATE INDEX IF NOT EXISTS idx_votes_station ON station_votes(station_id);
-- Aggregate play counter. Cheaper than COUNT(*) over play_history every render
-- and lets anonymous/public listing show play counts without exposing history.
CREATE TABLE IF NOT EXISTS station_plays (
station_id INTEGER PRIMARY KEY REFERENCES stations(id) ON DELETE CASCADE,
plays INTEGER NOT NULL DEFAULT 0,
last_played_at TEXT
);