Initial commit: self-hosted personal radio station
Flask + React web UI with audio player, podcast queue, feed management, episode browser, music library, schedule viewer, and log tail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Show the current podcast queue and episode history."""
|
||||
|
||||
import os
|
||||
import sqlite3
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
BASE_DIR = Path(os.environ.get("LOCALRADIO_BASE", "/opt/localradio"))
|
||||
DB_PATH = BASE_DIR / "state" / "radio.db"
|
||||
QUEUE_DIR = BASE_DIR / "state" / "queue"
|
||||
|
||||
|
||||
def show_queue():
|
||||
if not DB_PATH.exists():
|
||||
print("Database not found. Run init_db.py first.")
|
||||
sys.exit(1)
|
||||
|
||||
conn = sqlite3.connect(str(DB_PATH))
|
||||
conn.row_factory = sqlite3.Row
|
||||
|
||||
# Current queue
|
||||
rows = conn.execute("""
|
||||
SELECT q.position, e.feed_name, e.title, e.pub_date, e.file_path, q.enqueued
|
||||
FROM queue q
|
||||
JOIN episodes e ON e.id = q.episode_id
|
||||
WHERE q.played = 0
|
||||
ORDER BY q.position
|
||||
""").fetchall()
|
||||
|
||||
print("=== Podcast Queue ===")
|
||||
if rows:
|
||||
for row in rows:
|
||||
print(f" [{row['position']:3d}] {row['feed_name']}: {row['title']}")
|
||||
print(f" Published: {row['pub_date'] or 'unknown'}")
|
||||
print(f" Enqueued: {row['enqueued']}")
|
||||
else:
|
||||
print(" (empty — music is playing)")
|
||||
|
||||
# Queue directory
|
||||
print(f"\n=== Queue Directory ({QUEUE_DIR}) ===")
|
||||
if QUEUE_DIR.exists():
|
||||
files = sorted(QUEUE_DIR.iterdir())
|
||||
if files:
|
||||
for f in files:
|
||||
target = f" -> {os.readlink(f)}" if f.is_symlink() else ""
|
||||
print(f" {f.name}{target}")
|
||||
else:
|
||||
print(" (empty)")
|
||||
else:
|
||||
print(" (directory missing)")
|
||||
|
||||
# Recent episodes
|
||||
recent = conn.execute("""
|
||||
SELECT feed_name, title, pub_date, downloaded, queued, played, discovered
|
||||
FROM episodes
|
||||
ORDER BY discovered DESC
|
||||
LIMIT 15
|
||||
""").fetchall()
|
||||
|
||||
print("\n=== Recent Episodes (last 15) ===")
|
||||
for row in recent:
|
||||
status_flags = []
|
||||
if row["downloaded"]:
|
||||
status_flags.append("DL")
|
||||
if row["queued"]:
|
||||
status_flags.append("Q")
|
||||
if row["played"]:
|
||||
status_flags.append("P")
|
||||
status = ",".join(status_flags) or "-"
|
||||
print(f" [{status:6s}] {row['feed_name']}: {row['title']}")
|
||||
|
||||
# Feed state
|
||||
feeds = conn.execute("SELECT * FROM feed_state ORDER BY feed_name").fetchall()
|
||||
print("\n=== Feed State ===")
|
||||
for f in feeds:
|
||||
print(f" {f['feed_name']}: last polled {f['last_poll'] or 'never'}")
|
||||
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
show_queue()
|
||||
Reference in New Issue
Block a user