#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MANIFEST_PATH="${BUILD_MANIFEST:-$SCRIPT_DIR/build_manifest.env}" if [ -f "$MANIFEST_PATH" ]; then # shellcheck disable=SC1090 source "$MANIFEST_PATH" fi PACKAGE_NAME="${DEB_PACKAGE_NAME:-${PACKAGE_NAME:-}}" APP_TITLE="${DEB_APP_TITLE:-${APP_TITLE:-}}" VERSION="${DEB_VERSION:-${VERSION:-}}" ARCH="${DEB_ARCH:-${ARCH:-}}" SECTION="${DEB_SECTION:-${SECTION:-}}" PRIORITY="${DEB_PRIORITY:-${PRIORITY:-}}" MAINTAINER="${DEB_MAINTAINER:-${MAINTAINER:-}}" DESCRIPTION_SHORT="${DEB_DESCRIPTION_SHORT:-${DESCRIPTION_SHORT:-}}" DESCRIPTION_LONG="${DEB_DESCRIPTION_LONG:-${DESCRIPTION_LONG:-}}" OUT_DIR="$SCRIPT_DIR/dist" BIN_PATH="$OUT_DIR/nsfwapp-linux-amd64" OUT_FILE="$OUT_DIR/${PACKAGE_NAME}_${ARCH}.deb" ML_REQUIREMENTS_PATH="$SCRIPT_DIR/ml/requirements-ml.txt" CLEAN_BUILD_DIR=0 if [ -n "${DEB_BUILD_DIR:-}" ]; then BUILD_DIR="$DEB_BUILD_DIR" rm -rf "$BUILD_DIR" mkdir -p "$BUILD_DIR" else BUILD_DIR="$(mktemp -d "${TMPDIR:-/tmp}/${PACKAGE_NAME}.deb-build.XXXXXX")" CLEAN_BUILD_DIR=1 fi PKG_ROOT="$BUILD_DIR/root" cleanup() { if [ "$CLEAN_BUILD_DIR" = "1" ]; then rm -rf "$BUILD_DIR" fi } trap cleanup EXIT fail() { echo "Fehler: $*" >&2 exit 1 } [ -n "$PACKAGE_NAME" ] || fail "PACKAGE_NAME fehlt im Build-Manifest." [ -n "$APP_TITLE" ] || fail "APP_TITLE fehlt im Build-Manifest." [ -n "$VERSION" ] || fail "VERSION fehlt im Build-Manifest." [ -n "$ARCH" ] || fail "ARCH fehlt im Build-Manifest." [ -n "$SECTION" ] || fail "SECTION fehlt im Build-Manifest." [ -n "$PRIORITY" ] || fail "PRIORITY fehlt im Build-Manifest." [ -n "$MAINTAINER" ] || fail "MAINTAINER fehlt im Build-Manifest." [ -n "$DESCRIPTION_SHORT" ] || fail "DESCRIPTION_SHORT fehlt im Build-Manifest." [ -n "$DESCRIPTION_LONG" ] || fail "DESCRIPTION_LONG fehlt im Build-Manifest." command -v dpkg-deb >/dev/null 2>&1 || fail "dpkg-deb fehlt. Installiere es mit: sudo apt install -y dpkg-dev" [ -f "$ML_REQUIREMENTS_PATH" ] || fail "ML-Requirements nicht gefunden: $ML_REQUIREMENTS_PATH" mkdir -p "$OUT_DIR" if [ ! -f "$BIN_PATH" ] || [ "${DEB_SKIP_REBUILD:-0}" != "1" ]; then command -v go >/dev/null 2>&1 || fail "go fehlt. Installiere Go oder baue zuerst mit build.bat." command -v gcc >/dev/null 2>&1 || fail "gcc fehlt. Installiere: sudo apt install -y build-essential" command -v pkg-config >/dev/null 2>&1 || fail "pkg-config fehlt. Installiere: sudo apt install -y pkg-config" echo "Baue Linux-Binary..." mkdir -p "$SCRIPT_DIR/.gocache-linux" ( cd "$SCRIPT_DIR" GOOS=linux GOARCH=amd64 CGO_ENABLED=1 GOCACHE="$SCRIPT_DIR/.gocache-linux" go build -o "$BIN_PATH" ) fi [ -f "$BIN_PATH" ] || fail "Linux-Binary nicht gefunden: $BIN_PATH" chmod 0755 "$OUT_DIR/nsfwapp-linux-amd64" 2>/dev/null || true mkdir -p \ "$PKG_ROOT/DEBIAN" \ "$PKG_ROOT/opt/nsfwapp" \ "$PKG_ROOT/usr/bin" \ "$PKG_ROOT/usr/share/applications" \ "$PKG_ROOT/usr/share/doc/nsfwapp" \ "$PKG_ROOT/usr/share/pixmaps" chmod 0755 "$PKG_ROOT" "$PKG_ROOT/DEBIAN" install -m 0755 "$BIN_PATH" "$PKG_ROOT/opt/nsfwapp/nsfwapp" install -m 0644 "$ML_REQUIREMENTS_PATH" "$PKG_ROOT/opt/nsfwapp/requirements-ml.txt" if [ -f "$SCRIPT_DIR/assets/img/tray.ico" ]; then install -m 0644 "$SCRIPT_DIR/assets/img/tray.ico" "$PKG_ROOT/usr/share/pixmaps/nsfwapp.ico" fi cat >"$PKG_ROOT/usr/bin/nsfwapp" <<'EOF' #!/usr/bin/env sh set -eu install_dir="/opt/nsfwapp" app_dir="${NSFWAPP_HOME:-$HOME/nsfwapp}" runtime_bin="$app_dir/nsfwapp" mkdir -p "$app_dir/record/done" if [ ! -f "$runtime_bin" ] || ! cmp -s "$install_dir/nsfwapp" "$runtime_bin"; then tmp="$app_dir/.nsfwapp.tmp.$$" cp "$install_dir/nsfwapp" "$tmp" chmod 0755 "$tmp" mv "$tmp" "$runtime_bin" fi configure_ml_python_setup() { if [ "${NSFWAPP_SKIP_ML_SETUP:-0}" = "1" ]; then return 0 fi if [ -n "${AI_SERVER_PYTHON:-}" ]; then return 0 fi requirements_file="$install_dir/requirements-ml.txt" if [ ! -f "$requirements_file" ]; then return 0 fi NSFWAPP_ML_SETUP=1 NSFWAPP_ML_REQUIREMENTS="$requirements_file" NSFWAPP_ML_VENV="${NSFWAPP_ML_VENV:-$app_dir/ml-venv}" NSFWAPP_ML_SETUP_LOG="${NSFWAPP_ML_SETUP_LOG:-$app_dir/ml-setup.log}" export NSFWAPP_ML_SETUP NSFWAPP_ML_REQUIREMENTS NSFWAPP_ML_VENV NSFWAPP_ML_SETUP_LOG return 0 } configure_ml_python_setup cd "$app_dir" exec "$runtime_bin" "$@" EOF chmod 0755 "$PKG_ROOT/usr/bin/nsfwapp" cat >"$PKG_ROOT/usr/bin/nsfwapp-open" <<'EOF' #!/usr/bin/env sh set -eu url="${NSFWAPP_URL:-https://localhost:9999}" nohup nsfwapp >/dev/null 2>&1 & if command -v xdg-open >/dev/null 2>&1; then ( sleep 2 xdg-open "$url" >/dev/null 2>&1 || true ) & fi EOF chmod 0755 "$PKG_ROOT/usr/bin/nsfwapp-open" cat >"$PKG_ROOT/usr/bin/nsfwapp-open-data" <<'EOF' #!/usr/bin/env sh set -eu app_dir="${NSFWAPP_HOME:-$HOME/nsfwapp}" mkdir -p "$app_dir/record/done" if command -v xdg-open >/dev/null 2>&1; then xdg-open "$app_dir" >/dev/null 2>&1 || true fi EOF chmod 0755 "$PKG_ROOT/usr/bin/nsfwapp-open-data" cat >"$PKG_ROOT/usr/bin/nsfwapp-open-log" <<'EOF' #!/usr/bin/env sh set -eu app_dir="${NSFWAPP_HOME:-$HOME/nsfwapp}" log_file="$app_dir/recorder.log" mkdir -p "$app_dir/record/done" [ -f "$log_file" ] || : >"$log_file" if command -v xdg-open >/dev/null 2>&1; then xdg-open "$log_file" >/dev/null 2>&1 || true fi EOF chmod 0755 "$PKG_ROOT/usr/bin/nsfwapp-open-log" cat >"$PKG_ROOT/usr/bin/nsfwapp-stop" <<'EOF' #!/usr/bin/env sh set -eu app_dir="${NSFWAPP_HOME:-$HOME/nsfwapp}" runtime_bin="$app_dir/nsfwapp" install_bin="/opt/nsfwapp/nsfwapp" pids="" if command -v pgrep >/dev/null 2>&1; then for pattern in "$runtime_bin" "$install_bin"; do found="$(pgrep -f "$pattern" 2>/dev/null || true)" if [ -n "$found" ]; then pids="$pids $found" fi done fi if [ -z "$(echo "$pids" | tr -d '[:space:]')" ]; then if command -v notify-send >/dev/null 2>&1; then notify-send "NSFW App" "Die Anwendung läuft nicht." || true fi exit 0 fi for pid in $pids; do kill -TERM "$pid" 2>/dev/null || true done sleep 1 still_running=0 for pid in $pids; do if kill -0 "$pid" 2>/dev/null; then still_running=1 fi done if command -v notify-send >/dev/null 2>&1; then if [ "$still_running" = "1" ]; then notify-send "NSFW App" "Beenden wurde angefordert." || true else notify-send "NSFW App" "Anwendung beendet." || true fi fi EOF chmod 0755 "$PKG_ROOT/usr/bin/nsfwapp-stop" cat >"$PKG_ROOT/usr/share/applications/nsfwapp.desktop" <"$PKG_ROOT/usr/share/doc/nsfwapp/README.Debian" <<'EOF' NSFW App fuer Debian ==================== Start: nsfwapp Beenden: nsfwapp-stop Desktop: Der Launcher "NSFW App" startet das Backend und öffnet https://localhost:9999. Per Rechtsklick auf "NSFW App" gibt es Aktionen fuer Frontend, Datenordner, Log und Beenden, sofern die Desktop-Umgebung Desktop Actions anzeigt. User-Daten: Die installierte Binary liegt unter /opt/nsfwapp/nsfwapp. Beim Start wird sie nach ${NSFWAPP_HOME:-$HOME/nsfwapp}/nsfwapp kopiert und von dort ausgefuehrt. Dadurch bleiben recorder.log, recorder_settings.json, recorder_settings.json, PostgreSQL-Datenordner, generated/, record/ und record/done im User-Bereich. Wichtige Laufzeitprogramme: ffmpeg/ffprobe muessen fuer Recording, Teaser, Analyse und Videofunktionen verfuegbar sein. PostgreSQL ist die Datenbank. Fuer lokale Datenordner werden initdb/pg_ctl und fuer Migration/Backup pg_dump/pg_restore benoetigt. Der Launcher erstellt beim ersten Start automatisch ${NSFWAPP_HOME:-$HOME/nsfwapp}/ml-venv und installiert die mitgelieferte requirements-ml.txt. Details stehen in ml-setup.log. Setze AI_SERVER_PYTHON, wenn du eine eigene Python-Umgebung verwenden willst. EOF cat >"$PKG_ROOT/DEBIAN/control" <"$PKG_ROOT/DEBIAN/postinst" <<'EOF' #!/usr/bin/env sh set -e if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database /usr/share/applications >/dev/null 2>&1 || true fi exit 0 EOF chmod 0755 "$PKG_ROOT/DEBIAN/postinst" cat >"$PKG_ROOT/DEBIAN/postrm" <<'EOF' #!/usr/bin/env sh set -e if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database /usr/share/applications >/dev/null 2>&1 || true fi exit 0 EOF chmod 0755 "$PKG_ROOT/DEBIAN/postrm" dpkg-deb --root-owner-group --build "$PKG_ROOT" "$OUT_FILE" echo echo "Debian-Paket erzeugt:" echo " $OUT_FILE" echo echo "Build-Artefakte:" echo " $OUT_DIR/nsfwapp-linux-amd64" if [ -f "$OUT_DIR/nsfwapp.exe" ]; then echo " $OUT_DIR/nsfwapp.exe" fi echo echo "Installieren:" echo " sudo apt install ./dist/$(basename "$OUT_FILE")"