No description
Find a file
2026-06-20 20:16:16 +02:00
api Switch admin/API flows to article IDs with legacy job fallback 2026-05-31 18:04:21 +02:00
assets New icons 2026-06-07 11:34:32 +02:00
bin Personality update 2026-06-20 11:47:11 +02:00
js Refine map lightbox UX and map click behavior across pages 2026-05-31 15:19:39 +02:00
lib Permalinks changed from id to title slug... 2026-06-20 17:28:27 +02:00
.gitignore Modified logic for sending email when publishing. 2026-06-11 20:30:19 +02:00
404.php PWA basic implemented (not for admin.php) 2026-06-06 17:12:52 +02:00
_footer.php Map lighbox on permalink fixed 2026-06-20 20:16:16 +02:00
_footer_admin.php Added personality - Chamberlain 2026-06-19 18:15:40 +02:00
_header.php Permalinks changed from id to title slug... 2026-06-20 17:28:27 +02:00
_pwa_head.php PWA basic implemented (not for admin.php) 2026-06-06 17:12:52 +02:00
admin.php Render chkbox turns off once rendering job starts 2026-06-20 18:40:18 +02:00
altcha_asset.php CAPTCHA for journal subscription 2026-06-07 12:45:53 +02:00
altcha_challenge.php CAPTCHA for journal subscription 2026-06-07 12:45:53 +02:00
auth.php Renamed new.php to admin.php, fixed redirects 2026-06-04 14:33:29 +02:00
config.php Fix: Restore Describe button functionality and correct JSON path 2026-05-30 01:24:00 +02:00
contact.php.example MVLog removed 2026-06-20 16:13:40 +02:00
favicon.ico New icons 2026-06-07 11:34:32 +02:00
feed.php Permalinks changed from id to title slug... 2026-06-20 17:28:27 +02:00
header_titles.php Titles update 2026-06-04 12:56:02 +02:00
index.php Added og:url 2026-06-20 17:53:44 +02:00
job_status.php Render chkbox turns off once rendering job starts 2026-06-20 18:40:18 +02:00
login.php Renamed new.php to admin.php, fixed redirects 2026-06-04 14:33:29 +02:00
logout.php Redirect logout to login page 2026-05-25 22:39:55 +02:00
manifest.json MVLog removed 2026-06-20 16:13:40 +02:00
new.php Renamed new.php to admin.php, fixed redirects 2026-06-04 14:33:29 +02:00
offline.html PWA basic implemented (not for admin.php) 2026-06-06 17:12:52 +02:00
package-lock.json Add remaining relevant files (auto) 2026-05-29 13:29:12 +02:00
package.json Add remaining relevant files (auto) 2026-05-29 13:29:12 +02:00
push.json.example Ignore push.json and add push.json.example + README note 2026-05-29 13:36:58 +02:00
push_config.php Unify push config resolution for subscribe and send paths 2026-05-31 14:28:05 +02:00
push_subscribe.php Add web push notifications 2026-05-26 15:48:30 +02:00
README.md Permalinks changed from id to title slug... 2026-06-20 17:28:27 +02:00
robots.txt Updated robots.txt and sitemap added 2026-06-20 17:05:04 +02:00
send_push.js Add remaining relevant files (auto) 2026-05-29 13:29:12 +02:00
sitemap.php Permalinks changed from id to title slug... 2026-06-20 17:28:27 +02:00
sitemap.xml Updated robots.txt and sitemap added 2026-06-20 17:05:04 +02:00
style.css Footer styling 2026-06-07 08:03:21 +02:00
sw.js Updated PWA icons 2026-06-06 17:49:59 +02:00

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)

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.