138 lines
4.9 KiB
Markdown
138 lines
4.9 KiB
Markdown
# movmaker-webui (MVL)
|
|
|
|
PHP web UI for publishing and managing MVLog videos on **bubulescu.org**.
|
|
|
|
## Production location
|
|
|
|
- Web root: `/var/www/html`
|
|
- Public URLs:
|
|
- `https://bubulescu.org/`
|
|
- `https://bubulescu.org/admin.php`
|
|
- `https://bubulescu.org/login.php`
|
|
- `https://bubulescu.org/feed.php`
|
|
- `https://bubulescu.org/contact.php`
|
|
|
|
## Main structure
|
|
|
|
- `index.php` — public landing page (rendered videos and permalink pages)
|
|
- `admin.php` — authenticated admin UI
|
|
- `feed.php` — RSS feed
|
|
- `contact.php` — contact form
|
|
- `auth.php` — session auth helpers
|
|
- `config.php` — app config
|
|
- `style.css` — shared styles
|
|
- `_header.php`, `_footer.php`, `_footer_admin.php` — shared layout includes
|
|
|
|
Important dirs:
|
|
|
|
- `in-dir/` — input/article dirs
|
|
- `out-dir/` — rendered videos and article OG images (`<article_id>_og.jpg`)
|
|
- `thumbs/` — legacy thumbnail cache / cleanup dir
|
|
- `cache/` — metadata/search/push caches
|
|
|
|
## Public page (`index.php`)
|
|
|
|
- Randomized header title text (`<h1>`), fixed HTML title `MVL`
|
|
- Header actions: notifications, RSS, contact
|
|
- Search supports:
|
|
- general keyword (title/teaser/quote_da/description)
|
|
- `date=...`
|
|
- `location=...` / `place=...`
|
|
- Case-insensitive + accent-insensitive matching
|
|
- Shows title/date/location/teaser/description/quote_da
|
|
- Article permalinks use `/post/<title-slug>`; legacy `?id=<article_id>` URLs redirect to the canonical post URL.
|
|
- Permalink pages hide the bottom page numbers
|
|
- Optional map image per video (hidden when source article has `.mvlog-hide-map`)
|
|
- Video posters are resolved from the source image recorded in the thumbnail sidecar JSON; if the source image is missing, the `<video>` gets no poster
|
|
- Permalink OG/Twitter images use `out-dir/<article_id>_og.jpg` when present; otherwise they fall back to `https://bubulescu.org/assets/img/bubulescuorg.jpg`
|
|
|
|
## Admin (`admin.php`)
|
|
|
|
Requires login via PHP session.
|
|
|
|
Tabs:
|
|
- **New** — create input dirs + upload media
|
|
- **Edit** — edit metadata/media/order/toggles
|
|
- **Videos** — manage orphan output videos
|
|
|
|
Implemented behavior:
|
|
|
|
- Article identity uses `.mvlog-id` / `article_id` as the stable canonical ID; legacy dir-name fallback only applies to older entries that are missing the ID
|
|
- Draft metadata is read/written from `in-dir/<job>/data.txt`
|
|
- Supports metadata fields: `title`, `teaser`, `quote_da`, `date`, `place`, `description`
|
|
- Manual media reordering via `order.json` (AJAX action `reorder_file`)
|
|
- Per-article toggles:
|
|
- Preview (`set_preview`)
|
|
- Render (`set_enabled`)
|
|
- Show (`set_visible`)
|
|
- Hide map (`set_map_hidden` -> `.mvlog-hide-map`)
|
|
- `Save changes` always regenerates the map PNG(s) for the article on every press, via `bin/gpsmap.py`
|
|
- Map regeneration logs are written to `/var/log/mvlog_map.log`
|
|
- Custom video poster selection uses the source image recorded in `<output>_thumb.json`; if the source image is missing, no poster file is used
|
|
- `set_video_thumb` also writes an article-specific OG image to `out-dir/<article_id>_og.jpg`
|
|
- Thumbnail provenance is stored in the thumb JSON sidecar (`article_id`, `input_dir`, `source_file`, `source_path`, `created_at`)
|
|
- Describe button uses `lib/generate_data_sync.php`
|
|
- Job status polling via `job_status.php` every 32s
|
|
|
|
## Ordering rules
|
|
|
|
For visual media ordering in admin/render flow:
|
|
1. `order.json` (authoritative when present)
|
|
2. embedded metadata datetime
|
|
3. filename datetime
|
|
4. filesystem datetime
|
|
|
|
`order.json` is web/admin-owned (worker consumes it).
|
|
|
|
## Contact form (`contact.php`)
|
|
|
|
- Fields: name, email, message + honeypot anti-spam field
|
|
- Uses PHP `mail()`
|
|
- On success: redirects to `https://bubulescu.org/`
|
|
- Recipient is configured in `contact.php` (`$to_email`)
|
|
|
|
## Push notifications
|
|
|
|
Files:
|
|
- `push_config.php` — exposes only public VAPID key
|
|
- `push_subscribe.php` — stores subscriptions in `cache/push_subscriptions.json`
|
|
- `lib/send_push.php` + `send_push.js` — server-side send logic
|
|
- `api/enable_show.php` — triggers push on Show enable
|
|
- `sw.js` — service worker fallback notification text
|
|
|
|
Current text behavior:
|
|
- Show notifications open the canonical article permalink (`/post/<title-slug>`)
|
|
- payload body: `New aticle @ MVL!`
|
|
- SW fallback title/body: `MVL` / `New article @ MVL!`
|
|
|
|
Push config is loaded from first available:
|
|
- `/etc/mvlog/push.php`
|
|
- `/etc/mvlog/push.json`
|
|
- `/var/www/html/push.json`
|
|
- `~/.config/mvlog/push.json`
|
|
|
|
## Auth
|
|
|
|
- Session cookie name: `MVLOGSESSID`
|
|
- Cookie path: `/`
|
|
- Auth config: `/etc/mvlog/auth.php`
|
|
|
|
## Runtime config (`config.php`)
|
|
|
|
```php
|
|
return [
|
|
"site_name" => "Admin MVLog",
|
|
"videos_dir" => __DIR__ . "/out-dir",
|
|
"thumbs_dir" => __DIR__ . "/thumbs",
|
|
"uploads_dir" => __DIR__ . "/in-dir",
|
|
"public_videos" => "out-dir",
|
|
"public_thumbs" => "thumbs",
|
|
"items_per_page" => 8,
|
|
];
|
|
```
|
|
|
|
## Notes
|
|
|
|
- `contact.php` is currently in `.gitignore`.
|
|
- Keep secrets out of git (`push.json`, private keys, auth secrets).
|
|
- Worker/rendering is handled by separate movmaker worker project.
|