No description
| api | ||
| assets | ||
| bin | ||
| js | ||
| lib | ||
| .gitignore | ||
| 404.php | ||
| _footer.php | ||
| _footer_admin.php | ||
| _header.php | ||
| _pwa_head.php | ||
| admin.php | ||
| altcha_asset.php | ||
| altcha_challenge.php | ||
| auth.php | ||
| config.php | ||
| contact.php.example | ||
| favicon.ico | ||
| feed.php | ||
| header_titles.php | ||
| index.php | ||
| job_status.php | ||
| login.php | ||
| logout.php | ||
| manifest.json | ||
| new.php | ||
| offline.html | ||
| package-lock.json | ||
| package.json | ||
| push.json.example | ||
| push_config.php | ||
| push_subscribe.php | ||
| README.md | ||
| robots.txt | ||
| send_push.js | ||
| sitemap.php | ||
| sitemap.xml | ||
| style.css | ||
| sw.js | ||
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.phphttps://bubulescu.org/login.phphttps://bubulescu.org/feed.phphttps://bubulescu.org/contact.php
Main structure
index.php— public landing page (rendered videos and permalink pages)admin.php— authenticated admin UIfeed.php— RSS feedcontact.php— contact formauth.php— session auth helpersconfig.php— app configstyle.css— shared styles_header.php,_footer.php,_footer_admin.php— shared layout includes
Important dirs:
in-dir/— input/article dirsout-dir/— rendered videos and article OG images (<article_id>_og.jpg)thumbs/— legacy thumbnail cache / cleanup dircache/— metadata/search/push caches
Public page (index.php)
- Randomized header title text (
<h1>), fixed HTML titleMVL - 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
?id=<article_id>; filename fallback is no longer used - 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.jpgwhen present; otherwise they fall back tohttps://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_idas 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 actionreorder_file) - Per-article toggles:
- Preview (
set_preview) - Render (
set_enabled) - Show (
set_visible) - Hide map (
set_map_hidden->.mvlog-hide-map)
- Preview (
Save changesalways regenerates the map PNG(s) for the article on every press, viabin/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_thumbalso writes an article-specific OG image toout-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.phpevery 32s
Ordering rules
For visual media ordering in admin/render flow:
order.json(authoritative when present)- embedded metadata datetime
- filename datetime
- 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 keypush_subscribe.php— stores subscriptions incache/push_subscriptions.jsonlib/send_push.php+send_push.js— server-side send logicapi/enable_show.php— triggers push on Show enablesw.js— service worker fallback notification text
Current text behavior:
- Show notifications open the article permalink (
./?id=<article_id>) - 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)
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.phpis currently in.gitignore.- Keep secrets out of git (
push.json, private keys, auth secrets). - Worker/rendering is handled by separate movmaker worker project.