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,142 @@
|
||||
#!/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 ==="
|
||||
Reference in New Issue
Block a user