Skip to content

Releases: OneHotTake/VOD2MLIB

v1.16.1 — mount supervisor + hardening (community testing build)

Choose a tag to compare

@OneHotTake OneHotTake released this 29 Jun 20:48

Community testing build (pre-release). A robustness pass over the v1.16.0 Plex mount: a self-recovering supervisor, mount-server hardening, and collision-proof module names. Please test the Plex mount path and report issues before this is proposed upstream.

This supersedes the churned v1.16.0 testing build — grab this one.

Mount-server hardening

  • Fixed a spurious 403 that made the mount unusable. The network/auth gates queried the DB without stale-connection hygiene → fail-closed → 403 on 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/All listings go out ~10× smaller, compressed incrementally so memory stays bounded; the 302 playback path is untouched. Rows are batched per flush, rendered listings cached as bytes. access_log no longer grows server.log unbounded.
  • Collision-proof module names. Dispatcharr loads every plugin into one shared interpreter, so a generically-named module would clash in sys.modules with another plugin's same-named file and silently load the wrong one. The plugin's modules are now plugin-unique: vod2mlib_control.py and the vod2mlib_core/ package.

Mount supervisor

The mount is a child process, so its lifecycle is now actively managed:

  • Identity-safe tracking — tracked by pid + /proc start-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 restart brings 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] Status reports the failure with the last error; [MOUNT] Enable is 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.

About v1.16.0

If you're new here: v1.16.0 added Plex delivery via a live HTTP mount (rclone), built on the same unified core (vod2mlib_core) as the .strm output. ⚠ Breaking for existing .strm libraries — folder names changed to always carry {tmdb-…}/{imdb-…}; run [⚠ DANGER] Clean up then re-generate to migrate. See the v1.16.0 section of the CHANGELOG.

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.1.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: ed4151bcc0a97cb798ccf6f2b1ad3fa59311dd9d679ed995f8b005235261db70

v1.16.0 — Plex mount + unified engine (community testing build)

Choose a tag to compare

@OneHotTake OneHotTake released this 29 Jun 12:16

Community 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 (default 8889), token auth, size-hydration.
  • The mount runs as a small server inside Dispatcharr and installs uvicorn/fastapi/jinja2 on first [MOUNT] Enable (the .strm output 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 403 that made the mount unusable. The network/auth gates queried the DB without stale-connection hygiene → fail-closed → 403 on 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/All listings go out ~10× smaller, compressed incrementally so memory stays bounded; the 302 playback 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.modules with another plugin's same-named file (and silently load the wrong one). The plugin's modules are now plugin-unique: vod2mlib_control.py and the vod2mlib_core/ package.
  • Removed dead tree code; access_log no longer grows server.log unbounded.

Mount supervisor (new)

The mount is a child process, so its lifecycle is now actively managed:

  • Identity-safe tracking — tracked by pid + /proc start-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 restart brings 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] Status reports the failure with the last error; [MOUNT] Enable is 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