Skip to content

Commit 5aba175

Browse files
Photoboothflacoonb
authored andcommitted
fix: align docs with code and fix ESLint quote style for CI
- Fix ESLint single-quote violations in shellQuote and rsync args (remotebuzzer-server.js, sync-to-drive.js) that caused CI build failure - Add usb-sync.md to mkdocs_remote.yml navigation - Fix socket.io command name: move2usb → start-move2usb in docs - Remove non-existent hardware button trigger claim from Move2USB docs - Document general_permissions() auto-installing USB mount permissions - Clarify sudoers paths, numeric uid/gid, unmount behavior, copy.chk cleanup, and legacy file removal in USB Sync docs Made-with: Cursor
1 parent 36c3bfa commit 5aba175

File tree

5 files changed

+26
-19
lines changed

5 files changed

+26
-19
lines changed

assets/js/remotebuzzer-server.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ let collageInProgress = false,
1212
const { execSync, spawnSync } = require('child_process');
1313
const { pid: PID, platform: PLATFORM } = process;
1414
const REARM_TIMEOUT_MS = 60000; // Fallback to re-arm trigger if no completion arrives
15-
const shellQuote = (s) => "'" + String(s).replace(/'/g, "'\\''") + "'";
15+
const shellQuote = (s) => '\'' + String(s).replace(/'/g, '\'\\\'\'') + '\'';
1616

1717
/* LOGGING FUNCTION */
1818
const log = function (...optionalParams) {
@@ -750,7 +750,7 @@ function move2usbAction() {
750750
// First check the mountpoint from lsblk data
751751
if (drive.mountpoint) {
752752
try {
753-
execSync(`mountpoint -q '${drive.mountpoint.replace(/'/g, "'\\''")}'`, { stdio: 'ignore' });
753+
execSync(`mountpoint -q '${drive.mountpoint.replace(/'/g, '\'\\\'\'')}'`, { stdio: 'ignore' });
754754
return drive.mountpoint;
755755
// eslint-disable-next-line no-unused-vars
756756
} catch (err) {

assets/js/sync-to-drive.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { execSync, spawn } = require('child_process');
77
const fs = require('fs');
88
const path = require('path');
99

10-
const shellQuote = (s) => "'" + String(s).replace(/'/g, "'\\''") + "'";
10+
const shellQuote = (s) => '\'' + String(s).replace(/'/g, '\'\\\'\'') + '\'';
1111

1212
const log = (...optionalParams) => {
1313
const currentDate = new Date();
@@ -126,10 +126,10 @@ class SyncToDrive {
126126
'-b',
127127
'--backup-dir=' + path.join(device.mountpoint, 'deleted'),
128128
'--ignore-existing',
129-
"--exclude='deleted'",
130-
"--include='*.'{jpg,chk,gif,mp4}",
131-
"--include='*/'",
132-
"--exclude='*'",
129+
'--exclude=\'deleted\'',
130+
'--include=\'*.\'{jpg,chk,gif,mp4}',
131+
'--include=\'*/\'',
132+
'--exclude=\'*\'',
133133
'--prune-empty-dirs',
134134
this.source + '/',
135135
destinationPath
@@ -440,7 +440,7 @@ class SyncToDrive {
440440
// First check the mountpoint from lsblk data
441441
if (device.mountpoint) {
442442
try {
443-
execSync(`mountpoint -q '${device.mountpoint.replace(/'/g, "'\\''")}'`, { stdio: 'ignore' });
443+
execSync(`mountpoint -q '${device.mountpoint.replace(/'/g, '\'\\\'\'')}'`, { stdio: 'ignore' });
444444

445445
return device.mountpoint;
446446
// eslint-disable-next-line no-unused-vars

docs/faq/remote-button.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ Notes
6060
## 3) Remote trigger via Socket.io
6161

6262
- Channel: `photobooth-socket`
63-
- Commands: `start-picture`, `start-collage`, `collage-next`, `start-custom`, `start-video`, `print`, `rotary-cw`, `rotary-ccw`, `rotary-btn-press`, `move2usb`
63+
- Commands: `start-picture`, `start-collage`, `collage-next`, `collage-wait-for-next`, `start-custom`, `start-video`, `start-move2usb`, `print`, `rotary-cw`, `rotary-ccw`, `rotary-btn-press`, `completed`, `in-progress`
6464
- Response: `completed` after the workflow finishes.
65-
- `move2usb` copies (or moves) all photos/videos to the configured USB stick — see [USB Sync & Move2USB](usb-sync.md) for setup and permissions.
65+
- `start-move2usb` copies (or moves) all photos/videos to the configured USB stick — see [USB Sync & Move2USB](usb-sync.md) for setup and permissions.
6666

6767
## 4) Remote trigger via simple web requests (HTTP)
6868

docs/faq/usb-sync.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Photobooth offers two ways to get your photos and videos onto a USB stick:
55
| Feature | Purpose | Trigger |
66
|---------|---------|---------|
77
| **USB Sync** | Automatic background sync at a regular interval | Runs continuously while Photobooth is open |
8-
| **Move2USB** | One-shot copy **or** move of all media | Manual — HTTP endpoint, socket.io command, or hardware button |
8+
| **Move2USB** | One-shot copy **or** move of all media | Manual — HTTP endpoint or socket.io command |
99

1010
Both features share the same USB device identifier (Adminpanel → **USB Sync → USB device identifier**) and the same Linux mount permissions.
1111

@@ -26,7 +26,7 @@ The web-server user (`www-data`) needs permission to mount and unmount USB drive
2626
Photobooth ships two complementary mechanisms that are installed via the **Photobooth Setup Wizard**:
2727

2828
1. **Polkit rule** — allows `www-data` to call `udisksctl mount` / `udisksctl unmount` without a password.
29-
2. **sudoers rule** (`/etc/sudoers.d/021_www-data-usb-sync`) — passwordless `sudo mount`, `sudo umount` and `sudo mkdir -p /media/*` as fallback when udisksctl is unavailable.
29+
2. **sudoers rule** (`/etc/sudoers.d/021_www-data-usb-sync`) — passwordless `sudo mount /dev/* /media/*`, `sudo umount /dev/*` and `sudo mkdir -p /media/*` as fallback when udisksctl is unavailable. Both `/bin` and `/usr/bin` paths are covered for portability.
3030

3131
### Installing via the Setup Wizard
3232

@@ -45,8 +45,10 @@ The wizard will:
4545

4646
- Install the Polkit rule for udisksctl.
4747
- Install the sudoers rule for mount/umount/mkdir.
48-
- Try to disable desktop auto-mount (pcmanfm volume handling) to avoid permission conflicts.
49-
- Remove any legacy `020_www-data-usb` sudoers file.
48+
- Disable desktop auto-mount (pcmanfm `mount_on_startup`, `mount_removable`, `autorun` in both the system default and user profile config) to avoid permission conflicts.
49+
- Remove any legacy `020_www-data-usb` sudoers file and `50-photobooth-udisks.rules` polkit file.
50+
51+
**Note:** USB mount permissions are also installed automatically when running **2 Fix general permissions** or during a fresh Photobooth install. The dedicated "USB Sync policy" menu entry is only needed to re-apply or remove the rules individually.
5052

5153
Run the same menu entry again after OS upgrades to re-apply the rules.
5254

@@ -115,13 +117,12 @@ Move2USB lets you copy — or move — **all** current photos and videos to the
115117

116118
### Triggering Move2USB
117119

118-
- **HTTP endpoint:** `http://<IP>:<Port>/commands/start-move2usb`
119-
- **Socket.io:** emit `photobooth-socket``move2usb`
120-
- **Hardware button:** assign a key code to the Move2USB action (same input-device mechanism as picture/collage/print).
120+
- **HTTP endpoint:** `http://<IP>:<Port>/commands/start-move2usb` — requires Hardware Buttons enabled and Move2USB mode not `disabled`.
121+
- **Socket.io:** emit `photobooth-socket``start-move2usb`
121122

122123
### Copy verification
123124

124-
Move2USB creates a `copy.chk` marker file in the Photobooth data folder before rsync and expects it to appear on the USB stick after sync. If the marker is missing on the USB stick after rsync, the sync is treated as **failed** and no files are deleted (even in `move` mode).
125+
Move2USB creates a `copy.chk` marker file in the Photobooth data folder before rsync and expects it to appear on the USB stick after sync. If the marker is missing on the USB stick after rsync, the sync is treated as **failed** and no files are deleted (even in `move` mode). After successful verification, both the local and USB-side `copy.chk` files are cleaned up automatically.
125126

126127
### What gets deleted in "move" mode
127128

@@ -140,12 +141,17 @@ Photobooth uses a layered approach to mount USB drives:
140141
2. **findmnt check** — if udisksctl output was ambiguous, verify via `findmnt`.
141142
3. **sudo mount** — fallback using the sudoers rule; mounts to `/media/<label>`.
142143

143-
For **FAT32** (`vfat`) and **exFAT** volumes the mount options `umask=0000,uid=<www-data>,gid=<www-data>` are set automatically so the web-server process can write to the stick.
144+
For **FAT32** (`vfat`) and **exFAT** volumes the mount options `umask=0000,uid=<uid>,gid=<gid>` (using the numeric uid/gid of the running process, typically `33` for `www-data`) are set automatically so the web-server process can write to the stick.
144145

145146
If a drive is already mounted but **not writable** (e.g. auto-mounted by the desktop with different uid/gid), Photobooth unmounts and re-mounts it with the correct options.
146147

147148
Unmounting follows the same order: udisksctl first, `sudo umount` as fallback.
148149

150+
**When does each feature unmount?**
151+
152+
- **USB Sync** keeps the stick mounted between sync intervals and only unmounts on process termination (SIGTERM/SIGHUP/SIGINT).
153+
- **Move2USB** unmounts the stick after every sync operation (before deleting local files in `move` mode).
154+
149155
---
150156

151157
## Preparing a USB stick

mkdocs_remote.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ nav:
4747
- Screensaver: faq/screensaver.md
4848
- Tutorials: faq/tutorials.md
4949
- Remote Buttons: faq/remote-button.md
50+
- USB Sync & Move2USB: faq/usb-sync.md
5051
- Printer Troubleshooting: faq/printer-troubleshooting.md
5152
- gphoto2 Troubleshooting: faq/gphoto2-troubleshooting.md
5253
- GO2RTC Troubleshooting: faq/go2rtc-troubleshooting.md

0 commit comments

Comments
 (0)