bambuddy-nix/pkgs/bambuddy/default.nix

205 lines
5.3 KiB
Nix
Raw Permalink Normal View History

{
lib,
stdenv,
fetchFromGitHub,
buildNpmPackage,
python3,
makeWrapper,
ffmpeg,
}:
let
pname = "bambuddy";
version = "1.2.5.7";
src = fetchFromGitHub {
owner = "maziggy";
repo = "bambuddy";
rev = "188df76f8a7342542c0876dac68990ea2a8c8313"; # v1.2.5.7
hash = "sha256-KmlAdFoSIMa6Wahd4XPBvaBtpVR/5LPNMyaimuDZVb0=";
};
# Runtime Python dependencies, mirroring upstream requirements.txt.
# All of these ship in nixpkgs. Optional heavy extras (opencv4,
# fast-simplification) are included for feature parity with the upstream
# Docker image, which installs requirements.txt in full; the affected
# features (plate detection, STL thumbnails) degrade gracefully if absent.
pythonDeps =
ps: with ps; [
# Web framework
fastapi
uvicorn
uvloop
httptools
websockets
python-dotenv
# Database
sqlalchemy
aiosqlite
asyncpg
greenlet
# Pydantic / settings
pydantic
pydantic-settings
# Bambu Lab printer communication (MQTT / FTP)
paho-mqtt
aioftp
pyftpdlib
cryptography
pyopenssl
asyncssh
# 3MF processing
defusedxml
# Excel export
openpyxl
# Utilities
python-multipart
aiofiles
# QR codes / PDF generation / PDF thumbnails
qrcode
reportlab
pypdfium2
# STL thumbnails
trimesh
matplotlib
fast-simplification
networkx
lxml
# System monitoring
psutil
# Authentication
pyjwt
passlib
bcrypt
ldap3
pyotp
# HTTP clients
idna
httpx
certifi
curl-cffi
urllib3
aiohttp
# Plate detection
opencv4
numpy
pillow
];
pythonEnv = python3.withPackages pythonDeps;
# Prebuilt React frontend. `vite build` emits to `../static` (the app root,
# next to `backend/`), matching the upstream Dockerfile.
frontend = buildNpmPackage {
pname = "${pname}-web";
inherit version src;
sourceRoot = "${src.name}/frontend";
npmDepsHash = "sha256-S+WU4jgs2DPWHHfspeo5k8vPECK+5SidGa8kzI4K4lw=";
# The source tree arrives from the store read-only, but `vite build`
# empties and writes ../static (the repo ships a committed static/ dir).
preBuild = ''
chmod -R u+w "$NIX_BUILD_TOP/${src.name}"
rm -rf ../static
'';
installPhase = ''
runHook preInstall
mkdir -p $out/share
cp -r ../static $out/share/static
runHook postInstall
'';
meta = {
description = "Web frontend for Bambuddy";
license = lib.licenses.agpl3Only;
platforms = lib.platforms.unix;
};
};
in
stdenv.mkDerivation {
inherit pname version src;
dontBuild = true;
nativeBuildInputs = [ makeWrapper ];
buildInputs = [ pythonEnv ];
passthru = {
inherit pythonEnv frontend;
};
installPhase = ''
runHook preInstall
# App root: `backend/` (Python sources) + `static/` (prebuilt frontend).
# backend.app.core.config resolves both relative to this root, exactly
# like the upstream Docker image (/app/backend + /app/static).
mkdir -p $out/share/bambuddy
cp -r ${src}/backend $out/share/bambuddy/backend
cp -r ${frontend}/share/static $out/share/bambuddy/static
chmod -R u+w $out/share/bambuddy
# The upstream test suite is not shipped in the runtime package.
rm -rf $out/share/bambuddy/backend/tests
find $out/share/bambuddy -type d -name __pycache__ -prune -exec rm -rf {} +
install -Dm644 ${src}/LICENSE -t $out/share/licenses/bambuddy
mkdir -p $out/bin
install -Dm755 ${./wrapper.sh} $out/bin/bambuddy
# Substitute at build time so @out@ resolves to THIS package's path.
# (A separate replaceVars derivation would substitute its own outPath
# instead — which silently broke the PYTHONPATH in the launcher.)
substituteInPlace $out/bin/bambuddy \
--replace-warn '@out@' "$out" \
--replace-warn '@pythonEnv@' "${pythonEnv}"
# ffmpeg is used for timelapse conversion and camera stream re-encoding.
wrapProgram $out/bin/bambuddy \
--prefix PATH : ${lib.makeBinPath [ ffmpeg ]}
runHook postInstall
'';
# Fix up the interpreter reference in the substituted wrapper.
preFixup = ''
patchShebangs $out/bin/bambuddy
'';
meta = {
description = "Self-hosted command center for Bambu Lab 3D printers";
longDescription = ''
Bambuddy is a self-hosted command center for Bambu Lab 3D printers —
from a single A1 to an entire print farm. Monitor printers in real
time, archive every print automatically, slice and queue jobs locally,
and manage the whole workflow without Bambu's cloud.
This package bundles the FastAPI backend and the prebuilt React
frontend behind a single `bambuddy` launcher. Configuration is done via
environment variables (DATA_DIR, LOG_DIR, HOST, PORT, ...) — see the
NixOS module (`services.bambuddy`) or upstream `.env.example` for the
full list.
'';
homepage = "https://bambuddy.cool/";
changelog = "https://github.com/maziggy/bambuddy/releases/tag/v${version}";
license = lib.licenses.agpl3Only;
sourceProvenance = with lib.sourceTypes; [ fromSource ];
platforms = lib.platforms.unix;
mainProgram = "bambuddy";
};
}