Releases: corveck79/mycelium
Releases · corveck79/mycelium
Release list
v0.6.2
Install
docker pull ghcr.io/corveck79/mycelium:0.6.2Added
- spore-nfs and spore-smb: read-only NFSv3 and SMB2/3 servers exposing the virtual library as real files, backed by the existing
/spore-stream/<token>endpoint (no new materialization logic). Server-side tricks to block Direct Play on Shield/Android TV (stub channel count, forced PGS subtitle burn-in) stopped working reliably - Android's local-network fast path bypasses the profile negotiation Linux/desktop clients respect, turning the fake stub into a black screen instead of a transcode. With real size/bytes served, Direct Play becomes correct instead of catastrophic, on every client. Both protocols share a 3-window read-ahead LRU, background prefetch, resolved-CDN-URL caching, self-healing on a dead cached URL, and a token-bucket rate limiter with retry/backoff against TorBox/CDN 429s. spore-nfs later merged into the main image (one container instead of two).
Fixed
- MKV/non-MP4 playback via
/stream(Jellyfin's path, and any other client not building a moov-first cache) could be redirected straight to a CDN URL that had gone dead earlier than its 23h in-memory cache TTL, with no validation - Jellyfin/ffmpeg would follow the dead link into a TorBox error page and fail withFFmpegException: FFmpeg exited with code 8/ffprobe failed. Now HEAD-checked before redirecting, with an automatic re-resolve on a dead link. play_count/last_playedwere written to SQLite on every single byte-range request during playback, not just on play start - under concurrent playback these writes serialized against each other for no benefit. Debounced to once per token per 60s; the CDN liveness check above is similarly cached for 120s so repeated seeks in one session don't each pay a fresh CDN round trip.- Stale
JELLYFIN_API_KEYon deploy could leaverefresh_library(),merge_duplicate_versions(),refresh_missing_images()and continue-watching sync silently failing with 401 - not a code fix, but worth a mention since it was masking as playback flakiness.
v0.6.1
Install
docker pull ghcr.io/corveck79/mycelium:0.6.1A security- and correctness-focused release from a full multi-pass code review. No new features.
Security
- OIDC and trusted-proxy logins no longer implicitly become admin -
auth.pynow resolves or creates a real per-user role (userby default; only the very first user ever provisioned this way becomes admin, and only during initial, incomplete setup) AUTH_SESSION_SECRETis no longer used to sign sessions when left at the well-known default value - a random secret is generated and persisted instead, same pattern as the existingWEBHOOK_SECRET_AUTO- Added
is_admin()checks to roughly 30 previously-unprotected/ui/*and/ui/api/*routes: settings save/reset, backup restore, DB vacuum/prune, cleanup/repair/migrate triggers, Zilean sync/import, wanted-recheck, NFO/strm regeneration, and several legacy/api/*aliases that had slipped through /adminitself now redirects non-admin users to login instead of only checking that setup is complete- Web Player
/stream/<token>/*playback routes now require an authenticated session with the Web Player feature enabled - previously reachable by anyone who obtained a token TRUSTED_PROXY_NETWORKSdefault narrowed from broad private-IP ranges to loopback only- Webhook secret and internal token comparisons now use constant-time comparison throughout
- The Spore TCP server (port 8089, unauthenticated protocol) now binds to loopback by default instead of all interfaces
Fixed
- A transient scraper/cache-check error on a single episode could mark an entire multi-season request "failed", discarding seasons that had already been added successfully
- The retry queue could silently drop a failed retry and abort the rest of that cycle's batch instead of continuing
- Cleanup/repair and canonical-name migration could leave orphaned database rows behind after deleting or merging
.strmfiles, permanently blocking recreation of that title - Folder rename/merge database updates could corrupt a sibling folder's paths when one folder name was a literal prefix of another (e.g. "Alien (1979)" vs. "Alien (1979) Directors Cut")
- Duplicate-folder merges could silently delete a file that was never actually copied over first
- Plex's fast-start MP4 cache could corrupt sample offsets for CDN files with a second data block after the
moovatom (dual-mdat layout) - HTTP suffix byte-ranges (
bytes=-N) were parsed as the first N bytes instead of the last N - CSRF protection was effectively disabled on roughly 27 internal API routes because the exemption predated the frontend actually sending the CSRF token
- Several background jobs (series monitor, retry queue) could abort an entire batch when a single item raised an unexpected error instead of continuing with the rest
- Assorted smaller fixes: SQLite
LIKEwildcard characters in folder names could cause wrong-path matches during renames; a webplayer seek race could start two concurrent FFmpeg processes for the same session; two/api/*routes referenced an unimported module and would have raised on use
v0.6.0
Install
docker pull ghcr.io/corveck79/mycelium:0.6.0Credits
Several of the bugfixes in this release were discovered and/or confirmed through the work of Ventrex in his fork ("VenFlix") and the accompanying GitHub Discussions. Thanks for digging into these issues and sharing the fixes/ideas with the community.
Thanks also to Damosso for the Seerr webhook secret tip in #41, which shaped a docs fix earlier in this cycle.
Added
- Trakt: auto-request new watchlist items for download (not just watchlist sync), capped daily, built into the existing Trakt plugin
- MDBList integration: connect your own API key, pick lists to sync, capped auto-request
- Auto-approve: per-genre rules with year ranges, follow favorite actors (auto-requests their filmography, excludes talk shows/soaps), shared daily budget
- Discover genre tabs: admin-configurable browse rows per genre + year range
- Language filter: per-user include/exclude of content by original language in Discover
- Clickable cast: cast in the detail modal opens an actor page with bio + filmography + Follow button
- TorBox library scan: reads existing TorBox cache and creates
.strmfiles for anything missing (e.g. after a DB reset) - Notification settings in the React Settings page (Discord/Telegram)
- Real topbar search bar instead of just a link to the search page
- React Admin dashboard finally routed:
/adminnow shows a tab between the new dashboard (user management, Radarr/Sonarr import, Auto-approve, genre tabs, maintenance) and the existing Jinja page - this page already existed but was never wired to a route
Fixed
- Settings-UI overrides were silently ignored in several places (Zilean, TMDB, RealDebrid, TorBox, OpenSubtitles, catbox) due to frozen
config.pyimports instead ofsettings.get() - Mislabeled cams/trailers (e.g. "2160p" that's actually a cam) are now rejected based on physically plausible file size vs. TMDB runtime
- Unreleased titles could pull in fake/cam releases - now blocked via TMDB release date
- Multi-season series only got season 1 into the library
- Duplicate episode tokens/strms when title sanitizing landed differently
db.insert_request()could update the wrong row on retry (SQLitelastrowidquirk), leaving requests permanently stuck on "rate_limited"- TorBox timeouts were treated as success, writing a
.strmbefore the torrent was actually ready - Series could end up split across multiple folders due to varying release names
- Jellyfin library refresh had no debounce, could fire excessively during bulk operations
- Raw IMDb IDs (
tt1234567) instead of titles shown in notifications/UI for requests without a title in the payload - Toggle switches in the admin user panel rendered incorrectly (knob always on the right regardless of state)
- Clickable cast was invisible due to a z-index conflict between the detail and actor modals
- Removed a duplicate, colliding Trakt integration (a new build on top of an already-existing plugin) - including a database schema conflict that broke the existing plugin
- Web Player:
/ui/api/web-player/status/<job_id>silently droppedtoken/stream_typefrom its JSON response, so the frontend always fell into the HLS.js branch (pointed at a raw MP4 redirect instead of a playlist) instead of direct-playing eligible files, causing an infinite retry/timeout loop
v0.5.2
Install
docker pull ghcr.io/corveck79/mycelium:0.5.2Added
- Web Player VA-API: hardware-accelerated HEVC transcoding via VA-API (
renderD128); reduces CPU usage significantly on supported hardware - Web Player HEVC-always: HEVC is always transcoded to HLS regardless of codec; direct serve only for H264 to avoid browser incompatibility
- Docker Compose:
videodriverGID 937 added for VA-APIrenderD128access - Spore wrapper EAE detection: also detects EAE need from output encoder args (e.g. Shield TV requesting
eac3_eaeoutput via eARC); skips injecting native decoder hint when output iscopyto prevent EAE init failures on HTTP input
Fixed
Web Player
- Black screen / corrupt green output on 10-bit HEVC with VA-API (Apollo Lake J3455)
scale_vaapifailure on 10-bit HEVC sources- Stale segments causing black screen after seek or restart
- Missing
/direct,/convert-hls,/hls-statusroutes - HLS buffer increased to prevent stalls on slow CDN
- Temp directory leak when HLS conversion crashes before session registration
ffmpeg.logfile handle not closed onPopenfailureshutil.rmtreecalled before ffmpeg process exits (race condition)
Security
- Session fixation:
session.clear()now called before writing new session keys on login /torbox-webhookand/ui/api/repair-strmsnow require authentication/setup/savenow validates against a known-key allowlist (previously accepted arbitrary keys)/healthno longer leaks internal exception details in the response body
Data integrity
cleanup.py: new strm written viaprocess_torrentbefore the old one is deletedupgrader.py: season-pack strms written before per-episode strms are removedmp4_faststart.py:.fshcache written atomically via temp-file + rename; ftyp box fetched at actual size instead of hardcoded 64 bytes
Logic
torbox.py:metaDL_donestate never matched becausedownload_stateis lowercased before comparison — fixed tometadl_donetorbox.py: createtorrent quota now recorded after HTTP success, not before (prevented quota inflation on network errors)torrentio.py: season-pack regexs0?N→s0*N(?!\d)to correctly match zero-padded season codescatbox.py:release_idle()no longer aborts on first network error — each torrent deletion is now wrapped in try/exceptmonitor.py: aired episodes without a strm are now markedwantedin the DB (were silently left without status)retry_queue.py: startup crash on undefined_CREATETORRENT_LIMITconstant (should be_CREATETORRENT_LIMIT_HOUR)db.py:_migrate()ALTER TABLE loop now catches per-column errors instead of aborting remaining migrations
Fresh install
- Fixed crash
sqlite3.OperationalError: no such table: settingson first boot when the DB is empty (#34)
v0.5.1-dev
Install
docker pull ghcr.io/corveck79/mycelium:0.5.1-devAdded
- Library poster grid: movies tab now shows a paginated poster grid (24/page) with the same look as Discover and Watchlist
- Library search and filters: search box and All / Available / Wanted filter tabs in the movies view
- Open in Jellyfin preference: per-user toggle in Settings > Preferences; clicking a library poster opens the item directly in Jellyfin web instead of the detail modal
- Jellyfin batch lookup: Jellyfin item IDs are pre-fetched in one call so poster clicks are synchronous (no popup-blocker issues)
- Lazy poster loading: posters missing from the local cache are fetched on first render without blocking the page
Fixed
- GitHub Actions arm64 build crash: removed dead
spore-builderDockerfile stage that compiled a C LD_PRELOAD library usingstat64/__xstat64which do not exist on aarch64 - Jellyfin click mode not working after toggle: Settings now uses an optimistic session-cache update so Library reacts instantly without a page reload
- Detail modal not opening for older items that lack a stored
tmdb_id(now resolved via/ui/api/tmdb/find)
v0.4.2 - Security hardening
Install
docker pull ghcr.io/corveck79/mycelium:0.4.2Added
WEBHOOK_SECRETauto-generation with copy button in admin Settings- Metrics endpoint secured with optional Bearer token
- Rate limiting on authentication endpoints
Fixed
- Setup wizard now closes after first run (re-open via Settings)
- WebDAV auth hardening and security headers
v0.4.1 - Docker Hub
Install
docker pull ghcr.io/corveck79/mycelium:0.4.1Added
- Docker Hub CI/CD pipeline on release tags (multi-arch images)
- Splash screen as login background
v0.4.0 — Lite Mode
Install
docker pull ghcr.io/corveck79/mycelium:0.4.0Added
LITE_MODEfor webhook-only deployments without heavy background schedulers- Settings tab in admin dashboard (hot-reload quality filters and runtime config)
Changed
- Setup wizard UI improved
v0.3.0-beta
Install
docker pull ghcr.io/corveck79/mycelium:0.3.0-betaAdded
- Web Player plugin: in-browser HLS player with subtitle picker
- Trakt plugin: watchlist sync and ratings integration
- Plugin slot system: plugins can inject components into the frontend (episode player, settings cards)
- Web Player: HDR detection and SDR-only release selection for browser compatibility
- Web Player: multi-audio HLS master playlist with separate audio streams
v0.2.0-beta
Install
docker pull ghcr.io/corveck79/mycelium:0.2.0-betaAdded
- Multi-user authentication with roles (admin/user) and pending approval flow
- OIDC/SSO support for single sign-on
- Users tab in admin with pending approval management
- Redesigned React SPA: Library status indicators, region picker
Fixed
- Open redirect vulnerability on login
/setupaccessible without authentication