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>
89 lines
2.3 KiB
Python
89 lines
2.3 KiB
Python
"""GET /api/status — stream status, now playing, queue depth, current schedule."""
|
|
|
|
import os
|
|
from datetime import datetime
|
|
|
|
import yaml
|
|
from flask import Blueprint, jsonify
|
|
|
|
from ..config import BASE_DIR, STATION_CONFIG
|
|
from ..db import get_db
|
|
|
|
bp = Blueprint("status", __name__)
|
|
|
|
|
|
def _get_current_schedule_block():
|
|
"""Determine which schedule block is active right now."""
|
|
try:
|
|
with open(STATION_CONFIG) as f:
|
|
config = yaml.safe_load(f)
|
|
except Exception:
|
|
return None
|
|
|
|
now = datetime.now()
|
|
current_day = now.isoweekday() # 1=Mon ... 7=Sun
|
|
current_time = now.strftime("%H:%M")
|
|
|
|
for block in config.get("schedule", []):
|
|
if current_day not in block.get("days", []):
|
|
continue
|
|
start = block.get("start", "00:00")
|
|
end = block.get("end", "23:59")
|
|
|
|
# Handle overnight blocks (e.g., 18:00 - 06:00)
|
|
if start <= end:
|
|
if start <= current_time <= end:
|
|
return block
|
|
else:
|
|
if current_time >= start or current_time <= end:
|
|
return block
|
|
|
|
return None
|
|
|
|
|
|
def _get_stream_status():
|
|
"""Check if music files are available for streaming."""
|
|
music_dir = os.path.join(BASE_DIR, "media", "music")
|
|
fallback_dir = os.path.join(BASE_DIR, "media", "fallback")
|
|
count = 0
|
|
for d in (music_dir, fallback_dir):
|
|
if not os.path.isdir(d):
|
|
continue
|
|
for dirpath, _dirs, filenames in os.walk(d):
|
|
count += sum(1 for f in filenames if f.lower().endswith(".mp3"))
|
|
return {
|
|
"online": count > 0,
|
|
"tracks": count,
|
|
}
|
|
|
|
|
|
@bp.route("/status")
|
|
def status():
|
|
db = get_db()
|
|
|
|
queue_depth = db.execute(
|
|
"SELECT COUNT(*) as c FROM queue WHERE played=0"
|
|
).fetchone()["c"]
|
|
|
|
total_episodes = db.execute(
|
|
"SELECT COUNT(*) as c FROM episodes"
|
|
).fetchone()["c"]
|
|
|
|
active_feeds = db.execute(
|
|
"SELECT COUNT(*) as c FROM feed_state"
|
|
).fetchone()["c"]
|
|
|
|
stream = _get_stream_status()
|
|
block = _get_current_schedule_block()
|
|
|
|
return jsonify({
|
|
"stream": stream,
|
|
"queue_depth": queue_depth,
|
|
"total_episodes": total_episodes,
|
|
"active_feeds": active_feeds,
|
|
"current_block": {
|
|
"name": block["name"],
|
|
"folder": block["folder"],
|
|
} if block else None,
|
|
})
|