#!/usr/bin/env bash # install_for_python - Provision the Python-based radio automation stack. # Must be run as root from within the target directory (e.g. /srv/radio/). # Idempotent: safe to re-run. set -euo pipefail INSTALL_DIR="$(pwd)" SERVICE_NAME="$(basename "$INSTALL_DIR")" VENV="$INSTALL_DIR/.venv" PYTHON_BIN="$VENV/bin/python" echo "=== Radio Automation Installer (Python) ===" echo "Install dir: $INSTALL_DIR" echo "Service name: $SERVICE_NAME" echo # --- Prompt for config values (pre-fill from existing config.json) --- EXISTING_CONFIG="$INSTALL_DIR/config.json" declare -A CFG CFG[ICE_HOST]="localhost" CFG[ICE_PORT]="7777" CFG[ICE_MOUNT]="/audio.mp3" CFG[ICE_USER]="source" CFG[ICE_PASS]="" CFG[GPODDER_ENABLE]="false" CFG[GPODDER_HOST]="https://gpodder.net" CFG[GPODDER_USER]="" CFG[GPODDER_PASS]="" if [[ -f "$EXISTING_CONFIG" ]]; then echo "Existing config.json found; using as defaults." CFG[ICE_HOST]=$(jq -r '.icecast.host // "localhost"' "$EXISTING_CONFIG") CFG[ICE_PORT]=$(jq -r '.icecast.port // 7777' "$EXISTING_CONFIG") CFG[ICE_MOUNT]=$(jq -r '.icecast.mount // "/audio.mp3"' "$EXISTING_CONFIG") CFG[ICE_USER]=$(jq -r '.icecast.username // "source"' "$EXISTING_CONFIG") CFG[ICE_PASS]=$(jq -r '.icecast.password // ""' "$EXISTING_CONFIG") CFG[GPODDER_ENABLE]=$(jq -r '.gpodder.enable // false' "$EXISTING_CONFIG") CFG[GPODDER_HOST]=$(jq -r '.gpodder.host // "https://gpodder.net"' "$EXISTING_CONFIG") CFG[GPODDER_USER]=$(jq -r '.gpodder.username // ""' "$EXISTING_CONFIG") CFG[GPODDER_PASS]=$(jq -r '.gpodder.password // ""' "$EXISTING_CONFIG") fi read -rp "Icecast host [$CFG[ICE_HOST]]: " v; CFG[ICE_HOST]=${v:-$CFG[ICE_HOST]} read -rp "Icecast port [$CFG[ICE_PORT]]: " v; CFG[ICE_PORT]=${v:-$CFG[ICE_PORT]} read -rp "Icecast mount [$CFG[ICE_MOUNT]]: " v; CFG[ICE_MOUNT]=${v:-$CFG[ICE_MOUNT]} read -rp "Icecast source username [$CFG[ICE_USER]]: " v; CFG[ICE_USER]=${v:-$CFG[ICE_USER]} read -rsp "Icecast source password [$CFG[ICE_PASS]]: "; echo; CFG[ICE_PASS]=${v:-$CFG[ICE_PASS]} read -rp "Enable gPodder sync? (true/false) [$CFG[GPODDER_ENABLE]]: " v; CFG[GPODDER_ENABLE]=${v:-$CFG[GPODDER_ENABLE]} read -rp "gPodder host [$CFG[GPODDER_HOST]]: " v; CFG[GPODDER_HOST]=${v:-$CFG[GPODDER_HOST]} read -rp "gPodder username [$CFG[GPODDER_USER]]: " v; CFG[GPODDER_USER]=${v:-$CFG[GPODDER_USER]} read -rsp "gPodder password [$CFG[GPODDER_PASS]]: "; echo; CFG[GPODDER_PASS]=${v:-$CFG[GPODDER_PASS]} echo echo "Summary:" echo " Icecast: ${CFG[ICE_HOST]}:${CFG[ICE_PORT]}${CFG[ICE_MOUNT]}" echo " gPodder sync: ${CFG[GPODDER_ENABLE]}" read -rp "Proceed? [y/N] " confirm [[ "$confirm" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; } # --- Install system packages --- echo "Installing system packages..." apt-get update -qq apt-get install -y -qq python3 python3-venv python3-pip jq curl >/dev/null # --- Create venv and install Python deps --- if [[ ! -d "$VENV" ]]; then echo "Creating virtualenv at $VENV..." python3 -m venv "$VENV" fi echo "Installing Python dependencies..." "$VENV/bin/pip" install --quiet --upgrade pip "$VENV/bin/pip" install --quiet feedparser requests mutagen # --- Create directory structure --- for d in music podcasts jingles announcements playlists state logs; do mkdir -p "$INSTALL_DIR/$d" done # --- Generate config.json --- cat > "$INSTALL_DIR/config.json" </dev/null; then useradd --system --home-dir "$INSTALL_DIR" --shell /usr/sbin/nologin liquidsoap fi chown -R liquidsoap:liquidsoap "$INSTALL_DIR" # --- Write systemd service --- cat > /etc/systemd/system/"$SERVICE_NAME".service </dev/null | grep -v "fetch_podcasts.py"; echo "$CRON_FETCH") | crontab - (crontab -l 2>/dev/null | grep -v "update_playlists.py"; echo "$CRON_UPDATE") | crontab - # --- Reload and enable --- systemctl daemon-reload systemctl enable "$SERVICE_NAME" echo echo "=== Installation complete ===" echo "Next steps:" echo " 1. Drop MP3/M4A files into $INSTALL_DIR/music/" echo " 2. Edit $INSTALL_DIR/schedule.txt with your show schedule" echo " 3. Review $INSTALL_DIR/station.liq" echo " 4. Start services:" echo " sudo systemctl start icecast2" echo " sudo systemctl start $SERVICE_NAME"