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>
143 lines
4.4 KiB
Bash
143 lines
4.4 KiB
Bash
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# Local Radio Station — Health Check
|
|
# Reports status of all components
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
INSTALL_DIR="${LOCALRADIO_BASE:-/opt/localradio}"
|
|
ICECAST_URL="http://localhost:8000/status.xsl"
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
ok() { echo -e " ${GREEN}[OK]${NC} $1"; }
|
|
warn() { echo -e " ${YELLOW}[WARN]${NC} $1"; }
|
|
fail() { echo -e " ${RED}[FAIL]${NC} $1"; }
|
|
|
|
echo "=== Local Radio Health Check ==="
|
|
echo ""
|
|
|
|
# --- Service Status -----------------------------------------------------------
|
|
echo "Services:"
|
|
for svc in localradio-icecast localradio-stream localradio-poller; do
|
|
if systemctl is-active --quiet "$svc" 2>/dev/null; then
|
|
ok "$svc is running"
|
|
else
|
|
fail "$svc is NOT running"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
# --- Icecast Connectivity -----------------------------------------------------
|
|
echo "Icecast:"
|
|
if curl -s --max-time 3 "$ICECAST_URL" > /dev/null 2>&1; then
|
|
ok "Icecast responding at $ICECAST_URL"
|
|
else
|
|
fail "Icecast not responding"
|
|
fi
|
|
|
|
# Check if stream mount is active
|
|
if curl -s --max-time 3 -o /dev/null -w "%{http_code}" "http://localhost:8000/stream" 2>/dev/null | grep -q "200"; then
|
|
ok "Stream mount /stream is active"
|
|
else
|
|
warn "Stream mount /stream not active (may need listeners)"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# --- Music Directories --------------------------------------------------------
|
|
echo "Music directories:"
|
|
for dir in morning day night weekend; do
|
|
full_path="$INSTALL_DIR/media/music/$dir"
|
|
if [ -d "$full_path" ]; then
|
|
count=$(find "$full_path" -type f \( -name "*.mp3" -o -name "*.flac" -o -name "*.ogg" -o -name "*.opus" -o -name "*.m4a" -o -name "*.wav" \) 2>/dev/null | wc -l)
|
|
if [ "$count" -gt 0 ]; then
|
|
ok "$dir: $count audio files"
|
|
else
|
|
warn "$dir: empty (no audio files)"
|
|
fi
|
|
else
|
|
fail "$dir: directory missing"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
# --- Fallback -----------------------------------------------------------------
|
|
echo "Fallback:"
|
|
fallback_dir="$INSTALL_DIR/media/fallback"
|
|
if [ -d "$fallback_dir" ]; then
|
|
count=$(find "$fallback_dir" -type f \( -name "*.mp3" -o -name "*.flac" -o -name "*.ogg" -o -name "*.opus" -o -name "*.m4a" -o -name "*.wav" \) 2>/dev/null | wc -l)
|
|
if [ "$count" -gt 0 ]; then
|
|
ok "Fallback: $count audio files"
|
|
else
|
|
fail "Fallback: EMPTY — stream will go silent if all music dirs are empty!"
|
|
fi
|
|
else
|
|
fail "Fallback directory missing"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# --- Queue Status -------------------------------------------------------------
|
|
echo "Podcast queue:"
|
|
queue_dir="$INSTALL_DIR/state/queue"
|
|
if [ -d "$queue_dir" ]; then
|
|
queue_count=$(find "$queue_dir" -maxdepth 1 -type l -o -type f 2>/dev/null | wc -l)
|
|
if [ "$queue_count" -gt 0 ]; then
|
|
ok "$queue_count episode(s) in queue"
|
|
echo " Queue contents:"
|
|
ls -1 "$queue_dir" 2>/dev/null | head -10 | while read -r f; do
|
|
echo " - $f"
|
|
done
|
|
else
|
|
ok "Queue empty (music playing)"
|
|
fi
|
|
else
|
|
warn "Queue directory missing"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# --- Database -----------------------------------------------------------------
|
|
echo "Database:"
|
|
db_path="$INSTALL_DIR/state/radio.db"
|
|
if [ -f "$db_path" ]; then
|
|
ep_count=$(sqlite3 "$db_path" "SELECT COUNT(*) FROM episodes;" 2>/dev/null || echo "?")
|
|
queued=$(sqlite3 "$db_path" "SELECT COUNT(*) FROM queue WHERE played=0;" 2>/dev/null || echo "?")
|
|
feeds=$(sqlite3 "$db_path" "SELECT COUNT(*) FROM feed_state;" 2>/dev/null || echo "?")
|
|
ok "Database exists: $ep_count episodes tracked, $queued queued, $feeds feeds polled"
|
|
else
|
|
warn "Database not found (run init_db.py)"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# --- Feeds Config -------------------------------------------------------------
|
|
echo "Feeds config:"
|
|
feeds_file="$INSTALL_DIR/config/feeds.yaml"
|
|
if [ -f "$feeds_file" ]; then
|
|
ok "feeds.yaml exists"
|
|
else
|
|
fail "feeds.yaml not found"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# --- Recent Logs --------------------------------------------------------------
|
|
echo "Recent poller log:"
|
|
log_file="$INSTALL_DIR/logs/poller.log"
|
|
if [ -f "$log_file" ]; then
|
|
tail -5 "$log_file" | while read -r line; do
|
|
echo " $line"
|
|
done
|
|
else
|
|
warn "No poller log yet"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Health check complete ==="
|