diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..5713b1e --- /dev/null +++ b/install.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# Mado installer: sets up a Python virtualenv, installs dependencies, checks the +# programs ani-cli needs and (optionally) installs ani-cli and a systemd service. +# +# ./install.sh set up in ./.venv and print how to start it +# ./install.sh -y answer "yes" to every question (non-interactive) +# ./install.sh --service also install + start a systemd service (needs root) +# ./install.sh --port 8080 port used by the service / printed start command +# ./install.sh --https service sets ANIWEB_HTTPS=1 (use behind HTTPS) +# ./install.sh --host 0.0.0.0 address the service listens on (default 127.0.0.1) +set -euo pipefail + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +VENV="$DIR/.venv" +ANI_CLI_URL="https://raw.githubusercontent.com/pystardust/ani-cli/master/ani-cli" + +ASSUME_YES=0; SERVICE=0; HTTPS=0; PORT=8000; HOST=127.0.0.1 + +while [ $# -gt 0 ]; do + case "$1" in + -y|--yes) ASSUME_YES=1 ;; + --service) SERVICE=1 ;; + --https) HTTPS=1 ;; + --port) PORT="${2:?--port needs a value}"; shift ;; + --host) HOST="${2:?--host needs a value}"; shift ;; + -h|--help) sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + *) echo "Unknown option: $1 (try --help)" >&2; exit 2 ;; + esac + shift +done + +say() { printf '\033[1;35m==>\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m!!\033[0m %s\n' "$*" >&2; } +die() { printf '\033[1;31mxx\033[0m %s\n' "$*" >&2; exit 1; } + +ask() { # ask "question" -> 0 for yes + [ "$ASSUME_YES" = 1 ] && return 0 + [ -t 0 ] || return 1 + read -r -p "$1 [y/N] " reply + case "$reply" in y|Y|yes|YES) return 0 ;; *) return 1 ;; esac +} + +[ -f "$DIR/app.py" ] && [ -f "$DIR/static/index.html" ] \ + || die "app.py or static/index.html is missing. Run this script from the Mado folder." + +# ---- Python --------------------------------------------------------------- +say "Checking Python" +command -v python3 >/dev/null || die "python3 not found. Install Python 3.9 or newer." +python3 - <<'EOF' || die "Python 3.9 or newer is required." +import sys; sys.exit(0 if sys.version_info >= (3, 9) else 1) +EOF +echo " $(python3 --version)" + +say "Creating virtualenv in .venv" +if [ ! -x "$VENV/bin/python" ]; then + python3 -m venv "$VENV" 2>/dev/null || die "Couldn't create a virtualenv. On Debian/Ubuntu: sudo apt install python3-venv" +fi + +say "Installing Python dependencies" +"$VENV/bin/python" -m pip install --quiet --upgrade pip || warn "pip upgrade failed, continuing" +"$VENV/bin/python" -m pip install --quiet -r "$DIR/requirements.txt" +# waitress is a sturdier server than Flask's built-in one; failing to get it is fine +"$VENV/bin/python" -m pip install --quiet waitress \ + || warn "waitress not installed; Mado will use Flask's built-in server." + +# ---- Programs ani-cli depends on ------------------------------------------ +say "Checking programs ani-cli needs" +missing=() +for tool in curl sed grep od; do command -v "$tool" >/dev/null || missing+=("$tool"); done +command -v base64 >/dev/null || command -v openssl >/dev/null || missing+=("base64 (or openssl)") +if [ ${#missing[@]} -gt 0 ]; then + warn "Missing: ${missing[*]}" + warn "Install them with your package manager (e.g. sudo apt install curl sed grep coreutils openssl)." +fi + +# ---- ani-cli -------------------------------------------------------------- +say "Checking ani-cli" +if command -v ani-cli >/dev/null; then + echo " found: $(command -v ani-cli)" +else + warn "ani-cli is not installed." + if ask "Download ani-cli from GitHub now?"; then + if [ "$(id -u)" = 0 ]; then target=/usr/local/bin; else target="$HOME/.local/bin"; fi + mkdir -p "$target" + curl -fsSL "$ANI_CLI_URL" -o "$target/ani-cli" || die "Download failed. Install ani-cli manually: https://github.com/pystardust/ani-cli" + chmod +x "$target/ani-cli" + echo " installed: $target/ani-cli" + case ":$PATH:" in *":$target:"*) ;; *) warn "$target is not on your PATH; add it to your shell profile." ;; esac + ANI_DIR="$target" + else + warn "Install it before starting Mado: https://github.com/pystardust/ani-cli" + fi +fi + +# ---- Start script --------------------------------------------------------- +say "Writing run.sh" +cat > "$DIR/run.sh" </dev/null || die "systemctl not found; this system doesn't use systemd." + RUN_USER="${SUDO_USER:-root}" + RUN_HOME="$(getent passwd "$RUN_USER" | cut -d: -f6)" + chown -R "$RUN_USER" "$DIR" + cat > /etc/systemd/system/mado.service <