Commit a7a8304
committed
feat(ftp): implement asynchronous FTP/SFTP upload queue with improved remote gallery
This commit introduces a fully asynchronous upload pipeline for FTP/SFTP
remote storage, decoupling image upload from the photo capture workflow so
the Photobooth UI is never blocked while files are transferred.
Core architecture
-----------------
- New SQLite-backed UploadQueueService (src/Service/UploadQueueService.php)
manages a persistent job queue (pending → in_progress → completed/failed).
Each job stores a random 32-hex-character remote filename so local and
remote filenames are never the same, preventing enumeration.
- New EncryptionService (src/Service/EncryptionService.php) encrypts the FTP
password at rest using libsodium secretbox; key is stored in var/run/.
- New Symfony Console command UploadWorkerCommand
(src/Command/UploadWorkerCommand.php) runs as a long-lived background
worker (or once with --once). Picks up jobs, calls RemoteStorageService,
retries up to 5 times on failure, and reloads config on every run so admin
panel changes are picked up without restarting.
- New api/ftpListFolders.php lets the admin panel browse remote directories
before saving configuration.
- resources/config/photobooth-upload-worker.service: systemd unit for running
the worker as www-data.
API / backend changes
---------------------
- api/applyEffects.php: instead of uploading directly, enqueues a job via
UploadQueueService and triggers the worker process in the background.
- api/deletePhoto.php: resolves the remote random filename via
UploadQueueService::getRemoteFilename() before deleting on FTP, so the
correct remote file is removed.
- api/qrcode.php, api/print.php: QR URLs now use UploadQueueService to look
up the remote filename when FTP + useForQr is enabled.
- api/admin.php: exposes upload queue status (pending/failed counts) for the
debug panel.
- api/serverInfo.php: includes FTP queue stats in server-info response.
- RemoteStorageService::getWebpageUri() correctly appends baseFolder to the
website URL.
- RemoteStorageService::createWebpage() removes legacy .htaccess files
(caused 403 on hosts without AllowOverride Options) and instead uploads
index.php redirect guards to images/ and thumbs/.
- ConfigurationService: decrypts FTP password on load via EncryptionService.
- FtpConfiguration: password field marked as sensitive.
- src/Console/Application.php: registers UploadWorkerCommand.
Admin UI
--------
- lib/configsetup.inc.php: removed deprecated folder/urlTemplate fields;
added folder browser (ftpListFolders API), queue status display, and
"Test Connection" improvements.
- assets/js/admin/buttons.js: folder-browser modal, queue status polling,
FTP test-connection wiring.
- resources/lang/en.json: removed ftp:folder / ftp:urlTemplate keys; updated
manual:ftp:website description.
Remote gallery (resources/template/index.php)
---------------------------------------------
- Single-image view: image is rendered immediately with a JS onload/onerror
spinner; onerror auto-reloads every 3 s while upload is in progress.
Removed the PHP-side file_exists() upload-wait loop.
- Gallery mode: fixed guard so gallery is only rendered when
gallery_enabled=true (was falling through to else).
- Images sorted newest-first via usort + filemtime.
- ZIP download: fixed corrupt archive by using ZipArchive::CREATE |
ZipArchive::OVERWRITE (tempnam creates an existing file).
- Share button: uses Web Share API with native file sharing where supported;
falls back to wa.me deep-link. Icon changed from fa-brands fa-whatsapp to
fa-solid fa-share-nodes.
- Lightbox navigation: prev/next arrow buttons with wrap-around and keyboard
support (ArrowLeft / ArrowRight / Escape).
Code style
----------
- PHP CS Fixer: expanded single-line closures in Configuration/Section/*
to multi-line form for consistency with project style rules.1 parent 6296d4f commit a7a8304
File tree
22 files changed
+1131
-157
lines changed- admin/debug
- api
- assets/js
- admin
- lib
- resources
- config
- lang
- template
- src
- Command
- Configuration/Section
- Console
- Service
22 files changed
+1131
-157
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
| 54 | + | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
182 | 183 | | |
183 | 184 | | |
184 | 185 | | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
185 | 194 | | |
186 | 195 | | |
187 | 196 | | |
| |||
334 | 343 | | |
335 | 344 | | |
336 | 345 | | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
337 | 355 | | |
338 | 356 | | |
339 | 357 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| |||
336 | 337 | | |
337 | 338 | | |
338 | 339 | | |
339 | | - | |
| 340 | + | |
340 | 341 | | |
341 | | - | |
342 | | - | |
343 | | - | |
344 | | - | |
345 | | - | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
346 | 348 | | |
347 | 349 | | |
348 | 350 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
19 | | - | |
20 | | - | |
21 | 20 | | |
22 | 21 | | |
23 | 22 | | |
| |||
81 | 80 | | |
82 | 81 | | |
83 | 82 | | |
84 | | - | |
85 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
86 | 88 | | |
87 | 89 | | |
88 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
156 | 157 | | |
157 | 158 | | |
158 | 159 | | |
159 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
160 | 163 | | |
161 | | - | |
162 | | - | |
| 164 | + | |
163 | 165 | | |
164 | 166 | | |
165 | 167 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | 24 | | |
27 | 25 | | |
28 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
29 | 33 | | |
30 | 34 | | |
31 | 35 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| |||
0 commit comments