Просмотр исходного кода

Fix Windows install syntax error from multi-line for /f command (#544)

  The Python hash verification in start_bambuddy.bat used a multi-line
  `for /f "usebackq"` with a backtick-delimited command split across
  lines. Windows CMD cannot parse line breaks inside backtick-delimited
  for /f commands, causing "The syntax of the command is incorrect" at
  step 1/6. Removed the entire redundant verification block — the
  verify_sha256 subroutine already checks the archive against the
  pinned hash. The removed block also had a secondary bug: it always
  downloaded the amd64 checksum from python.org even on arm64 systems.
maziggy 6 месяцев назад
Родитель
Сommit
f488c9f3f4
2 измененных файлов с 1 добавлено и 56 удалено
  1. 1 1
      CHANGELOG.md
  2. 0 55
      install/start_bambuddy.bat

+ 1 - 1
CHANGELOG.md

@@ -16,7 +16,7 @@ All notable changes to Bambuddy will be documented in this file.
 ### Fixed
 - **Sidebar Navigation Ignores User Permissions** — All sidebar navigation items (Archives, Queue, Stats, Profiles, Maintenance, Projects, Inventory, Files) were visible to every user regardless of their role's permissions. Only the Settings item was permission-gated. Now each nav item is hidden when the user lacks the corresponding read permission (e.g., `archives:read`, `queue:read`, `library:read`). The Printers item remains always visible as the home page. Also added the missing `inventory:read|create|update|delete` permissions to the frontend Permission type (they existed in the backend but were absent from the frontend type definition).
 - **Camera Button Clickable Without Permission & ffmpeg Process Leak** ([#550](https://github.com/maziggy/bambuddy/issues/550)) — Two camera issues in multi-user environments (e.g., classrooms with multiple printers). First, the camera button on the printer card was clickable even when the user's role lacked `camera:view` permission. Now disabled with a permission tooltip, matching the existing pattern for `printers:control` on the chamber light button. Second, ffmpeg processes (~240MB each) were never cleaned up after closing a camera stream. The `stop_camera_stream` endpoint called `terminate()` but never `wait()`ed or `kill()`ed, and HTTP disconnect detection in the streaming response only checked between frames — if the generator was blocked reading from ffmpeg stdout, disconnect was never detected (due to TCP send buffer masking the closed connection). Three fixes: (1) the stop endpoint now uses `terminate()` → `wait(2s)` → `kill()` → `wait()`; (2) each stream gets a background disconnect monitor task that polls `request.is_disconnected()` every 2 seconds independently of the frame loop, directly killing the ffmpeg process on disconnect; (3) a periodic cleanup (every 60s) scans `/proc` for any ffmpeg process with a Bambu RTSP URL (`rtsps://bblp:`) that isn't in an active stream and `SIGKILL`s it — catching orphans that survive app restarts or generator abandonment.
-- **Windows Install Fails With "Syntax of the Command Is Incorrect"** ([#544](https://github.com/maziggy/bambuddy/issues/544)) — The `start_bambuddy.bat` launcher had Unix (LF) line endings instead of Windows (CRLF). When a user's git config has `core.autocrlf=false` or `input`, the file is checked out with LF endings and `cmd.exe` cannot parse it. Added a `.gitattributes` file that forces CRLF for all `.bat` files regardless of git config.
+- **Windows Install Fails With "Syntax of the Command Is Incorrect"** ([#544](https://github.com/maziggy/bambuddy/issues/544)) — The `start_bambuddy.bat` Python hash verification used a multi-line `for /f "usebackq"` with a backtick-delimited command split across lines. Windows CMD cannot parse line breaks inside backtick-delimited `for /f` commands, causing "The syntax of the command is incorrect" immediately after downloading Python. The entire block was also redundant — it downloaded a separate checksum file from python.org and re-verified the hash, but `verify_sha256` had already checked the archive against the pinned hash on the previous line. Removed the duplicate verification block. Also had a secondary bug: always downloaded the `amd64` checksum even on `arm64` systems.
 - **Queue Badge Shows on Incompatible Printers** ([#486](https://github.com/maziggy/bambuddy/issues/486)) — The purple queue counter badge in the printer card header showed on all printers of the same model when a job was scheduled for "any [model]", even if the printer didn't have the matching filament color loaded. The `PrinterQueueWidget` (which shows "Clear Plate & Start") already filtered by filament type and color, but the badge count used the raw unfiltered queue length. Now applies the same filament compatibility filter to the badge count.
 - **SpoolBuddy Daemon Can't Find Hardware Drivers** — The daemon's `nfc_reader.py` and `scale_reader.py` import `read_tag` and `scale_diag` as bare modules, but these files live in `spoolbuddy/scripts/` which isn't on Python's module search path. The systemd service sets `WorkingDirectory` to `spoolbuddy/` and runs `python -m daemon.main`, so only the `spoolbuddy/` and `daemon/` directories are on `sys.path`. Added `scripts/` to `sys.path` at daemon startup, resolved relative to the module file so it works regardless of install path. Also moved the `read_tag` import inside `NFCReader.__init__`'s try/except block — it was previously outside, so a missing module crashed the entire daemon instead of gracefully skipping NFC polling. Demoted hardware-not-available log messages from ERROR to INFO since missing modules are expected when hardware isn't connected.
 - **SpoolBuddy Scale Tare & Calibration Not Applied** — The SpoolBuddy scale tare and calibrate buttons on the Settings page queued commands but never executed them. Five bugs in the chain: (1) the daemon received the `tare` command via heartbeat but never called `scale.tare()` — a comment said "need cross-task communication" but the ScaleReader was already available in the shared dict; (2) no API endpoint existed for the daemon to report the new tare offset back to the backend database, so tare results were lost; (3) when calibration values changed in heartbeat responses, the daemon updated its config object but never called `scale.update_calibration()`, so the ScaleReader kept using its initial values forever; (4) the heartbeat response that delivered the tare command still contained pre-tare calibration values, which immediately overwrote the new tare offset back to zero; (5) the `set-factor` endpoint computed `calibration_factor` using the DB `tare_offset`, which could be stale or zero if the tare hadn't persisted yet — producing a wildly wrong factor (e.g., 5000g displayed with empty scale). Added a `POST /devices/{device_id}/calibration/set-tare` endpoint and `update_tare()` API client method. The heartbeat loop now executes `scale.tare()` when the tare command is received, persists the result via the new endpoint, propagates calibration changes to the ScaleReader instance, and skips calibration sync on the heartbeat cycle that delivers a tare command. The calibration flow now captures the raw ADC at tare time and sends it alongside the loaded-weight ADC in step 2, so the factor is computed from the actual tare reference rather than the DB value — making calibration self-contained and independent of the tare persistence round-trip. The calibration weight input uses a compact touch-friendly numpad since the RPi kiosk has no physical keyboard.

+ 0 - 55
install/start_bambuddy.bat

@@ -172,66 +172,11 @@ if errorlevel 1 (
 call :verify_sha256 "%PORTABLE%\python.zip" "%PYTHON_ZIP_HASH_EXPECTED%" "Python"
 if errorlevel 1 (
     echo [ERROR] Failed to download Python archive.
-    pause
-    exit /b 1
-)
-
-REM Download official SHA256 checksum for the Python archive
-curl -L --progress-bar -o "%PORTABLE%\python.zip.sha256" ^
-    "https://www.python.org/ftp/python/%PYTHON_VER%/python-%PYTHON_VER%-embed-amd64.zip.sha256"
-if errorlevel 1 (
-    echo [ERROR] Failed to download Python checksum file.
-    del "%PORTABLE%\python.zip" >nul 2>&1
-    pause
-    exit /b 1
-)
-
-REM Compute SHA256 hash of the downloaded archive
-set "PYTHON_ZIP_HASH="
-for /f "tokens=1 usebackq" %%H in (`
-    certutil -hashfile "%PORTABLE%\python.zip" SHA256 ^| findstr /R /I "^[0-9A-F][0-9A-F]"
-`) do (
-    set "PYTHON_ZIP_HASH=%%H"
-    goto :python_hash_done
-)
-
-:python_hash_done
-if not defined PYTHON_ZIP_HASH (
-    echo [ERROR] Failed to compute SHA256 hash for Python archive.
-    del "%PORTABLE%\python.zip" >nul 2>&1
-    del "%PORTABLE%\python.zip.sha256" >nul 2>&1
-    pause
-    exit /b 1
-)
-
-REM Read expected SHA256 hash from the checksum file
-set "PYTHON_ZIP_HASH_EXPECTED="
-for /f "tokens=1" %%H in ('type "%PORTABLE%\python.zip.sha256"') do (
-    set "PYTHON_ZIP_HASH_EXPECTED=%%H"
-    goto :python_expected_hash_done
-)
-
-:python_expected_hash_done
-if not defined PYTHON_ZIP_HASH_EXPECTED (
-    echo [ERROR] Failed to read expected SHA256 hash for Python archive.
-    del "%PORTABLE%\python.zip" >nul 2>&1
-    del "%PORTABLE%\python.zip.sha256" >nul 2>&1
-    pause
-    exit /b 1
-)
-
-REM Compare actual and expected hashes (case-insensitive)
-if /I not "%PYTHON_ZIP_HASH%"=="%PYTHON_ZIP_HASH_EXPECTED%" (
-    echo [ERROR] SHA256 checksum verification for Python archive failed.
-    echo [INFO] Expected: %PYTHON_ZIP_HASH_EXPECTED%
-    echo [INFO] Actual:   %PYTHON_ZIP_HASH%
     del "%PORTABLE%\python.zip" >nul 2>&1
-    del "%PORTABLE%\python.zip.sha256" >nul 2>&1
     pause
     exit /b 1
 )
 
-del "%PORTABLE%\python.zip.sha256" >nul 2>&1
 echo Extracting Python...
 tar -xf "%PORTABLE%\python.zip" -C "%PYTHON_DIR%"
 if errorlevel 1 (