From c5895208fae62df544355d2c25b75ae31b5e9f0f Mon Sep 17 00:00:00 2001 From: Linrador <68631622+Linrador@users.noreply.github.com> Date: Tue, 23 Jun 2026 12:10:40 +0200 Subject: [PATCH] added build as debian package --- .gitignore | 4 + backend/build.bat | 1 + backend/build_deb.bat | 43 +++++++++++ backend/build_deb.sh | 173 ++++++++++++++++++++++++++++++++++++++++++ backend/nsfwapp.exe | Bin 46818910 -> 46818910 bytes 5 files changed, 221 insertions(+) create mode 100644 backend/build_deb.bat create mode 100644 backend/build_deb.sh diff --git a/.gitignore b/.gitignore index 7daec9a..555abaf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,7 @@ backend/generated backend/web/dist backend/data/pending-autostart/__global__.json backend/.gocache +backend/.gocache-build +backend/.gocache-linux +backend/.deb-build +backend/dist diff --git a/backend/build.bat b/backend/build.bat index 7c8fbd8..7c9887b 100644 --- a/backend/build.bat +++ b/backend/build.bat @@ -45,6 +45,7 @@ echo. echo Build erfolgreich. echo Windows: nsfwapp.exe echo Debian: nsfwapp-linux-amd64 +echo Debian-Paket: build_deb.bat goto end :error diff --git a/backend/build_deb.bat b/backend/build_deb.bat new file mode 100644 index 0000000..04896a5 --- /dev/null +++ b/backend/build_deb.bat @@ -0,0 +1,43 @@ +@echo off +setlocal + +cd /d "%~dp0" + +echo Baue Debian Application Package via WSL... + +where wsl >nul 2>nul +if errorlevel 1 goto wsl_missing + +set "WSL_CWD=" +for /f "delims=" %%i in ('wsl wslpath -a "%CD%" 2^>nul') do set "WSL_CWD=%%i" +if "%WSL_CWD%"=="" goto wsl_path_error +if not "%WSL_CWD:~0,1%"=="/" goto wsl_missing + +wsl bash -lc "cd ""%WSL_CWD%"" && bash ./build_deb.sh" +if errorlevel 1 goto error + +echo. +echo Debian-Paket erfolgreich gebaut. +goto end + +:wsl_missing +echo. +echo Debian-Paket-Build braucht eine installierte WSL-Linux-Distribution. +echo Einmalig installieren, z.B.: +echo wsl --install -d Debian +exit /b 1 + +:wsl_path_error +echo. +echo WSL-Pfad konnte nicht aus dem Windows-Pfad erzeugt werden: +echo %CD% +exit /b 1 + +:error +echo. +echo Debian-Paket-Build fehlgeschlagen. +exit /b 1 + +:end +endlocal +exit /b 0 diff --git a/backend/build_deb.sh b/backend/build_deb.sh new file mode 100644 index 0000000..5942639 --- /dev/null +++ b/backend/build_deb.sh @@ -0,0 +1,173 @@ +#!/usr/bin/env bash +set -euo pipefail + +PACKAGE_NAME="${DEB_PACKAGE_NAME:-nsfwapp}" +APP_TITLE="${DEB_APP_TITLE:-NSFW App}" +VERSION="${DEB_VERSION:-0.1.0}" +ARCH="${DEB_ARCH:-amd64}" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BIN_PATH="$SCRIPT_DIR/nsfwapp-linux-amd64" +BUILD_DIR="$SCRIPT_DIR/.deb-build" +PKG_ROOT="$BUILD_DIR/root" +OUT_DIR="$SCRIPT_DIR/dist" +OUT_FILE="$OUT_DIR/${PACKAGE_NAME}_${VERSION}_${ARCH}.deb" + +fail() { + echo "Fehler: $*" >&2 + exit 1 +} + +command -v dpkg-deb >/dev/null 2>&1 || fail "dpkg-deb fehlt. Installiere es mit: sudo apt install -y dpkg-dev" + +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" + +rm -rf "$BUILD_DIR" +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" + +install -m 0755 "$BIN_PATH" "$PKG_ROOT/opt/nsfwapp/nsfwapp" +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" +data_home="${XDG_DATA_HOME:-$HOME/.local/share}" +app_dir="$data_home/nsfwapp" +runtime_bin="$app_dir/nsfwapp" + +mkdir -p "$app_dir" + +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 + +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/share/applications/nsfwapp.desktop" <"$PKG_ROOT/usr/share/doc/nsfwapp/README.Debian" <<'EOF' +NSFW App fuer Debian +==================== + +Start: + nsfwapp + +Desktop: + Der Launcher "NSFW App" startet das Backend und oeffnet https://localhost:9999. + +User-Daten: + Die installierte Binary liegt unter /opt/nsfwapp/nsfwapp. + Beim Start wird sie nach ${XDG_DATA_HOME:-$HOME/.local/share}/nsfwapp/nsfwapp kopiert + und von dort ausgefuehrt. Dadurch bleiben recorder.log, recorder_settings.json, + generated/ und eine optionale externe .env im User-Bereich. + +Optionale Konfiguration: + Lege eine .env neben die Runtime-Binary, z.B.: + ~/.local/share/nsfwapp/.env + +Wichtige Laufzeitprogramme: + ffmpeg/ffprobe muessen fuer Recording, Teaser, Analyse und Videofunktionen verfuegbar sein. + Der AI-Server braucht Python und die benoetigten Python-Pakete deiner ML-Umgebung. +EOF + +cat >"$PKG_ROOT/DEBIAN/control" < +Depends: ca-certificates, ffmpeg, python3, xdg-utils, libnotify-bin +Description: NSFW recorder backend and web UI + Local Debian package for the NSFW recorder backend with embedded web UI and ML assets. +EOF + +cat >"$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" + +mkdir -p "$OUT_DIR" +dpkg-deb --build "$PKG_ROOT" "$OUT_FILE" + +echo +echo "Debian-Paket erzeugt:" +echo " $OUT_FILE" +echo +echo "Installieren:" +echo " sudo apt install ./dist/$(basename "$OUT_FILE")" diff --git a/backend/nsfwapp.exe b/backend/nsfwapp.exe index 502583c4e9a127b1dbd47cfa852bd9827b5ffa17..a2ddeed7d7d4b2b37f73cb79885ab9fbb78cfb55 100644 GIT binary patch delta 3438 zcmbW%T@N{_6?4+;$OzkT@O@uGd4sR=P*QHdkGLsKS% z26v4~it6d-5i;D@;R;EM3=SFHJ+5O)gkN&RD37#+=)Nvza#)wp(3X)AzTvLaI8TpZ z39h90=yXSPdXj%eY({A3OhZ;UJsjt#N zrJ+hAmBuPfRGO+ZQ)#Z!LZzijD-{nFPZci}ZxtUEUloUnpNhXqfJ&fBkV7Wv<5~9*krISi$l~9!~Dq$*JRl2EkR|!|?p%S4IsnSy=N~M=dv`TN47?oI+ zJ}P}x`l<9+8K5#yWsu5Xl_4raRpM0QRT5MZRh%j=m0>EwRgzSaRYs_cR2ij`qLQjI z`h=uS4{8z^;0g=~a3v;qncj(kP9J}lGu|2R=@sYja{9QOE?-B2!^<;wL+K2+8btzv ze7%Dlj@*1ZdCqy+Da{&VjkU&E>DG8_f|X%Sv@)$p)?{mnHPxDCO}A!PS=LNzmNnZ_ zYmPP7nrF?ovaJQyLTizgV=cCpSWB&C)^clwwbEK;t+v)!Ypr$GdTWEV(aNdnqwcXlb?X-4TyRALeUTdGV-#TC&v<_K^ts~Y^>zH-iI$@o(PFbg|GuBz_oORy1 zVC7l))l5o!>yh=D^||%f`oj9sdSX4bzOufyzOlZwzO%l!ez1PDo>|YWpRAv)U#wrP z->l!QKde8kzpTHl7uHMbmGzJHuk||nWhb{B3*4aq6of)h7>YnqCp#+qKQcxPo zKv^gU<)H#pgi25usz6n!2GyYk)P!148|pw^s0a0-0W^e0&={IPQ)mXwp#`*rR^S1i z;04~`1HRw@Kk$bD2!tSL4Q-$;w1f800fHd}I>MVj?aUMkT_6m)LO19R;m`vjAQE~) z6!d~<=nXLt3w@w3^n?B|00zP!7z{&TD8xZLBtRlK!3D!$I3z(bjDV3a3Q`~yMnf8m zfw3?S(qX(?o^2hs%v=9+qvf#CjERs5lVCDTfvGSJro#-#f|)Q2W`n{Um<#h@K4ilJ zSO|+C2NuH;SPIKvIjn${unJbg8dwYKU_ESrjgSkQU^8rit*{NY!w%R9yI?o$fxWN~ z_QL@<2#4S>9D$>7435JII0>iVG@OC6a1PGH1;~SZxCocvGF*YHa1E}*4Y&!n;5OWW zyYLpg4fo(ayaVsTd+8p<@H_kgf5KnzH@twC@CyEcf8n)Tc7ADh8{EJh3P3?91cjjp z6oq0SP#j7?Nhk$xo+`ss7Ro_+r~nnA5>$pNP!*~{b*KR~p%&DJI#3ttL49Zd4WSV< zh9=Mynn81D0WF~wcz`E(fj9VoFF3#t{2>4WAqZMS8)ysdpgnYeU!Xn6l#jpgH!ZKJ6D_|w8g4M7F*1|ei4;x@3y2SKumKgX?euZo22$ J`g7kH`yWpVgo6M8 delta 3438 zcmbW%)mIf*6oBys_O`pb1G!w_;>E-O6+y88o4O(fV0XI>R1`b0ySu@TaY|>@8E2eP zCv>{YQD=Yt3G?v%);{a3bso;cesp_xxkuKL2YIrxZXJGjykK-nY}@d(WY@4Lr?dNz z*p$HGi9SBQAsr^fNA*k}866%zVr*J+Ohmw7w{Lnvj~GuVz=ZlcSK~uI9IrTsynQf)Ofw@u~eKXDqbqyDtT1$s^nA2uTnszph_VXyDh9z zM5U-oF_q#fB~(hPlu{|JQbwh$N;#GCDiu^Js#H>`tWrg#s!BDL>MAuRDqU0}R3cTns&rF{Qt7VJL#3xmFO}XZ z(JC=2u_}F3`l|F(>8~ti#q3>!@|iI&Ph?PFkm|)7Ba5taZ*h zZ(Xo*tX%7&b;-JHU9qlO*R1Q-4eO?L%X-VYZM|*1W4&v=XT5LTvF=(QSRY#Vtozmj z>m%!9>!J0D^{Ms9`po*=dTc$ho?2g6Us_*TUt7AkJeAt&(<&2 zuhwtY@75pIpVnX2-_}3Y3+rF&rS-~so$;c*SEdEtkO%TYKFALRpdb_ifx=J(ib63c z4ke%@l!DSw2FgM?C=V5&B2c^QRq{LLm$~LMP}9;m`#lAQHMl zH;97n&;xoxFX#=?5CgH$2l_%k=nn&6APj;yh=&A7ge365U`U1`kOD(t7z~FIkP2y# z4kKX{jD|5V)+@)hj@QIn|8t{dveAqQFcBufWS9a|VH!+_888!O!EBfV3Ugr|%!dV# z0SjRfEQU;20!twamcepZ0V`n@tcEqP7S_Rf*Z>%k58j76a2Gy+58)o%hX?Qxd<+la6ZjM!!DsL}JccLm6uy8j;VbwWp22hY z2EK*w;CuK1euSUkXZQtvh2P+J_yhigzu<592VTIx@Dg6ZYp;yl;@&oRfj8uVypRv_ zLjfoVg+QP%6oH~p4Bk9df~h2wg3?e1%0f9P4;7#yRD#M-1*$?ds17xtCe(u3PzUNl zJ*W>2pdmDZ#?S=ng%gC-j2e5DhU93w@w3^n?B|00zP!h=X`YfJ8_F4-AH6 z7y>CU6o$cY7y+q}2I(*oM!{$p17l$vjE4y@5hlT8m;zH_8cc^7FcW6MY?uQIb73CL zhXs%U3tw%02?72Ho<1t0$X7lY=<4N6L!IF z*aLfEAMA$%a1ai`VK@Ru;TRl;6L1nv!D%=HXW<;2hYOGcxo{CK!DYAtSK%65hZ}Iy MJIB_a_r~7;0Z4p;%m4rY