Audiofy – Musikwünsche für Partys
Server (Website, Admin-Bereich, Player-API) und Player (raspotify + Controller) mit Install-Skripten für Debian-Systeme. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+146
@@ -0,0 +1,146 @@
|
||||
# Audiofy – gemeinsame Hilfsfunktionen für die Install-Skripte (wird per "source" geladen)
|
||||
# shellcheck shell=bash
|
||||
|
||||
AUDIOFY_DIR="${AUDIOFY_DIR:-/opt/audiofy}"
|
||||
AUDIOFY_USER="${AUDIOFY_USER:-audiofy}"
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
VORLAGEN="$REPO/install/vorlagen"
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
SUDO=""
|
||||
ALS_DIENST=(runuser -u "$AUDIOFY_USER" --)
|
||||
else
|
||||
SUDO="sudo"
|
||||
ALS_DIENST=(sudo -u "$AUDIOFY_USER")
|
||||
fi
|
||||
|
||||
# --- Ausgabe ------------------------------------------------------------------
|
||||
|
||||
schritt() { printf '\n\033[1m==> %s\033[0m\n' "$*"; }
|
||||
info() { printf ' %s\n' "$*"; }
|
||||
warnung() { printf '\033[33m ! %s\033[0m\n' "$*"; }
|
||||
abbruch() { printf '\033[31m ✗ %s\033[0m\n' "$*" >&2; exit 1; }
|
||||
|
||||
# --- Abfragen -----------------------------------------------------------------
|
||||
|
||||
# frage VAR "Text" [Standard]
|
||||
frage() {
|
||||
local antwort
|
||||
read -r -p " $2${3:+ [$3]}: " antwort
|
||||
printf -v "$1" '%s' "${antwort:-${3:-}}"
|
||||
}
|
||||
|
||||
# frage_geheim VAR "Text" – Eingabe wird nicht angezeigt
|
||||
frage_geheim() {
|
||||
local antwort
|
||||
read -r -s -p " $2: " antwort
|
||||
echo
|
||||
printf -v "$1" '%s' "$antwort"
|
||||
}
|
||||
|
||||
# ja_nein "Frage" [j|n] – Rückgabewert 0 = ja
|
||||
ja_nein() {
|
||||
local standard="${2:-j}" antwort
|
||||
read -r -p " $1 [$([ "$standard" = j ] && echo J/n || echo j/N)]: " antwort
|
||||
antwort="${antwort:-$standard}"
|
||||
[[ "$antwort" =~ ^[jJyY] ]]
|
||||
}
|
||||
|
||||
# --- System -------------------------------------------------------------------
|
||||
|
||||
pruefe_system() {
|
||||
[ -f /etc/debian_version ] || abbruch "Nur für Debian und Debian-basierte Systeme (z. B. Raspberry Pi OS)."
|
||||
command -v systemctl >/dev/null || abbruch "systemd wird benötigt."
|
||||
command -v apt-get >/dev/null || abbruch "apt wird benötigt."
|
||||
if [ -n "$SUDO" ]; then
|
||||
command -v sudo >/dev/null || abbruch "Bitte als root ausführen oder sudo installieren."
|
||||
info "Für die Einrichtung sind root-Rechte nötig – sudo fragt ggf. nach deinem Passwort."
|
||||
sudo true || abbruch "sudo nicht möglich."
|
||||
fi
|
||||
python3 -c 'import sys; sys.exit(sys.version_info < (3, 11))' 2>/dev/null \
|
||||
|| abbruch "Python 3.11 oder neuer wird benötigt (Debian 12 oder neuer)."
|
||||
}
|
||||
|
||||
pakete() {
|
||||
info "Installiere: $*"
|
||||
$SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y -qq "$@" >/dev/null
|
||||
}
|
||||
|
||||
dienst_benutzer() {
|
||||
if ! id "$AUDIOFY_USER" >/dev/null 2>&1; then
|
||||
$SUDO useradd --system --home-dir "$AUDIOFY_DIR" --no-create-home --shell /usr/sbin/nologin "$AUDIOFY_USER"
|
||||
info "Dienst-Benutzer '$AUDIOFY_USER' angelegt (ohne Login, ohne sudo)"
|
||||
fi
|
||||
}
|
||||
|
||||
# code_kopieren QUELLE ZIEL – ersetzt den Inhalt von ZIEL (gehört root, Dienst darf nur lesen)
|
||||
code_kopieren() {
|
||||
local quelle="$1" ziel="$2"
|
||||
$SUDO install -d -o root -g "$AUDIOFY_USER" -m 750 "$ziel"
|
||||
$SUDO find "$ziel" -mindepth 1 -delete
|
||||
tar -C "$quelle" --exclude='__pycache__' --exclude='.venv' --exclude='.pytest_cache' --exclude='tests' -cf - . \
|
||||
| $SUDO tar -C "$ziel" --no-same-owner -xf -
|
||||
$SUDO chown -R root:"$AUDIOFY_USER" "$ziel"
|
||||
$SUDO find "$ziel" -type d -exec chmod 750 {} +
|
||||
$SUDO find "$ziel" -type f -exec chmod 640 {} +
|
||||
}
|
||||
|
||||
# venv_einrichten REQUIREMENTS
|
||||
venv_einrichten() {
|
||||
local venv="$AUDIOFY_DIR/.venv"
|
||||
[ -x "$venv/bin/python" ] || $SUDO python3 -m venv "$venv"
|
||||
$SUDO "$venv/bin/pip" install -q --upgrade pip
|
||||
$SUDO "$venv/bin/pip" install -q -r "$1"
|
||||
$SUDO chown -R root:"$AUDIOFY_USER" "$venv"
|
||||
$SUDO chmod -R g+rX,o-rwx "$venv"
|
||||
}
|
||||
|
||||
# vorlage DATEI ZIEL – ersetzt {{NAME}} durch den Wert der Shell-Variablen NAME
|
||||
vorlage() {
|
||||
local inhalt
|
||||
inhalt="$(python3 - "$VORLAGEN/$1" <<'PY'
|
||||
import os, re, sys
|
||||
text = open(sys.argv[1]).read()
|
||||
def ersetzen(m):
|
||||
wert = os.environ.get(m.group(1))
|
||||
if wert is None:
|
||||
sys.exit(f"Vorlage {sys.argv[1]}: {m.group(1)} ist nicht gesetzt")
|
||||
return wert
|
||||
print(re.sub(r"\{\{([A-Z_]+)\}\}", ersetzen, text), end="")
|
||||
PY
|
||||
)" || abbruch "Vorlage $1 konnte nicht ausgefüllt werden"
|
||||
printf '%s\n' "$inhalt" | $SUDO tee "$2" >/dev/null
|
||||
}
|
||||
|
||||
# --- .env (gehört dem Dienst-Benutzer, Rechte 600) ------------------------------
|
||||
|
||||
# env_setzen DATEI KEY WERT – der Wert läuft über stdin (nicht in der Prozessliste sichtbar)
|
||||
env_setzen() {
|
||||
printf '%s' "$3" | "${ALS_DIENST[@]}" python3 -c '
|
||||
import os, sys
|
||||
pfad, key = sys.argv[1], sys.argv[2]
|
||||
wert = sys.stdin.read()
|
||||
zeilen = open(pfad).read().splitlines() if os.path.exists(pfad) else []
|
||||
zeilen = [z for z in zeilen if not z.strip().startswith(key + "=")] + [f"{key}={wert}"]
|
||||
fd = os.open(pfad, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
|
||||
with os.fdopen(fd, "w") as f:
|
||||
f.write("\n".join(zeilen) + "\n")
|
||||
' "$1" "$2"
|
||||
}
|
||||
|
||||
# env_wert DATEI KEY – gibt den Wert aus (leer, wenn nicht vorhanden)
|
||||
env_wert() {
|
||||
"${ALS_DIENST[@]}" sh -c 'grep -m1 "^$2=" "$1" 2>/dev/null | cut -d= -f2-' _ "$1" "$2" || true
|
||||
}
|
||||
|
||||
# env_umbenennen DATEI ALT NEU – übernimmt alte Schlüsselnamen (für Updates)
|
||||
env_umbenennen() {
|
||||
local wert
|
||||
if [ -z "$(env_wert "$1" "$3")" ]; then
|
||||
wert="$(env_wert "$1" "$2")"
|
||||
if [ -n "$wert" ]; then
|
||||
env_setzen "$1" "$3" "$wert"
|
||||
info "$2 → $3 übernommen"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user