From 978ba234b6701383ebe8f7681c4080d1f4670880 Mon Sep 17 00:00:00 2001 From: hbrain Date: Mon, 25 May 2026 22:42:03 +0200 Subject: [PATCH] Add project README --- README.md | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..7d01bb7 --- /dev/null +++ b/README.md @@ -0,0 +1,348 @@ +# movmaker-webui + +A small PHP web interface for publishing and managing **MVLog** videos on Bubulescu.Org. + +The app has two sides: + +- **Public landing page**: lists rendered videos from `out-dir/`. +- **Admin page**: creates and edits movmaker input directories in `in-dir/`. + +Generated videos are rendered by the separate `movmaker` worker script and published back into this web app. + +## Paths and URLs + +Production location: + +```text +/var/www/html/mvlog +``` + +Public URLs: + +```text +https://bubulescu.org/mvlog/ +https://bubulescu.org/mvlog/new.php +https://bubulescu.org/mvlog/login.php +https://bubulescu.org/mvlog/feed.php +``` + +Important directories: + +```text +in-dir/ Admin-created movmaker input directories +out-dir/ Rendered public videos +cache/ Cached video metadata +assets/ CSS assets, background image, fonts +thumbs/ Reserved for thumbnails +``` + +## Main files + +```text +index.php Public video landing page +new.php Protected admin interface +login.php PHP session login page +logout.php Destroys admin session and redirects to login +feed.php RSS feed of latest videos +auth.php PHP session authentication helpers +config.php Main app config +style.css Site/admin styling +``` + +## Features + +### Public landing page + +`index.php` lists videos from `out-dir/`. + +Features: + +- Dark cinematic MVLog theme +- Sticky compact header +- RSS icon in the header +- One video per row +- Metadata display: + - title + - event date from embedded metadata + - location when available + - description when available + - video creation/publish timestamp in the top-right corner of each row +- Download discouraged with: + - `controlsList="nodownload"` + - right-click disabled on videos +- Video metadata cached in `cache/videos.json` + +### RSS feed + +`feed.php` exposes an RSS feed of recent videos: + +```text +https://bubulescu.org/mvlog/feed.php +``` + +The feed includes video title, link, description, publication date, and video enclosure. + +### New badges + +Recent videos can be styled with a `New` badge. The CSS class is: + +```css +.new-badge +``` + +### Admin page + +`new.php` is protected by PHP session login. + +Admin tabs: + +- **New**: create a new input directory +- **Edit**: edit existing input directories +- **Videos**: manage orphan videos not referenced by `.movmaker-state.json` + +Admin can: + +- Create input dirs +- Upload images/videos/audio +- Edit metadata +- Edit per-file captions for images/videos +- Remove media files +- Delete input dirs +- Optionally delete the generated output video associated with an input dir +- Delete orphan videos + +Internal files such as `.movmaker-state.json` and `data.txt` are not shown as removable media files. + +## Authentication + +The admin area uses PHP sessions, not nginx Basic Auth. + +Auth files: + +```text +/var/www/html/mvlog/auth.php +/etc/mvlog/auth.php +``` + +`/etc/mvlog/auth.php` stores username/password hashes outside the web root: + +```php + [ + 'username' => 'password_hash_here', + ], +]; +``` + +The password hash should be generated with PHP `password_hash()`. + +Example: + +```bash +php -r 'echo password_hash("new-password", PASSWORD_DEFAULT), PHP_EOL;' +``` + +Then update `/etc/mvlog/auth.php`. + +Logout: + +```text +/mvlog/logout.php +``` + +Logout destroys the PHP session and redirects to `login.php`. + +## Input directory naming + +New admin-created input directories must use: + +```text +YYYYMMDD_slug-title +``` + +Example: + +```text +20260525_mohnesee +``` + +Do **not** include time in the directory name. + +## `data.txt` format + +Each input directory contains a `data.txt` file. + +All entries use mandatory `key: value` syntax: + +```text +Title: My Movie Title +Location: Sønderborg +Date: 2026-05-25 +Description: Short description of the video. +filename.jpg: Optional caption for this file +filename.mp4: Optional caption for this clip +``` + +Supported general keys: + +```text +Title +Location +Date +Description +``` + +Per-file captions are stored as: + +```text +filename.ext: caption text +``` + +Audio files do not get captions in the admin UI. + +## Worker integration + +Rendering is handled by the separate `movmaker` project, especially: + +```text +/home/hbrain/source/movmaker/mvlog_worker.py +``` + +The worker: + +1. Scans remote `in-dir/` directories. +2. Computes an input fingerprint. +3. Compares with `.movmaker-state.json`. +4. Renders changed jobs with `movmaker.py`. +5. Publishes MP4 files to `out-dir/`. +6. Updates `.movmaker-state.json`. +7. Clears `cache/videos.json` after publishing. + +State file per input dir: + +```text +in-dir//.movmaker-state.json +``` + +The state file maps an input dir to its generated output video. Orphan detection must rely on this state file only. + +Systemd units on the worker machine: + +```text +/etc/systemd/system/mvlog-worker.service +/etc/systemd/system/mvlog-worker.timer +``` + +Useful commands: + +```bash +systemctl status mvlog-worker.service --no-pager +systemctl status mvlog-worker.timer --no-pager +journalctl -u mvlog-worker.service -n 100 --no-pager +``` + +## Orphan video handling + +The admin **Videos** tab shows generated videos in `out-dir/` that are not referenced by any input directory state file. + +Important rule: + +> Orphan detection must use `.movmaker-state.json` only. Do not infer ownership from metadata or title fallback. + +## Configuration + +`config.php` returns the main app config: + +```php +return [ + "site_name" => "Movmaker WebUI", + "videos_dir" => __DIR__ . "/out-dir", + "thumbs_dir" => __DIR__ . "/thumbs", + "uploads_dir" => __DIR__ . "/in-dir", + "public_videos" => "out-dir", + "public_thumbs" => "thumbs", + "items_per_page" => 12, +]; +``` + +## nginx/PHP requirements + +The app runs under nginx + PHP-FPM. + +Admin uploads require larger request limits. Production currently uses: + +```nginx +client_max_body_size 512M; +``` + +PHP-FPM upload override: + +```ini +upload_max_filesize = 512M +post_max_size = 512M +max_file_uploads = 100 +max_input_time = 600 +max_execution_time = 600 +``` + +Example file: + +```text +/etc/php/8.2/fpm/conf.d/99-mvlog-upload.ini +``` + +After changing nginx/PHP config: + +```bash +sudo nginx -t +sudo systemctl reload nginx +sudo systemctl restart php8.2-fpm +``` + +## Timezone + +The public page and RSS feed explicitly use: + +```php +date_default_timezone_set('Europe/Copenhagen'); +``` + +This ensures displayed creation/publish times are Danish local time, not UTC. + +## Permissions + +Expected web ownership is generally: + +```text +www-data:www-data +``` + +The git repo may be owned by `hbrain:www-data`. + +State files should be group-writable so the worker can update them: + +```bash +chmod 664 in-dir/*/.movmaker-state.json +``` + +The worker writes state files using a temp file and `chmod 664` to avoid permission problems. + +## Git notes + +Repository: + +```text +https://git.novosel.dk/marijo/movmaker-webui.git +``` + +If git complains about ownership: + +```bash +git config --global --add safe.directory /var/www/html/mvlog +sudo chown -R hbrain:www-data /var/www/html/mvlog/.git +``` + +Do not commit generated media from `in-dir/` or `out-dir/`. + +`AGENTS.md` is local assistant/project context and should remain ignored by git.