Initial commit: Phase 1 – Projektstruktur, DB-Schema, Core-API

- FastAPI-Backend mit vollständiger ABS v2.x API-Kompatibilität
- SQLAlchemy-Models: User, Library, LibraryItem, BookFile, Chapter,
  Podcast, PodcastEpisode, MediaProgress, Bookmark, PlaybackSession
- Auth: JWT-Login (/login, /logout, /api/authorize)
- Library + Items Endpoints inkl. camelCase ABS-Response-Format
- HLS-Streaming via FFmpeg (POST /api/items/:id/play, Session-Sync)
- Me/Progress Endpoints + Lesezeichen
- User-Management + Server-Settings (Admin)
- Library-Scanner (MP3/WAV Discovery, Hintergrund-Task)
- File Watcher (watchdog, 30s Debounce)
- Matching-Skelett (MusicBrainz, OpenLibrary, Google Books – Phase 5)
- Docker-Setup: backend (Python 3.12+FFmpeg), frontend (React/Vite),
  nginx Reverse-Proxy auf Port 3000
- setup.sh: Installiert Docker auf Debian/Ubuntu, richtet .env ein

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Audiolib
2026-05-26 11:43:35 +02:00
commit 14ffee3051
56 changed files with 3220 additions and 0 deletions

126
setup.sh Normal file
View File

@@ -0,0 +1,126 @@
#!/usr/bin/env bash
set -euo pipefail
# ─────────────────────────────────────────────────────────────────────────────
# Audiolib Setup-Skript
# Läuft auf Debian/Ubuntu-basierten Systemen (inkl. Proxmox LXC, Raspberry Pi)
# ─────────────────────────────────────────────────────────────────────────────
BOLD="\033[1m"
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
RESET="\033[0m"
info() { echo -e "${GREEN}[OK]${RESET} $*"; }
warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; }
error() { echo -e "${RED}[FEHLER]${RESET} $*" >&2; exit 1; }
header() { echo -e "\n${BOLD}$*${RESET}"; }
# ── Root-Check ────────────────────────────────────────────────────────────────
if [[ $EUID -ne 0 ]]; then
error "Bitte als root ausführen: sudo bash setup.sh"
fi
header "━━━ Audiolib Setup ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# ── Docker installieren ───────────────────────────────────────────────────────
header "1/4 · Docker prüfen / installieren"
if command -v docker &>/dev/null; then
DOCKER_VERSION=$(docker --version | awk '{print $3}' | tr -d ',')
info "Docker bereits installiert: $DOCKER_VERSION"
else
warn "Docker nicht gefunden installiere Docker..."
apt-get update -qq
apt-get install -y -qq ca-certificates curl gnupg lsb-release
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
DISTRO=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
# Ubuntu-Basis (z.B. Mint) als ubuntu behandeln
[[ "$DISTRO" == "ubuntu" || "$DISTRO" == "linuxmint" ]] && DISTRO="ubuntu" || DISTRO="debian"
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/${DISTRO} \
$(lsb_release -cs) stable" \
> /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable --now docker
info "Docker installiert: $(docker --version)"
fi
# ── Docker Compose prüfen ─────────────────────────────────────────────────────
if docker compose version &>/dev/null; then
info "Docker Compose Plugin verfügbar: $(docker compose version --short)"
elif command -v docker-compose &>/dev/null; then
warn "Altes docker-compose gefunden. Empfehle: apt install docker-compose-plugin"
# Alias damit der Rest des Skripts 'docker compose' nutzen kann
shopt -s expand_aliases
alias docker\ compose='docker-compose'
else
error "Docker Compose nicht gefunden. Bitte manuell installieren."
fi
# ── .env einrichten ───────────────────────────────────────────────────────────
header "2/4 · Konfiguration (.env)"
if [[ -f .env ]]; then
warn ".env existiert bereits wird nicht überschrieben."
warn "Bitte manuell prüfen: nano .env"
else
cp .env.example .env
# Zufälligen JWT_SECRET generieren
JWT_SECRET=$(openssl rand -hex 32 2>/dev/null || cat /dev/urandom | tr -dc 'a-f0-9' | head -c 64)
sed -i "s|JWT_SECRET=change_me_in_production_use_a_long_random_string|JWT_SECRET=${JWT_SECRET}|" .env
info ".env angelegt mit zufälligem JWT_SECRET."
echo ""
echo -e " ${YELLOW}WICHTIG: Bitte jetzt .env öffnen und anpassen:${RESET}"
echo -e " ${BOLD}nano .env${RESET}"
echo ""
echo " Mindestens setzen:"
echo " ADMIN_PASSWORD=<sicheres_passwort>"
echo " AUDIOFILES_PATH=<pfad_zu_deinen_audiodateien>"
echo ""
fi
# ── Verzeichnisse anlegen ─────────────────────────────────────────────────────
header "3/4 · Verzeichnisse anlegen"
mkdir -p data/db data/covers data/hls_cache data/logs
info "data/-Verzeichnisse erstellt."
# audiofiles-Verzeichnis nur anlegen wenn AUDIOFILES_PATH auf ./audiofiles zeigt
if grep -q "^AUDIOFILES_PATH=\./audiofiles" .env 2>/dev/null; then
mkdir -p audiofiles
warn "audiofiles/ angelegt. Audiodateien dort ablegen oder AUDIOFILES_PATH in .env anpassen."
fi
# ── Berechtigungen ────────────────────────────────────────────────────────────
# Docker läuft normalerweise als root im Container, data-Ordner für alle beschreibbar
chmod -R 777 data/ 2>/dev/null || true
# ── Fertig ────────────────────────────────────────────────────────────────────
header "4/4 · Bereit zum Starten"
echo ""
echo -e "${BOLD}Setup abgeschlossen.${RESET} Nächste Schritte:"
echo ""
echo -e " 1. ${YELLOW}nano .env${RESET} ← ADMIN_PASSWORD und AUDIOFILES_PATH setzen"
echo ""
echo -e " 2. ${BOLD}docker compose up -d --build${RESET}"
echo ""
echo -e " 3. Audiobookshelf-App öffnen → Server-URL:"
echo -e " ${BOLD}http://$(hostname -I | awk '{print $1}'):3000${RESET}"
echo ""
echo -e " Logs anzeigen: ${BOLD}docker compose logs -f backend${RESET}"
echo -e " Stoppen: ${BOLD}docker compose down${RESET}"
echo ""