#!/usr/bin/env bash # Cadence — install deps (if needed) and start the dashboard on http://localhost:8000 # # bash run.sh → port 8000 # PORT=8010 bash run.sh → custom port # # If the browser says "not answering on 127.0.0.1:8000", this script tells you why # instead of exiting quietly. set -uo pipefail cd "$(dirname "$0")" PORT="${PORT:-8000}" bold() { printf '\033[1m%s\033[0m\n' "$*"; } ok() { printf ' \033[32m✓\033[0m %s\n' "$*"; } bad() { printf ' \033[31m✗\033[0m %s\n' "$*"; } warn() { printf ' \033[33m!\033[0m %s\n' "$*"; } die() { bad "$1"; shift; for line in "$@"; do echo " $line"; done; exit 1; } # ── 1. python itself ───────────────────────────────────────────────────────── if ! command -v python3 >/dev/null 2>&1; then die "python3 is not installed." \ "macOS: brew install python (or install from python.org)" \ "Debian/Ubuntu: sudo apt install python3 python3-venv python3-pip" fi PYV="$(python3 -c 'import sys;print("%d.%d"%sys.version_info[:2])' 2>/dev/null || echo "?")" case "$PYV" in 3.9|3.1[0-9]|3.[2-9][0-9]|[4-9].*) ok "python $PYV" ;; *) die "python $PYV is too old — Cadence needs 3.9 or newer." \ "Install a newer python3, then run: bash run.sh" ;; esac # ── 2. is the port already taken? ──────────────────────────────────────────── port_busy() { if command -v ss >/dev/null 2>&1; then ss -ltn 2>/dev/null | grep -q ":${PORT} "; return $?; fi if command -v lsof >/dev/null 2>&1; then lsof -iTCP:"${PORT}" -sTCP:LISTEN >/dev/null 2>&1; return $?; fi return 1 } if port_busy; then # A Cadence backend already listening is fine — say so, don't start a second one. if curl -fsS -m 3 "http://127.0.0.1:${PORT}/healthz" >/dev/null 2>&1; then ok "Cadence is already running on http://localhost:${PORT}" echo echo " Open http://localhost:${PORT} — nothing else to do." echo " (Stop the old one first if you want a restart.)" exit 0 fi die "port ${PORT} is already used by another program." \ "Start Cadence on a different port: PORT=8010 bash run.sh" \ "See what holds it: lsof -iTCP:${PORT} -sTCP:LISTEN (or: ss -ltnp | grep ${PORT})" fi # ── 3. dependencies ────────────────────────────────────────────────────────── have_deps() { "$1" -c 'import flask, yt_dlp, ytmusicapi, requests' >/dev/null 2>&1; } PY=python3 if have_deps python3; then ok "dependencies already available" else bold "Installing dependencies (first run only)" if python3 -m pip install -q -r requirements.txt >/dev/null 2>&1 && have_deps python3; then ok "installed into system python" else # PEP 668 "externally managed" systems (Debian, Ubuntu, Homebrew) refuse system pip warn "system pip declined — using a local virtualenv in ./.venv" if [ ! -d .venv ]; then python3 -m venv .venv >/dev/null 2>&1 || die "could not create .venv" \ "Debian/Ubuntu: sudo apt install python3-venv then re-run: bash run.sh" \ "macOS: brew install python then re-run: bash run.sh" fi ./.venv/bin/pip install -q -r requirements.txt || die "pip install failed" \ "Check your internet connection, then re-run: bash run.sh" \ "Behind a proxy? export HTTPS_PROXY=http://host:port" have_deps ./.venv/bin/python || die "dependencies still missing after install" \ "Try: rm -rf .venv && bash run.sh" ok "installed into ./.venv" PY=./.venv/bin/python fi fi # ── 4. start ───────────────────────────────────────────────────────────────── bold "Starting Cadence on http://localhost:${PORT}" echo " (Ctrl+C stops it)" echo PORT="$PORT" exec "$PY" app.py