github getmydia/mydia v0.10.0-beta3
Mydia v0.10.0-beta3

pre-release4 hours ago

Mydia v0.10.0-beta3 — The Usenet & Parser Release

It's been two months since v0.9.0 and a lot has happened under the hood. This beta wraps up two long-running rollouts — the Usenet feature-parity push (10 issues, 9 merged units) and the Release Parser v3 rewrite (8 units, 245-case parity) — alongside a serious round of architectural cleanup that's been quietly making the codebase easier to live in.

Tagged as beta because the surface area is large and we want a wider testing window before cutting v0.10.0 final.

🎬 The Big Stories

Usenet, finally feature-complete

When the Usenet pipeline shipped a few months back, it worked — but it wasn't a peer of the torrent path. This release closes the gap. Mydia now:

  • Parses usenetdate and nzb_grabs from Newznab/Prowlarr/NZBHydra2 responses, so the ranker can actually reason about NZB freshness and popularity instead of pretending NZB results were torrents with zero seeders.
  • Filters releases by minimum post age (per-indexer setting), so you can avoid grabbing brand-new posts that haven't propagated yet.
  • Ranks NZB results properly with a dedicated scoring branch instead of torrent heuristics.
  • Routes downloads by content type — separate SABnzbd/NZBGet categories for movies vs TV vs anime, instead of the old one-category-per-client setup.
  • Maps quality to a 5-tier priority profile per client, so you can push 4K to high priority and SD to low without touching the client.
  • Detects stalled downloads at 99% and surfaces them with a badge in the Downloads view rather than polling forever.
  • Blacklists failed releases so the next search doesn't pick the same broken NZB again.
  • Accepts SABnzbd + NZBGet completion webhooks as a fast-path signal on top of the existing poll loop. MediaImport is now idempotent so duplicate triggers from webhook + poll are safe.

Internally, SABnzbd (665 LOC) and NZBGet (517 LOC) now share a unified DownloadStatus struct and adapter helpers, with table-driven state mapping tests against frozen JSON fixtures from real API responses.

Closes #119, #120, #121, #122, #123, #124, #125, #126, #127, #128, #129.

Release Parser v3

The old FileParser.V2 was a regex-soup with edge cases that bit us in real-world torrent titles. v3 is a clean tokenizer → classifier → resolver pipeline with a regression corpus harvested from Sonarr and Radarr. All 14 call sites have been migrated, V2 has been deleted, and the parser is now 245-case parity tested against the corpus.

The tokenizer is byte-safe (it was Unicode bugs in the old parser that caused the file-parser-unicode-byte-offset fix), and the quality extractor finally handles weird release groups, parenthesized sub-expressions, and word-form Season 1 Episode 5 titles that V2 missed.

Auto-rename on import (TRaSH Guides format)

You can now opt into automatic file renaming on import using the TRaSH Guides naming format. Per-library toggle, exposed in library settings and through GraphQL.

Jellyfin NFO export

NFO writer module that emits Jellyfin-compatible .nfo files on import and refresh. Per-library opt-in plus a bulk export mix task for back-filling existing media. Handy if you're running Mydia alongside Jellyfin and want metadata to follow your files.

Issues tab revamp

The Downloads → Issues tab is now a proper three-section layout: unmatched, partial pack, failed. Manual match, manual resolution, and dismiss are all first-class actions instead of buried buttons. Season packs with unresolved files now do partial imports — the matched episodes land, the rest stay flagged.

Player CTA in the sidebar

The sidebar now surfaces the bundled web player with a prominent label and a CTA banner — so first-time users actually discover that /player is a thing.

🛠 Reliability & correctness

  • qBittorrent: multipart uploads, post-add verification, 5.x compatibility, and a less-aggressive "missing" detector that doesn't flap on slow refreshes.
  • Season pack redownload loop: fixed — packs no longer requeue every hour. Trackerless torrents are now detected structurally instead of by string matching.
  • Title mismatch filter: search results where the parsed title doesn't match the target are rejected upfront. Unicode normalization (NFD) is consistent across the search path so accents don't cause false negatives.
  • Crash reporting: Logger backend now installs cleanly on Elixir 1.15+, and the admin toggle actually works.
  • Configurable metadata language for TMDB/TVDB requests, per install.
  • Test suite is ~42% faster (221s → 127s) and Docker CI builds dropped from 2h+ to ~15min.

🧱 Architectural cleanup

A lot of this release is invisible to users but matters for everyone contributing or reading the code:

  • AdminConfigLive split into eight focused LiveViews (AdminSettingsLive, AdminIndexersLive, AdminQualityProfilesLive, AdminLibraryPathsLive, AdminMediaServersLive, AdminDownloadClientsLive, AdminSystemLive, AdminRemoteAccessLive). The monolith is gone.
  • Settings and Downloads contexts split into facade + sub-modules.
  • MediaLive.Show extracted into focused event modules (SearchEvents, FileEvents, SubtitleEvents, plus five more).
  • Type safety overhaul: @spec and @type t annotations across all 43 Ecto schemas, all context module public functions, and 14 Oban workers (with typed Args structs). MediaFile.metadata is now a FileMetadata struct, not a plain map.
  • QueryHelpers.Filterable macro for declarative query filters, rolled out across collections, accounts, and downloads.
  • Component organization conventions documented (three-tier system: core / domain / feature-local).

⚙️ Infra

  • Iroh upgraded to 0.97 for the P2P core.
  • Docker CI: replaced Blacksmith with standard GitHub Actions for layer caching.
  • CI postgres containers no longer leak between precommit runs.

🐛 Notable fixes

  • Series rescan no longer imports wrong files / deletes metadata on refresh.
  • SQLite FK corruption during table recreation: fixed.
  • Word-form Season Two Episode Five filenames now import correctly.
  • File parser uses byte offsets for regex slicing, fixing Unicode title mismatches.
  • Req.TransportError from FlareSolverr and indexer connections no longer crashes the page.
  • Paused torrents at 100% are correctly classified as completed.

📦 Try it

docker pull ghcr.io/getmydia/mydia:0.10.0-beta3
# Postgres variant
docker pull ghcr.io/getmydia/mydia:0.10.0-beta3-pg
# Or the rolling beta tag
docker pull ghcr.io/getmydia/mydia:beta

Player builds for Android, macOS, Windows, and Linux are attached below.

Feedback welcome — open issues at getmydia/mydia. The plan is to bake this for a couple of weeks, fold in any regressions, then cut v0.10.0 final.

Full Changelog: v0.9.0...v0.10.0-beta3

Don't miss a new mydia release

NewReleases is sending notifications on new releases.