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:
@@ -9,51 +9,51 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
let db;
|
||||
|
||||
export function initDb(dbPath) {
|
||||
const abs = resolve(dbPath);
|
||||
mkdirSync(dirname(abs), { recursive: true });
|
||||
db = new Database(abs);
|
||||
db.pragma('journal_mode = WAL');
|
||||
db.pragma('foreign_keys = ON');
|
||||
const schema = readFileSync(resolve(__dirname, 'schema.sql'), 'utf8');
|
||||
db.exec(schema);
|
||||
runMigrations(db);
|
||||
return db;
|
||||
const abs = resolve(dbPath);
|
||||
mkdirSync(dirname(abs), { recursive: true });
|
||||
db = new Database(abs);
|
||||
db.pragma('journal_mode = WAL');
|
||||
db.pragma('foreign_keys = ON');
|
||||
const schema = readFileSync(resolve(__dirname, 'schema.sql'), 'utf8');
|
||||
db.exec(schema);
|
||||
runMigrations(db);
|
||||
return db;
|
||||
}
|
||||
|
||||
export function getDb() {
|
||||
if (!db) throw new Error('DB not initialized');
|
||||
return db;
|
||||
if (!db) throw new Error('DB not initialized');
|
||||
return db;
|
||||
}
|
||||
|
||||
// Idempotent migrations for upgrading older DBs that pre-date a column.
|
||||
function runMigrations(db) {
|
||||
const stationCols = new Set(db.prepare("PRAGMA table_info(stations)").all().map((c) => c.name));
|
||||
if (!stationCols.has('uuid')) {
|
||||
db.exec('ALTER TABLE stations ADD COLUMN uuid TEXT');
|
||||
}
|
||||
if (!stationCols.has('category')) {
|
||||
db.exec('ALTER TABLE stations ADD COLUMN category TEXT');
|
||||
}
|
||||
const streamCols = new Set(db.prepare("PRAGMA table_info(streams)").all().map((c) => c.name));
|
||||
if (!streamCols.has('uuid')) {
|
||||
db.exec('ALTER TABLE streams ADD COLUMN uuid TEXT');
|
||||
}
|
||||
const stationCols = new Set(db.prepare("PRAGMA table_info(stations)").all().map((c) => c.name));
|
||||
if (!stationCols.has('uuid')) {
|
||||
db.exec('ALTER TABLE stations ADD COLUMN uuid TEXT');
|
||||
}
|
||||
if (!stationCols.has('category')) {
|
||||
db.exec('ALTER TABLE stations ADD COLUMN category TEXT');
|
||||
}
|
||||
const streamCols = new Set(db.prepare("PRAGMA table_info(streams)").all().map((c) => c.name));
|
||||
if (!streamCols.has('uuid')) {
|
||||
db.exec('ALTER TABLE streams ADD COLUMN uuid TEXT');
|
||||
}
|
||||
|
||||
// Backfill UUIDs. For RB stations, prefer the existing source_ref so the
|
||||
// public UUID matches the upstream Radio-Browser stationuuid.
|
||||
const setStationUuid = db.prepare('UPDATE stations SET uuid = ? WHERE id = ?');
|
||||
for (const row of db.prepare("SELECT id, source, source_ref FROM stations WHERE uuid IS NULL OR uuid = ''").all()) {
|
||||
const u = (row.source === 'radiobrowser' && row.source_ref) ? row.source_ref : randomUUID();
|
||||
setStationUuid.run(u, row.id);
|
||||
}
|
||||
// Backfill UUIDs. For RB stations, prefer the existing source_ref so the
|
||||
// public UUID matches the upstream Radio-Browser stationuuid.
|
||||
const setStationUuid = db.prepare('UPDATE stations SET uuid = ? WHERE id = ?');
|
||||
for (const row of db.prepare("SELECT id, source, source_ref FROM stations WHERE uuid IS NULL OR uuid = ''").all()) {
|
||||
const u = (row.source === 'radiobrowser' && row.source_ref) ? row.source_ref : randomUUID();
|
||||
setStationUuid.run(u, row.id);
|
||||
}
|
||||
|
||||
const setStreamUuid = db.prepare('UPDATE streams SET uuid = ? WHERE id = ?');
|
||||
for (const row of db.prepare("SELECT id FROM streams WHERE uuid IS NULL OR uuid = ''").all()) {
|
||||
setStreamUuid.run(randomUUID(), row.id);
|
||||
}
|
||||
const setStreamUuid = db.prepare('UPDATE streams SET uuid = ? WHERE id = ?');
|
||||
for (const row of db.prepare("SELECT id FROM streams WHERE uuid IS NULL OR uuid = ''").all()) {
|
||||
setStreamUuid.run(randomUUID(), row.id);
|
||||
}
|
||||
|
||||
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_stations_uuid ON stations(uuid)');
|
||||
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_streams_uuid ON streams(uuid)');
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_stations_category ON stations(category)');
|
||||
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_stations_uuid ON stations(uuid)');
|
||||
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_streams_uuid ON streams(uuid)');
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_stations_category ON stations(category)');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user