v1.16.0 — Plex mount + unified engine (community testing build)
Pre-releaseCommunity testing build (pre-release). Plex mount support + the unified library engine, with a robust self-recovering mount supervisor and collision-proof module names. Please test the Plex mount path and report issues before this is proposed upstream.
What's new in v1.16.0
VOD2MLIB delivers your VOD catalogue two ways from one engine: .strm files (Jellyfin/Emby/Kodi/ChannelsDVR) and a live HTTP mount for Plex (which can't play .strm). Both share one naming path, one playback-URL builder, and one config schema, so a title lands at the same name whichever output you use. The Plex mount integrates VODFS (MIT) onto that shared core.
[MOUNT]actions: Enable / Disable / Status / rclone config / Hydrate sizes now.[PLEX]settings: mount HTTP port (default8889), token auth, size-hydration.- The mount runs as a small server inside Dispatcharr and installs
uvicorn/fastapi/jinja2on first[MOUNT] Enable(the.strmoutput still needs no extra packages).
⚠ Breaking for existing .strm libraries — folder names changed. .strm now uses the unified naming: folders always carry {tmdb-…}/{imdb-…} when known, with more aggressive provider-noise cleanup. To migrate: run [⚠ DANGER] Clean up, then re-generate. New installs are unaffected.
Mount-server hardening
- Fixed a spurious
403that made the mount unusable. The network/auth gates queried the DB without stale-connection hygiene → fail-closed →403on every request (rclone saw I/O errors). The STREAMS policy actually defaults to allow-all; the denials were spurious. Gates now refresh the connection before the ORM call; fail-closed intent is unchanged. - gzip + streamed directory tree. Large
/Movies/Alllistings go out ~10× smaller, compressed incrementally so memory stays bounded; the302playback path is untouched. Rows are batched per flush, and rendered listings are cached as bytes. - Collision-proof module names. Dispatcharr loads every plugin into one shared interpreter, so a generically-named helper module would clash in
sys.moduleswith another plugin's same-named file (and silently load the wrong one). The plugin's modules are now plugin-unique:vod2mlib_control.pyand thevod2mlib_core/package. - Removed dead tree code;
access_logno longer growsserver.logunbounded.
Mount supervisor (new)
The mount is a child process, so its lifecycle is now actively managed:
- Identity-safe tracking — tracked by pid +
/procstart-time (recycled-PID proof, zombie-aware); stop verifies identity before signalling and escalates SIGTERM → SIGKILL. - Auto-recovery — a celery-beat healthcheck reconciles the mount on an interval (and on any plugin interaction). After a crash or a container restart it is respawned automatically — verified live: a
docker restartbrings the mount back unattended, typically within ~a minute. - Crash-loop guard — if the child can't start, it stops retrying after a few attempts and
[MOUNT] Statusreports the failure with the last error;[MOUNT] Enableis the explicit retry.
Precondition: auto-recovery (and the mount itself) needs the plugin data dir (/data/plugins/vod2mlib) to be writable by the user Dispatcharr runs as. If it isn't, [MOUNT] Status stays DOWN and the supervisor logs a concise permission warning each tick — see the README troubleshooting note.
Verified
Live in the integration harness: rclone lists folders and streams real MP4 bytes through the 302→proxy path; a SIGKILL'd child and a full docker restart are both recovered automatically by the supervisor (the respawned child is reparented to the celery worker); Plex scans both Movie and TV sections, tmdb-matched with playable parts and no scanner errors. 188 unit tests pass.
Install (manual)
Download plugin-vod2mlib-v1.16.0.zip below → Dispatcharr → Plugins → Import → upload the zip → enable. Requires Dispatcharr v0.24.0+; for durable playback URLs over days, run Dispatcharr on :dev (see README troubleshooting re: UUID orphaning).
SHA256: dffe11ac8c87ac6446520882143679a6c85610235937084effb7dc17b10ed60d