Docs / Reference
What Mediarium does today
A plain comparison of what Mediarium does today against the apps it can replace or sit beside, written from the source code.
- Snapshot: 2026-10-11, Mediarium 3.0.0 (database migrations up to
0170; see the changelog). Read every "No" as "not found when this was written". If it matters to you, look ininternal/andweb/src/pages. - How each row was judged: Yes = implemented and reachable in the UI or API. Partial = something real exists but it is narrower than the reference app. No = not found. The evidence is a package, file, endpoint or guide you can open.
- Reference apps are described from general knowledge of those projects and may be out of date for their newest versions. Uncertain claims are worded loosely or left out.
- Abbreviations: Rad Radarr, Son Sonarr, Lid Lidarr, Pro Prowlarr, Sab SABnzbd, qB qBittorrent, Baz Bazarr.
- In Mediarium's screens, indexers are called Indexers.
1. Where Mediarium stands in one paragraph
Movies, TV, music, ebooks and audiobooks all work end to end (music, ebooks and audiobooks once you switch them on; see 2.4b and Ebooks and audiobooks). That covers TMDB metadata; one search across Newznab/Torznab indexers and definition-based torrent sites (the community Cardigann definitions, downloaded on demand); grabbing; a built-in Usenet client (multiple servers, PAR2, native RAR and ZIP unpacking, 7z only for .7z); and a built-in BitTorrent engine (with an embedded WireGuard VPN and kill switch), or a torrent client or debrid service you already use. It also has hardlink import with naming presets, quality profiles with custom formats (and a TRaSH import), delay profiles, upgrade hunting, a blocklist with automatic retry, monitoring, tags, several folders per kind of media, a calendar, a wanted list, import lists that sync on a schedule, a request portal, subtitles, many kinds of notification, media server refresh, family accounts with single sign-on options, backups (also to the cloud), a clean-up of the downloads folder, health checks and a first-run wizard.
What is still thin or missing, stated plainly: files are not unpacked while they download (Usenet downloads unpack when they finish); downloads can't be dragged to reorder; a delay profile is one setting for the whole library (none per title, none for music or books); there are no per-indexer query limits, no per-indexer tags and no category mapping you can edit; there is no Last.fm scrobbling (ListenBrainz works); no comics or manga, no podcasts, and no adult content module; no theme songs or extras; watch state is read from your media server every six hours, not pushed by a webhook; and IMDb and Letterboxd lists are read from the exported file, not synced live (those sites don't allow it). Section 3 has the full list.
Family accounts exist. An administrator can add basic-user and viewer accounts (see Accounts). RAR (RAR4 and RAR5, including multi-part sets) and ZIP are unpacked natively in Go, so they work the same everywhere. Only the rare .7z format uses the 7z tool, which the Docker image includes.
2. Matrix
2.1 Library, search and automation (Radarr / Sonarr territory)
| Feature | In Mediarium today | Evidence | In reference apps |
|---|---|---|---|
| Monitoring (movie, show, season, episode) | Yes | PUT /api/movies/{id}/monitored, /api/series/{id}/monitored, /seasons/{season}/monitored, /episodes/{id}/monitored. Two optional switches stop monitoring a movie once it is downloaded, and a show once it has ended and every episode is in (library.unmonitor_downloaded, library.unmonitor_finished_shows) |
Rad, Son |
| Quality profiles (ordered tiers, cutoff, upgrade-until) | Yes | internal/quality/profile.go (15-tier ladder), /api/quality-profiles CRUD, per-title profile; five built-in presets: Cinema recordings, Any, 720p, 1080p (default) and 4K & over, all starting with upgrades off; "Skip bad releases" is on in every profile (whole discs, 3D, upscales, burned-in subtitles, poor re-encode groups) and a fixed release (PROPER, REPACK) wins over the broken one; a profile can refuse season packs; fallback profiles (see Quality profiles) |
Rad, Son |
| Custom formats (spec-based scoring: release group, HDR, codec, language, regex) | Yes | internal/api/custom_formats.go, /api/custom-formats (CRUD and /test), scores per profile with a minimum score and an upgrade-until score, a Score column in interactive search. Formats from Radarr, Sonarr and the TRaSH Guides import unchanged: GET /api/trash-guides/{app}, POST .../formats and .../profiles (ready-made profiles included), or paste their JSON. An advanced option, hidden until "Show advanced options" is on (Quality profiles). The TRaSH import is a button you press, not a scheduled sync |
Rad, Son (Recyclarr syncs TRaSH ones) |
| Quality definitions (min/max size per quality) | Yes | size limits per quality in MB per minute, with a reset to defaults (quality.size_limits, off by default); releases outside them are skipped and marked in the list. On top of that, a built-in minimum per quality catches fakes (internal/quality/size.go) and a profile can set the largest size (max_size_gb) |
Rad, Son |
| Delay profiles (wait N minutes for a preferred protocol) | Partial | one profile for the whole library: preferred protocol, minutes to wait for Usenet and for torrents, and "don't wait for the best quality" (internal/delay, setting search.delay_profile, GET/PUT /api/search/delay, GET /api/search/waiting). Held releases show on Wanted and on the title page. Movies and shows only. No profile per title or per tag, none for music or books. Off by default |
Rad, Son |
| Per-title protocol preference (usenet / torrent / both) | Yes | PUT /api/movies/{id}/sources, library.default_sources |
partly (via delay profiles) |
| Indexer management (add, test, edit, enable/disable, delete) | Yes | /api/indexers GET/POST/PUT/DELETE, /test, /{id}/test, /{id}/enabled. Newznab and Torznab APIs, plus sites from the definition list (kind: cardigann) with their own settings; passwords, cookies and keys stored encrypted and never returned. A failed test of a definition-based site shows on the dashboard |
Rad, Son, Pro |
| Indexer definitions engine (Cardigann / hundreds of trackers) | Yes | internal/indexers/cardigann*.go, definitions.go, GET /api/indexer-definitions. Runs the community Prowlarr/Indexers definitions (schema v11, downloaded when the site list is opened, none bundled): login by form, POST, GET or cookie with CSRF inputs and error/test selectors, HTML, JSON and XML results, the template language and the common filters, magnet and .torrent downloads through the signed-in session, per-site request delay, optional FlareSolverr for Cloudflare. You can add your own definition file (POST /api/indexer-definitions/custom). Almost all of the current definitions pass validation, and the site list marks the rest as unsupported, with the reason. Not supported: CAPTCHA logins, look-around regexes in regexp filters (skipped in re_replace), a handful of invalid selectors. Tested against local fixture sites; expect some real sites to need fixes |
Pro |
| Indexer priorities, per-indexer tags, seed rules | Partly | priority Preferred / Normal / Last resort breaks ties between equal releases (PUT /api/indexers/{id}/priority); seed rules per indexer for the built-in torrent client (PUT /api/indexers/{id}/seed-rules). No tags on indexers |
Rad, Son, Pro |
| Indexer back-off, health and statistics | Yes | after 3 failures in a row an indexer is left out of searches for 5 minutes, doubling up to 6 hours, with the reason and the time shown on the card and in Health, and a Try again now button (POST /api/indexers/{id}/resume, internal/api/indexer_health.go); searches, failures, success rate, releases found and grabs per indexer on the Statistics page (GET /api/stats/indexers, migration 0071). See Indexers and Search |
Rad, Son, Pro |
| Per-indexer query limits, category mapping | No | not found. Searches use fixed Newznab categories for each kind of media; definition-based sites map their own categories inside the definition. Nothing to edit per indexer | Pro |
| Usenet retention | Yes | tell Mediarium how many days your provider keeps posts (downloads.retention_days); automatic searches skip older posts and the release list marks them (Downloading) |
Sab (article age), Pro |
| Sync indexers to other apps | n/a | Mediarium is one app; can import Torznab/Newznab URLs from Prowlarr manually | Pro |
| RSS sync | Partial | rss-sync job (every 15 min by default, a setting; internal/api/automation.go) runs an empty-query search on every enabled indexer and matches recent listings to monitored items. It is a listings poll, not a dedicated per-indexer RSS feed; no per-indexer toggle |
Rad, Son |
| IRC announce (grab at the moment of release) | Yes | internal/announce, /api/irc-announce CRUD, /test and a log per connection: Mediarium sits in a tracker's announce channel and downloads a wanted release as it is announced. Four built-in announcement styles, a template editor and a test box, limits per hour and per bot. Only acts on titles already in the library. Off until you add a connection (IRC announce) |
Autobrr (separate app); Rad, Son via other tools |
| Scheduled missing / upgrade hunting | Yes | hunt job (every 6 h by default, a setting), series-refresh 12 h, genre-backfill hourly (internal/api/automation.go, automation_tv.go, genres_job.go) |
Rad, Son |
| Manual / interactive search with reject reasons | Yes | GET /api/movies/{id}/search, /api/series/{id}/search, ReleaseTable.tsx; "Search now" per row; the list sorts and filters by size, seeders, quality, score, indexer and words |
Rad, Son, Pro |
| Global cross-indexer search | Yes | GET /api/search, POST /api/search/grab, web/src/pages/Search.tsx |
Pro |
| Calendar | Yes | GET /api/calendar, pages/Calendar.tsx, month and agenda views, filters, and a private iCal feed per account (/api/calendar/feed/{token}.ics) |
Rad, Son (with iCal) |
| Wanted: missing and cutoff-unmet | Yes | GET /api/wanted, pages/Wanted.tsx |
Rad, Son |
| Rename / organize on import (token naming, presets) | Yes | internal/organizer/naming.go, presets plex/jellyfin/kodi/minimal/custom, Radarr and Sonarr token names, a builder with ready-made formats and a token list, live preview GET /api/settings/naming-preview |
Rad, Son |
| Bulk rename of an existing library | Yes | preview, then rename the ticked files with their subtitles (GET/POST /api/rename, Settings > Library) |
Rad, Son |
| Import an existing library | Yes | POST /api/library/scan, /api/library/import, GET /api/library/import/active, pages/ImportLibrary.tsx. Confirming registers every title at once in one transaction (no lookups); a background worker (internal/api/import_worker.go) then fills in details, resumes after a restart and retries failures. Imported titles are added unmonitored and set to leave what you have alone; two switches on the review page (both off) start monitoring, and for shows also look for missing episodes (Import your library) |
Rad, Son |
| Change many titles at once (Library select mode) | Yes | administrators pick titles (Shift-click for a range, "Select all N in this view") and monitor, switch better versions, set the quality profile, downloaders or tags, search now (monitored and missing only, 25 at a time) or remove them, each with one request in one transaction: PUT /api/library/bulk/{monitored,no-upgrade,profile,sources,tags}, POST /api/library/bulk/{search-now,remove}, and /api/music/bulk/{follow,profile,remove} for artists; files are deleted only when the request says so (Library) |
Rad, Son |
| Move many titles to another library folder | Yes | POST /api/library/move-files/preview and /api/library/move-files (internal/api/move_files.go): change the folder only for new files, or move the files already there too (copied and checked first when it is another drive) |
Rad, Son (mass editor) |
| Move over from other apps | Yes | internal/migrate, POST /api/migrate/preview, /api/migrate/run, GET /api/migrate/status: twelve apps (Radarr, Sonarr, Prowlarr, SABnzbd, NZBGet, Jackett, NZBHydra2, Overseerr/Jellyseerr, Ombi, Bazarr, Medusa, SickChill), read-only on their side. Library (files registered in place), monitored flags, quality profile matching, indexers, Usenet servers, requests and subtitle languages (Move from other apps). Screen: Settings → System → Move from other apps. |
Rad, Son, Pro, Sab |
| Manual import / manual match for unmatched releases | Yes | Activity > Import a file by hand: pick a file in the downloads folder and the movie or episode it is (/api/manual-import) |
Rad, Son |
| Multiple root folders | Yes | more movie and TV folders under Settings > Library > Folders and file names; the Add dialog and each title's page choose the folder (GET /api/library/folders, PUT /api/movies/{id}/folder, PUT /api/series/{id}/folder, internal/api/folders_extra.go); imports, renaming, the recycle bin, disk checks and the Radarr/Sonarr-compatible root folder list know about them |
Rad, Son |
| Several qualities of one title (a 4K copy next to 1080p) | Yes | opt-in second copies of a movie or show, each with its own profile, downloads and upgrades, kept in a copies folder of its own (internal/api/copies.go, movies.copy_of/series.copy_of; see Library) |
Rad, Son (a second instance) |
| Tags | Yes | tags on movies and shows (up to 20 per title) set on the title, when adding, on a selection, on an import list or in the Library filter; every tag becomes a collection on Plex, Jellyfin and Emby; cleanup rules can keep tagged titles (GET /api/tags, PUT /api/movies/{id}/tags, PUT /api/series/{id}/tags, PUT /api/library/bulk/tags). Not on indexers or notifications |
Rad, Son, Pro, qB |
| Import lists (automatic add from a list) | Yes | internal/importlists, /api/import-lists (CRUD, /preview, /{id}/run, /{id}/forget): Trakt (lists, watchlists, charts), TMDB, MDBList, and IMDb and Letterboxd from an exported file, read on a schedule from every hour to every week. Each list has a quality profile, folder, tags, a minimum rating and year, and an "add at most N at a time" limit. The Plex watchlist of each account (/api/plex-watchlist) is checked every 20 minutes. IMDb and Letterboxd have no open API, so those two are not live (Import lists) |
Rad, Son |
| List exclusions | Yes | "Not interested" on Discover (/api/exclusions); import lists skip those titles |
Rad, Son |
| Season packs, multi-episode releases | Yes | internal/parser, pipeline_tv.go, automation_tv.go; a grab marks the episodes it will deliver as downloading when it is queued, and automatic searches never grab an episode that is already downloading, so a pack's episodes are only tried singly after the pack failed (grab_claim.go). A profile can turn season packs off |
Son |
| Anime / absolute numbering / daily shows / series types | Yes | a show's episode numbering is standard, anime (absolute numbers) or daily (air dates), guessed when it is added (internal/api/series_type.go, parser Absolute/AirDate); specials are searched and grabbed one at a time, by S00Exx or by their title, once ticked |
Son |
| Scene numbering and anime mapping | Yes | TheXEM scene numbers, anime-lists mapping, AniList, AniDB and MyAnimeList links, a show's other names, and a Refresh mapping button (internal/animemap, GET /api/series/{id}/numbering, POST .../numbering/refresh, setting numbering.lookup); "Add anime groups" adds starter release-group terms to a profile (Library). Follows TheTVDB's numbering for scene episodes, which differs from TMDB for a few shows |
Son |
| Audio languages, original-language audio | Yes | a list of languages, best first, and "Original language of the title" (quality.language, internal/api/original_language.go); a release with two or more audio tracks counts when one is on the list (Quality profiles) |
Rad, Son (via language custom formats) |
| Minimum availability / release-date gating for movies | Partial | a film still only in cinemas is not searched automatically: it waits for the digital or disc date TMDB lists, or 90 days after the cinema date when TMDB has none; not held for a profile that takes CAM/TeleSync, and Search now still works. Not configurable per movie | Rad |
| Movie collections | Yes | a movie's page shows its TMDB collection with Add the whole collection and an option to add new films that join it; the Library filters by collection (GET /api/collections, POST /api/collections/{id}/add, PUT /api/collections/{id}/follow, Library) |
Rad |
| Editions | No | there is no edition management. The {Edition Tags} naming token fills in an edition that the release name states, so Plex's edition naming works |
Rad |
| Media management: recycle bin | Yes | removed files wait in .mediarium-trash inside the library folder for 7 days, with Put back (/api/trash) |
Rad, Son |
| Media management: file permissions / chmod / chown | Yes (mode; owner from PUID/PGID) |
set the mode of the files and folders Mediarium creates (library.file_mode, library.folder_mode, GET /api/settings/file-permissions, internal/fileperms); the container honours UMASK. Ownership comes from PUID/PGID only, no chown setting (Library) |
Rad, Son |
| Media management: existing-file conflict policy | Yes | library.import_conflict_policy skip / overwrite / overwrite-if-better / ask, atomic replace (organizer/import.go) |
Rad, Son (differently) |
| Media management: hardlink then copy fallback | Yes | organizer/import.go tries os.Link and copies when the link fails for any reason (another drive or mount, or a filesystem without hardlinks). The "same drive" check on the dashboard compares device numbers (organizer/samefs_unix.go), so two Docker mounts of one disk can pass it and still copy, which is why the compose file uses one /data mount (Install guide) |
Rad, Son |
| NFO and artwork files | Yes (off by default) | NFO files and poster, background, logo and season artwork for Kodi, Jellyfin and Emby, written after imports and for the library you already have (internal/metafiles, library.metadata_files) |
Rad, Son |
| Health checks | Yes | GET /api/health, internal/api/health.go (missing keys, no indexer, paused indexers, folder problems, VPN, recent failures, titles waiting for subtitles (only while subtitles are switched on), a missing par2 or 7z, and a shared Trakt or OpenSubtitles key reaching its limit) |
Rad, Son, Pro |
| Shared-key usage tracking | Yes | GET /api/usage counts requests and limit hits (HTTP 429, OpenSubtitles 406) per service over 24 hours (internal/usage); the dashboard suggests a free personal key when the shared one is busy |
none |
| Logs and errors | Yes | Settings > System > Logs and errors: real problems only (failed downloads, Usenet, indexers, media servers, import, disk and folders, database, notifications), each with a plain explanation and what to try, repeats counted on one row, kept 30 days, copy for support and a text file, optional message on new errors (internal/problems, GET /api/system/problems; see Logs and errors) |
Rad, Son, Pro (their log pages), Sab (warnings) |
| Notifications | Yes | internal/notify: email, webhook (with your own JSON body), Discord, Telegram, Slack, ntfy, Gotify, Pushover, Matrix, Home Assistant (notify service or webhook), Apprise (any service Apprise knows) and web push to the browser; per-target event choice, quiet hours, a test button and a test log (POST /api/notifications/test). Not Notifiarr, and no per-notification tags (Notifications) |
Rad, Son, Pro, Sab, Baz |
| Web push and installing as an app | Yes | push to a phone or computer from the browser itself with no app or account, encrypted per device (internal/notify/push.go, web/public/push-sw.js, GET /api/notifications/push-key); the web app has a manifest, so it installs to the home screen and opens like an app. Needs https; on iPhone and iPad, add it to the Home Screen first. No offline mode |
none |
| Media server connection (Plex, Jellyfin, Emby, Silo, Audiobookshelf, Kavita, webhook) | Yes | internal/mediaservers, /api/media-servers: find servers on the network, sign in with Plex, Jellyfin Quick Connect or a Jellyfin/Emby login (or add one with a token or API key), test, partial library scan of the imported folder after each import (debounced, with path mapping, full-scan fallback), Refresh now, "Watch in" links found by TMDB id (GET /api/media-servers/links, open to members), dashboard item when a server fails. Any other server can get a JSON message by webhook. See Media servers |
Rad, Son (Connect: Plex, Emby/Jellyfin library update) |
| History | Yes | GET /api/activity, Activity page; per title GET /api/movies/{id}/events and GET /api/series/{id}/events: each search with how many releases were acceptable and why not, the grab and the profile used, download and post-processing steps, failures, blocklisting and retries (see Activity) |
Rad, Son, Pro |
| Blocklist (auto on bad release, manual, retry next best) | Yes | internal/blocklist, /api/blocklist, POST /api/queue/{id}/blocklist. Retry on a failed Usenet download repeats post-processing on the files it already has instead of downloading again; one download at a time per movie or episode (a grab by hand while one runs gets 409) |
Rad, Son |
| Updates and restarts | Yes | new-version notice (daily GitHub check, notes, steps for Docker and native), signed Update now and overnight install, pushed updates (opt-in, POST /api/system/update), restart and safe restart, self-restart when stuck, Docker health check (internal/updatecheck, internal/selfupdate, docker/entrypoint.sh); see Install guide and Security |
Rad, Son (built-in updater) |
| Backup / restore | Yes | admin-only GET /api/system/backup (consistent VACUUM INTO snapshot + secret.key + manifest, as a zip) and POST /api/system/restore (strict validation, staged, applied on the next start; old files kept in before-restore-*), internal/backup. Nightly backups kept in /config/backups, with optional passphrase-locked copies in S3-style storage or a WebDAV folder, and restore from such a copy (internal/cloudbackup, /api/system/backups/cloud). Settings and database only, never media |
Rad, Son, Pro, Sab, Baz |
| API keys and authentication | Yes | local accounts, cookie sessions, rate-limited login, X-API-Key (internal/auth, /api/auth/api-keys); read-only keys for a viewer or for monitoring |
all |
| Two-step sign-in (TOTP) | Yes | a six-digit code from an authenticator app after the password, recovery codes, switched on per person (internal/totp, /api/auth/two-step/*); wrong codes are counted per account |
Rad, Son, Pro (not built in) |
| External auth (OIDC, LDAP, passkeys, proxy header) | Yes | OpenID Connect (Authelia, Authentik, Keycloak, Pocket ID, Google; internal/oidcauth), LDAP and Active Directory (internal/ldapauth), passkeys (/api/auth/passkey*), and sign-in through a reverse proxy's user-name header from a trusted proxy address only (/api/auth/proxy-signin). All off until you turn them on; local sign-in can be switched off, and MEDIARIUM_DISABLE_SSO=1 is the way back in (Accounts). No HTTP basic auth |
Rad, Son, Pro (forms/basic/external) |
| URL base and secrets from files | Yes | URL_BASE=/mediarium runs the app under a sub-path of a domain; any container variable can be read from a file (NAME_FILE=/run/secrets/x) for Docker secrets (Install guide) |
Rad, Son (URL base) |
| Prometheus metrics | Yes | GET /metrics (also /api/metrics), admin only, accepts a bearer API key: wanted counts, library sizes, queue, disk space, health and indexer status (Install guide) |
Rad, Son via exporters |
| Statistics / disk-space overview | Yes | Statistics page: library size, titles per quality, downloads per month, charts over time from a daily snapshot (GET /api/stats/history), indexer statistics and, with watched status on, what gets watched (GET /api/stats/library), plus the dashboard's folder health |
Rad, Son |
| A title's files on disk, playing a video in the browser | Partial | GET /api/movies/{id}/files and GET /api/series/{id}/files list the title's folder (relative path, size, date, kind: video, subtitle, image, nfo, other). GET /api/files/stream?movie={id}&path=... (or series=) sends a video file as it is, with seeking, for a <video> player; SRT and VTT files next to the video are offered in the player's subtitle menu. It also previews pictures (jpg, png, webp, gif, with their image type) and text files (nfo, srt, ass, ssa, vtt, txt, up to 2 MB, always as text/plain). Anything else, html, svg and scripts included, is refused with 415, and every file is sent with X-Content-Type-Options: nosniff, Content-Security-Policy: sandbox and Content-Disposition: inline. Only files inside the library folders can be reached (no ../, no symlinks leading out). No transcoding: MP4 and WebM play in every browser, MKV only where the browser supports it (internal/mediafiles) |
Plex, Jellyfin, Emby (with transcoding) |
| Discover, recommendations | Yes | /api/discover/*, "More like your library" (recent, popular titles that several of your titles point to; a paged "Browse more" list with a switch for older titles, list=similar on /api/discover/list), browse by genre, year and sort order (/api/discover/browse, /api/discover/genres), pageable trending, popular and coming-soon rails for movies and shows (/api/discover/list), titles and posters in your own language (pages/Discover.tsx) |
Overseerr / Jellyseerr-style, partly Rad, Son |
| Apps made for Radarr, Sonarr and Lidarr can connect | Partial | Mediarium answers as those apps at /radarr, /sonarr and /lidarr with an administrator's API key, so Overseerr and Jellyseerr, Homepage and Homarr, and phone apps such as nzb360, LunaSea and Ruddarr work (internal/api/arr*.go, Other apps). Library, add, monitor, search, queue, wanted, calendar, root folders, quality profiles and tags work. Not available: history, manual imports, renaming, the apps' own settings pages and changing profiles from the app |
Rad, Son, Lid (as the thing being connected to) |
| First-run wizard with live folder checks | Yes | pages/Onboarding.tsx, /api/settings/folder-check |
none of them as such |
| Mobile-friendly UI, light/dark theme, several languages | Yes | web/src/index.css, ThemeToggle.tsx; screens in English, Spanish, German, French and Brazilian and European Portuguese (messages from the server itself stay in English for now) |
Rad, Son (mobile partly) |
2.2 Usenet downloader (SABnzbd territory)
| Feature | In Mediarium today | Evidence | In reference apps |
|---|---|---|---|
| NZB download via NNTP, SSL, yEnc | Yes | internal/download/nntp.go, yenc.go, nzb.go, downloader.go |
Sab |
| Multiple servers, primary and backup with priority | Yes | DownloadFromServers (falls through per article), usenet_servers UI, migrations/0012 |
Sab |
| Connections per server, test button | Yes | Connections in ClientConfig, POST /api/usenet-servers/test; Find the right number (POST /api/usenet-servers/{id}/probe) tries connections one by one and sets what the provider really allows |
Sab |
| PAR2 verify and repair | Yes, needs par2 binary |
internal/organizer/par2.go; skipped silently if par2 is missing unless articles are missing. Obfuscated releases get their real names back from the PAR2 data first; a release with too few repair files for its missing articles is stopped early and blocklisted |
Sab |
| Unpack (RAR, ZIP, 7z) | Yes | internal/organizer/archive.go: RAR (single, .partNN.rar, .rar+.r00) via pure-Go rardecode, ZIP via archive/zip, both with path-traversal and size-bomb protection; password-protected archives fail as a bad release. Only .7z shells out to 7z |
Sab |
| Direct unpack (unpack while downloading) | No | files are unpacked after the download finishes | Sab |
| Article cache | No | not found | Sab |
| Pause / resume queue or item | Yes | POST /api/queue/{id}/pause, /resume, /stop, POST /api/queue/pause-all, /resume-all (queue_control.go); a paused download keeps its files and stays paused after a restart. The Download clients tab in Activity has Pause all and Resume all for each downloader alone |
Sab, qB |
| Speed limit, scheduling | Yes | one limit for Usenet and torrents, optionally only between two hours (downloads.speed_limit_mb, downloads.speed_limit_hours), download hours (new downloads start only between two hours, downloads.hours), and a free-space floor |
Sab, qB |
| Queue ordering / priority per item | Partly | downloads wait in one line: what a person started goes before what the automatic searches added, then first come, first served; a resumed download goes to the front of its group (priority and line_seq on download_queue, internal/queue/dispatch.go). There is no drag to reorder |
Sab, qB |
| Categories | No (Usenet) | movies vs TV is tracked in the queue row, but there is no user-visible category for Usenet downloads and no per-category script. The built-in torrent client does have categories (see 2.3) | Sab, qB |
| Post-processing scripts | Yes, after import | internal/api/scripts.go: one script from /config/scripts, picked in Settings > System (not with an API key), run after each import with MEDIARIUM_* variables, one at a time with a time limit (Your own script) |
Sab, Rad, Son |
| Retention / article-age handling | Yes | downloads.retention_days: older posts are skipped by automatic searches and marked in the release list |
Sab |
| Reject releases that contain programs | Yes (on by default) | .exe, .scr, .bat and similar are rejected before the download and again after unpacking, blocklisted, and another release is searched for (downloads.reject_executables, internal/api/download_checks.go) |
Sab (unwanted extensions), Rad, Son |
| Duplicate detection | Yes (optional) | a release that was already downloaded or is already in the queue is not downloaded again (downloads.skip_duplicates) |
Sab |
| Failed download handling (blocklist and pick next release) | Yes | internal/api/pipeline.go, blocklist.go |
Rad, Son (Sab reports failure) |
| Add an NZB, torrent file, address or magnet link by hand | Yes | Activity > add a download: upload a file or paste an address or magnet link, for a movie or episode you pick (POST /api/downloads/manual, internal/api/manual_download.go) |
Sab |
| RSS feeds in the downloader | No (handled by automation, above) | Sab | |
| Live queue with progress | Yes | GET /api/queue, GET /api/downloads/status; speed and time left per download, and a Details box with indexer, release, size, times and what happened |
Sab |
| A proxy for Usenet, indexers or torrents | Yes | a SOCKS5 or HTTP proxy with a Test button (/api/proxy, network.proxy, network.proxy_for); a proxy for torrents counts for the kill switch |
Sab, qB |
2.3 Torrent client (qBittorrent territory)
| Feature | In Mediarium today | Evidence | In reference apps |
|---|---|---|---|
| Magnet and .torrent grabs | Yes | internal/torrentclient (anacrolix/torrent), pipeline.go downloadTorrent |
qB |
| Seeding limits (ratio, time) | Yes, global and per indexer | torrent.seed_ratio_limit, torrent.seed_time_limit_h, SeedUntilGoal in internal/torrentclient (stops the torrent and, once imported, deletes its data); rules per indexer (PUT /api/indexers/{id}/seed-rules) |
qB |
| Categories and per-category save paths | Yes | up to 12 categories, each with an optional folder name, chosen per kind of media (Movies, TV, Music, Books); a torrent is saved in incomplete/<folder>/queue-N (torrent.categories, torrent.category_map, Downloading). No per-category script |
qB |
| Speed limits (global, per torrent, alternative) | Yes (no second alternative set) | one global limit shared with Usenet, with hours; a download limit per torrent and an upload limit of the engine's own (torrent.upload_limit_kb, PUT /api/queue/{id}/torrent) |
qB |
| Queueing / max active torrents | Yes | one shared limit, Downloads at the same time (1 to 5, one by default, downloads.concurrent), for Usenet and torrents together; a download keeps its place until it is imported, a seeding torrent does not (internal/queue/dispatch.go, internal/api/dispatch.go) |
qB |
| Stalled-download detection | Yes | a torrent with no data for a time you choose (1 to 72 hours, or never; downloads.stall_hours) is stopped, blocklisted and another release is tried (torrentclient.ErrStalled) |
qB (Cleanuparr adds it for *arr queues) |
| File selection, sequential download | Yes | choose which files to download (samples and notes are left out by default), download in order, and optionally only the wanted season of a season pack (PUT /api/queue/{id}/torrent/files, torrent.skip_junk, torrent.sequential_default, torrent.pack_only_wanted) |
qB |
| Per-torrent priority | No | the download line decides the order; there is no priority per torrent | qB |
| A torrent list UI (peers, trackers, pause, recheck) | Partly | Activity > Download clients shows the built-in torrent client and Usenet downloader as two cards, with every download and the queue buttons, and the clients you connected with state, speed, peers, time left, ratio, idle time, and pause, resume, check, remove and "give up and search again". Peers and seeds of a built-in torrent show under Details. No tracker list | qB |
| Listen port setting | Yes | torrent.listen_port, default 58264 (TCP and UDP), published in the compose files; one shared engine for all torrents; GET /api/downloads/status reports whether incoming connections have been seen |
qB |
| Port forwarding | Yes (UPnP / NAT-PMP) | a switch that asks the router to open the port and shows the result (torrent.port_mapping); never used with the VPN tunnel. VPN providers' own port forwarding still needs external glue |
qB (UPnP) |
VPN with kill switch, no NET_ADMIN |
Yes | internal/vpn (embedded userspace WireGuard), vpn.require_for_torrents, /api/vpn/*, egress IP check; paste a WireGuard .conf to fill the form |
none built in (Gluetun sidecar is the usual answer) |
| Peer discovery when tunneled | Partial | with a tunnel, DHT, uTP and incoming peers are off (torrentclient.New), so magnets rely on trackers; UDP trackers are skipped |
qB |
| Use a torrent client you already run | Yes | qBittorrent, RDT-Client and Decypharr: downloads and seeds in their own folder, Mediarium imports from there without moving or deleting; category, path mapping, optional remove after import; Decypharr symlinks (internal/qbit, /api/download-client, Downloading) |
Rad, Son (download clients) |
| Debrid services | Yes | Real-Debrid and TorBox: the service downloads the torrent, Mediarium fetches the finished files over https; nothing seeded, built-in torrent client can stay off (internal/debrid, /api/debrid) |
Rad, Son (via other tools) |
2.4 Subtitles (Bazarr territory)
| Feature | In Mediarium today | Evidence | In reference apps |
|---|---|---|---|
| Providers | Partial: two, plus add-ons | OpenSubtitles and SubDL (optional free key), searched together, best fit wins; SubDL carries on when the OpenSubtitles daily limit is used up (internal/subtitles/opensubtitles.go, subdl.go). You can also add the address of a subtitle add-on (the Stremio kind) to search more sites (/api/subtitles/addons, subtitles.addons); subtitles in older Windows code pages are converted to UTF-8 and WebVTT to SRT |
Baz (many) |
| Subtitles inside the video | Yes | MKV/WebM and MP4/M4V/MOV subtitle tracks read from the headers count as there; forced tracks don't (unless a forced track is what you want); subtitles.count_embedded (internal/subtitles/embedded.go) |
Baz (embedded subtitles provider) |
| Subtitles that come with the release | Yes | .srt .ass .ssa .sub .idx .sup files in the finished download are copied next to the video as <video>.<lang>.<ext>; language read from the file or folder name, episodes in a pack matched by SxxEyy (internal/subtitles/sidecar.go, langdetect.go) |
Baz (reads existing files) |
| Master switch, off by default | Yes | subtitles.enabled (subtitlesEnabled in /api/settings and /api/modules). While off there are no searches or downloads, no subtitle health items, no Wanted tab or count, no subtitle tools on title pages, and the subtitle routes answer 409. Subtitles inside a download are still imported |
Baz (always on) |
| Offer, not auto-fetch | Yes | with the switch on, subtitles.auto_download is off unless turned on; a health item offers the missing ones, the Wanted page fetches them on request (POST /api/subtitles/get) |
Baz (always automatic) |
| Auto download after import and missing sweep | Yes, opt in | subtitles_auto.go, subtitle-sweep job, Wanted page tab; only when subtitles.auto_download is 1 |
Baz |
| Daily download limit awareness | Yes | downloads and OpenSubtitles' reported remaining are tracked; GET /api/subtitles/quota warns when more is wanted than the day allows |
Baz |
| "No subtitles wanted" per title | Yes | POST / DELETE /api/subtitles/dismiss, left out of Wanted, the offer and every fetch |
Baz (per-series profiles) |
| Manual search and choose per movie or episode | Yes | /api/movies/{id}/subtitles, /api/episodes/{id}/subtitles; the list sorts by rating and fit |
Baz |
| Best-fit ranking (file hash, release group, source, codec) | Yes | internal/subtitles/pick.go, hash.go: a subtitle made for the exact video file (OpenSubtitles hash) comes first |
Baz (scored) |
| Multiple languages | Yes, global list | subtitles.languages |
Baz (per-language profiles) |
| Per-language kind: normal, SDH, forced | Yes | per language choose normal or SDH, normal only, SDH only, forced only, or any of these with a forced track alongside (subtitles.profiles); files are named .sdh and .forced so Plex, Jellyfin and Emby understand them. The choice is global, not per series |
Baz (per-series profiles) |
| Upgrade existing subtitles | Yes | internal/api/subtitles_upgrade.go: for 30 days after an automatic pick, looks every three days for one made for the exact file and swaps it in; never a hand-picked or edited subtitle; subtitles.upgrade (on, only with automatic downloading) |
Baz |
| Sync / re-time subtitles | Yes | internal/subtitles/timing.go, POST /api/subtitles/timing: shift, or line up with another subtitle in time (frame-rate drift included); the original is kept |
Baz |
| Embedded-subtitle detection | Yes | see "Subtitles inside the video" above | Baz |
2.4b Music (Lidarr territory)
Switch it on in Settings > Media types (Media types, Music). Until then every /api/music/ route answers 404 and nothing runs in the background.
| Feature | In Mediarium today | Evidence | In reference apps |
|---|---|---|---|
| Module switchboard (movies, TV, music, ebooks, audiobooks) | Yes | GET/PUT /api/modules, settings modules.*, internal/api/modules.go; switching a module off stops its automation and refuses new titles (409), deleting nothing |
none |
| Artist search and metadata | Yes | metadata client (internal/music*): identifying User-Agent, one request per second from a shared bucket, retry with backoff on 503, in-memory cache; GET /api/music/search?q= |
Lid |
| Cover art | Yes | the front cover (500 px) from the cover-art service is fetched once per album, cached under the config folder and served by GET /api/music/albums/{id}/cover and /api/music/artists/{id}/cover (cache headers, plain 404 when there is none); saved as cover.jpg in the album folder on import when none exists, never overwriting (internal/api/music_cover.go) |
Lid |
| Artists, albums, EPs, singles, tracklists | Yes | POST /api/music/artists with monitor all / future / none, GET /api/music/artists[/{id}], GET /api/music/albums/{id}; the canonical release (earliest official, most common country) supplies the tracklist; live albums, compilations and remixes are left out |
Lid |
| Monitoring (artist, album) | Yes | PUT /api/music/albums/{id}/monitored decides what is searched; an artist is followed or not (PUT /api/music/artists/{id} with monitored, profileId): a followed artist is checked every 12 hours and new releases are added monitored (music-refresh job, internal/api/music_follow.go) |
Lid |
| Audio quality profiles | Yes | tiers MP3-192, MP3-256, AAC-256, MP3-320/V0, FLAC, FLAC 24bit; presets Lossy (MP3 320), the default, and Lossless (FLAC) with a Lossy fallback; cutoff, upgrades, fallback chain (internal/music/quality.go); profiles can be made, edited and deleted and the default chosen (/api/music/profiles, musicDefaultProfileId), with the same rules as video profiles; edited in Settings > Library > Quality (MusicProfiles.tsx, reusing the fallback editor), per-artist profile on the artist page |
Lid |
| Release-name parser for music | Yes | artist, album, year, format, bitrate, bit depth, source, discography (internal/music/parse.go, table-driven tests with P2P and scene names) |
Lid |
| Search and grab (Usenet and torrent) | Yes | Newznab/Torznab categories 3000, 3010, 3040, 3050; interactive search with rejection reasons POST /api/music/albums/{id}/search, /grab, /search-now; scheduled hunt (25 albums per run) and retry after a bad release; same queue, downloaders and blocklist as movies |
Lid |
| Import and naming | Yes | audio files matched to the tracklist (number, then title), Artist/Album (Year)/NN - Title.ext (D-NN on multi-disc), hardlink then copy, cover.jpg/folder.jpg kept, old files replaced on an upgrade; per-album activity GET /api/music/albums/{id}/events |
Lid |
| Files of an album and playing a track in the browser | Yes | GET /api/music/albums/{id}/files (like the movie listing, tracks marked with trackId) and GET /api/files/stream?album={id}&path= with the right audio types (audio/flac, audio/mpeg, audio/mp4, audio/aac, audio/ogg, audio/opus), ranges, the same sandbox headers and path safety through internal/mediafiles (ForDir, inside the music folder only). No transcoding |
Lid |
| Import an existing music folder | Yes | POST /api/music/import/scan, GET /api/music/import/scan/{id} (admin): matches Artist/Album folders in the music database, registers files in place, reports the unmatched |
Lid |
| Reading embedded audio tags and real quality | Yes | github.com/dhowden/tag (BSD-2-Clause) for artist, album artist, album, title, track and disc, year and picture (internal/music/tags.go); in-house header readers for FLAC, MP3 (Xing/VBRI/Info), M4A (AAC, ALAC), ADTS and Ogg Vorbis/Opus give bit depth and bitrate (internal/music/audioinfo.go). Tags identify an album when scanning and match files to the tracklist after a download; the quality of files on disk is read from them, and a file that cannot be read stays Unknown. Files and tags are never rewritten |
Lid |
| Media server refresh after a music import | Yes | the same refresher as movies and TV (mediaservers.MediaMusic): Plex scans the album folder in its music library (type artist; all music libraries when no folder matches), Jellyfin and Emby get the folder through Library/Media/Updated; 15 second debounce, path mapping |
Lid |
| Music screens: Media types page, Library Music tab, artist page, collection import | Yes | web/src/pages/settings/ModulesSettings.tsx, MusicLibrary.tsx, MusicArtist.tsx, MusicImport.tsx; the app-wide modules state (ModulesContext.tsx) hides the Movies, TV and Music tabs of modules that are off, for every account; artist search with an add dialog in Discover (MusicDiscover.tsx, AddMusicDialog.tsx, the same dialog in both) and in the header search; follow switch and profile picker on the artist page; album Files tab with an in-app audio player (FilesPanel.tsx); local cover art; a page for every album on Discover, also those you don't have |
Lid |
| Music player in the browser | Yes | a bar at the bottom of the app that keeps playing while you move around: previous, next, seek, shuffle, repeat, remembered volume, media keys and lock screen, play and shuffle for a whole artist, and a window of its own you can pop out (MusicPlayer.tsx, musicPlayerContext.ts). A track the browser can't play (ALAC outside Safari) is skipped with a note |
Lid has none; Plexamp, Navidrome-style players |
| Playlists, queue panel, gapless playback and crossfade | Yes | private or shared playlists (/api/music/playlists, internal/api/music_playlists.go), a queue panel, gapless playback with an optional crossfade (GET /api/music/player-settings) |
none |
| Lyrics | Yes | synced lyrics from a .lrc file, the file's tags or LRCLIB (GET /api/music/tracks/{id}/lyrics, internal/lrclib, setting music.lyrics_online) |
none |
| ReplayGain | Yes (off by default) | the player reads track and album gain and peak tags, including Opus R128_*, and evens out the volume (GET /api/music/tracks/{id}/gain) |
none |
| Sending plays to ListenBrainz | Yes | each account connects its own ListenBrainz token; now playing and listens are sent, kept and retried when ListenBrainz is unreachable (internal/listenbrainz, /api/music/listenbrainz) |
Lid has none |
| Last.fm scrobbling | No | not supported; ListenBrainz is | none |
| Music in the calendar, dashboard tiles, Wanted page | Partial | Wanted (missing and upgrades, with a kind filter and Search now), Activity (queue rows with cover, retry, blocklist, waiting list) and the dashboard's recent lists show albums (Wanted.tsx, Queue.tsx, Dashboard.tsx); albums are in /api/calendar as kind: "album" (albumCalendarEntries) and on the Upcoming calendar with a music badge (CalendarGrid.tsx), but not in the dashboard's coming-up list (library.music carries the music counts, see Music) |
Lid |
| Delay profiles for music | No | the delay profile applies to movies and shows only | Lid |
2.5 Users, requests and the wider ecosystem
| Feature | In Mediarium today | Evidence | Where it exists |
|---|---|---|---|
| Multiple users and roles | Yes | administrator, basic user and Viewer (looks and plays, never changes anything; a test walks every route to prove it), accounts that can be turned off without deleting them, and per-user permissions for basic users (which media types, add titles themselves, pick releases, search and monitoring, retry, subtitles, play, read and listen); one route table decides who may call what (internal/api/server.go, access.go; Accounts). No per-user libraries |
Overseerr, Jellyseerr (users, roles); *arr apps are single-login |
| Request portal (family asks, admin approves) | Yes | a basic user without "add titles themselves" sends a request; administrators approve or decline it with a note under Activity > Requests (internal/requests, /api/requests*). On top of that: email and device notices when a request is approved, declined or ready to watch, per-person limits per day or week, 4K requests (a second copy with its own profile), and "Report a problem" on a movie or show, answered under Activity > Reports (/api/issues*). No per-user libraries or request approval chains |
Overseerr, Jellyseerr |
| Books (Readarr) | Yes | ebooks and audiobooks by book (Open Library, optional Hardcover token), format preference, search, grab and filing by author (Ebooks and audiobooks); following authors and series (their missing and new books are added by themselves); release dates on the calendar; narrators and running times from Audnexus; import of an existing folder; MOBI/AZW3 open in the reader through a built-in converter; Audiobookshelf and Kavita as media servers | Readarr |
| Mediarium Books: reader, player, e-reader sync | Yes | built-in reader (EPUB, PDF) and audiobook player with chapters, speed and sleep timer, reading position kept across devices; an OPDS catalogue for KOReader, Moon+ Reader, Librera, Marvin and Foliate with its own e-reader password (internal/opds, opds_api.go); Kobo sync with KEPUB conversion and reading position (internal/kobo, kobo_api.go). Kobo sync is not yet tested on a real Kobo |
Calibre-Web, Audiobookshelf, Kavita |
| Comics, manga | No | not planned for now | Mylar3, Kapowarr |
| Podcasts | No | not found | Audiobookshelf |
| Adult (Whisparr) | No | not planned | Whisparr |
| Extras and theme songs | No | trailers play behind a title page (muted, from YouTube, on by default and switchable) but no extras are downloaded and no theme songs | Plex, Jellyfin, Emby (themes) |
| Play-state stats | Partial | with What's been watched on, Mediarium asks Plex, Jellyfin and Emby every six hours which titles were played and shows it on title pages and the Statistics page (how much gets watched, space held by what nobody watched, most and latest watched). Polled, not pushed by a webhook; no per-user history of its own (GET /api/watched, watched.sync) |
Tautulli |
| Archive extraction helper for other apps | n/a (built in) | Unpackerr | |
| Sync TRaSH profiles and custom formats | Partial | import of the TRaSH formats and ready-made profiles in the app (see custom formats above); a button, not a scheduled sync | Recyclarr |
| Notification hub | Partial | built-in senders and Apprise, no Notifiarr integration | Notifiarr |
| Auto hunt for missing / upgrades | Yes (built into automation) | hunt job |
Huntarr |
| Clean stalled / failed queue items | Yes | failed downloads are blocklisted and retried; a stalled torrent is stopped, blocklisted and replaced (time is a setting); working folders are removed after import, torrent data once its seeding goal is met, and a daily clean-up (GET/POST /api/system/cleanup) removes orphaned, leftover and empty folders in the downloads working folder (never the library) and prunes history older than cleanup.history_retention_days (see Downloading) |
Cleanuparr |
| Library cleanup rules (unwatched, old) | Yes (off by default) | remove movies or episodes watched a while ago, or movies nobody watched long after they were added, with a preview first, tags that keep a title safe, the recycle bin, and every removal in Activity (cleanup.rules, GET /api/watched/cleanup/preview, POST /api/watched/cleanup/run, internal/cleanup). Needs a media server for the watch data |
Maintainerr |
3. What to add next
Effort: S = days or less, M = about 1 to 2 weeks, L = weeks. Priority reasons are about making a public v1 credible, not about copying everything. Items struck through are done.
P0: the most important gaps
| # | Item | Effort | Why |
|---|---|---|---|
| 1 | ~~Make RAR unpack work in the image~~ Done: RAR is unpacked natively in Go; the health check now notes a missing 7z (info, .7z only) and a missing par2 |
S | Most Usenet releases are RAR |
| 2 | ~~Hardlink defaults~~ Partly done: the compose file and guides use one /data mount. Still open: make the "same drive" check try a real os.Link probe instead of comparing device numbers |
S | Separate mounts silently copy; the dashboard can say everything is fine |
| 3 | ~~Windows: copy when a link fails~~ Done: any link failure falls back to a copy | S | |
| 4 | ~~In-app backup and restore~~ Done (Settings > System > Backup and restore), with nightly backups and cloud copies | M | /config copy while running can corrupt; the selling point is "one folder", so make it one click |
| 5 | Download queue control: ~~pause/resume~~ done (Pause, Resume, Stop, Pause all, Resume all, and a download line), ~~speed limit~~ done (with hours and download hours); still open: dragging to reorder (Usenet and torrent) | M | Baseline expectation coming from SABnzbd or qBittorrent |
| 6 | ~~Manual import / manual match UI for releases that fail matching~~ Done (Activity > Import a file by hand) | M to L | Named in the original plan; without it failures are dead ends |
| 7 | ~~Edit indexers~~ Done, ~~per-indexer priority~~ done, back-off and statistics done; still open: per-indexer RSS toggle, tags, query limits | S to M | Priorities decide which indexer wins a tie |
| 8 | ~~A real definitions engine~~ Done: torrent sites can be added from the community definition list without Prowlarr or Jackett, and you can add your own definition file (see Indexers and Search); still open: proving it against more real sites, CAPTCHA logins | L | Without it torrent users needed Prowlarr or Jackett, which defeats the "no other containers" pitch |
P1: needed to compete with *arr for daily use
| # | Item | Effort |
|---|---|---|
| 9 | ~~Torrent management page~~ Mostly done: Activity > Download clients, file selection, sequential download, per-torrent and upload limits, categories, seeding rules, UPnP, stall time; still open: tracker list, per-torrent priority | L |
| 10 | ~~Custom formats with scoring plus TRaSH import~~ Done. Still open: a scheduled TRaSH sync | L |
| 11 | ~~Delay profiles~~ Partly done: one profile for the library. Still open: a profile per title or tag, and for music and books | M |
| 12 | ~~Multiple root folders per media type~~ Done | M |
| 13 | ~~Tags~~ Done for titles, import lists and cleanup rules. Still open: tags on indexers and notifications | M |
| 14 | ~~Recycle bin and file-permission (chmod) options~~ Done | S |
| 15 | ~~Import lists that sync on a schedule (Trakt, TMDB lists, Plex watchlist) plus exclusions~~ Done, with MDBList and IMDb and Letterboxd files. Live IMDb and Letterboxd sync is blocked by those sites | M |
| 16 | More subtitle providers and ~~per-language profiles~~ done (normal, SDH, forced). Subtitle add-ons bring in more sites; still open: native providers beyond OpenSubtitles and SubDL | M to L |
| 17 | ~~Multi-user with roles~~ Done: admin, basic-user and viewer accounts, read-only keys (see Accounts) | M |
| 18 | ~~iCal feed for the calendar; /metrics~~ Done |
S |
P2: polish
| # | Item | Effort |
|---|---|---|
| 19 | ~~Download scheduling~~ Done: download hours (see Downloading) and post-processing scripts (see Your own script) | M |
| 20 | ~~OIDC / reverse-proxy header auth~~ Done, with LDAP, passkeys and two-step sign-in | M |
| 21 | ~~Anime handling (absolute numbering, series types, daily shows)~~ Done, with specials (see Library) and TheXEM / AniList scene numbering | M to L |
| 22 | Subtitle ~~sync~~ Done (shift and line up with another subtitle; see Subtitles) and ~~upgrades~~ done | M |
| 23 | ~~Quality size limits~~ Done, ~~movie collections~~ done. Still open: editions | M |
| 24 | ~~Bulk rename of an existing library~~ Done: Rename existing files (see Library) | M |
| 25 | ~~NFO and artwork files, bulk move to another folder~~ Done | M |
P3: later
| # | Item | Effort |
|---|---|---|
| 26 | ~~Request portal~~ Done (approval, limits, 4K, notices, problem reports) | L |
| 27 | ~~Play-state sync from Plex, Jellyfin, Emby~~ Done (off by default; see Media servers), with watch statistics on the Statistics page. Still open: updates pushed by a webhook instead of a six-hour poll | L |
| 28 | ~~Library cleanup rules~~ Done, with a preview and keep tags (off by default) | M |
Still not there
What is honestly missing today, in no particular order. None of it is hidden behind a setting.
| Item | What is missing |
|---|---|
| Direct unpack | Usenet downloads are unpacked when they finish, not while they download |
| Article cache | no cache in front of the Usenet downloader |
| Dragging to reorder the download line | the line is ordered by who started the download, then first come first served |
| Delay profile per title | there is one delay profile for the whole library; none for music or books |
| Per-indexer query limits and category mapping | not editable per indexer; no tags on indexers; no per-indexer RSS toggle |
| Per-torrent priority and a tracker list | the download line decides the order |
| Editions | only the {Edition Tags} naming token that reads an edition from the release name |
| Last.fm scrobbling | ListenBrainz works |
| Comics and manga | no module |
| Podcasts | no module |
| Adult content | not planned |
| Extras and theme songs | not downloaded |
| Watch state by webhook | read from Plex, Jellyfin and Emby every six hours |
| Live IMDb and Letterboxd sync | those sites offer no open API; their lists are read from the exported file |
| TRaSH sync on a schedule | the TRaSH import is a button you press |
| Native subtitle providers beyond OpenSubtitles and SubDL | add-ons cover more sites |
Hardlink check with a real os.Link probe |
the dashboard compares device numbers |
| Kobo sync on a real device | not yet tried on a real Kobo; tested against fixtures only |
| Offline use of the web app | it installs to the home screen but needs the server |
4. Optional modules for later
Each of these could become a module of its own. The projects named are for ideas only; check a project's licence before reusing any of its code.
| Module | What it would do | Projects to study |
|---|---|---|
| Music | Built: metadata, release matching, per-track naming, quality profiles for FLAC/MP3, a player with playlists, lyrics, ReplayGain and ListenBrainz (see 2.4b). Not built: writing tags | Lidarr (the *arr way), Picard (metadata and tagging), beets (tagging and organizing library tool) |
| Books and audiobooks | Built: ebooks and audiobooks with Open Library details, authors, Discover, import and the Mediarium Books reader and player (see Ebooks and audiobooks). Also built: following series, release dates on the calendar, narrators and running times, OPDS and Kobo sync | Readarr (same family), Calibre-Web (library), Audiobookshelf (audiobooks and podcasts server) |
| Comics | Volume/issue tracking with a comics metadata source. Not built | Mylar3, Kapowarr |
| Podcasts | Subscribe to feeds, download episodes, retention rules. Not built | Audiobookshelf also handles podcasts |
| Anime specifics | Built: absolute numbering, series types, TheXEM scene numbering, AniList, AniDB and MyAnimeList links, release-group terms, audio languages. Not built: dual-audio scoring beyond the language list | Sonarr's anime handling, Shoko |
| Request portal | Built: users ask, admins approve, requests turn into monitored titles; limits, 4K, notices and problem reports | Overseerr, Jellyseerr |
| Watch-status sync | Built: play state from Plex, Jellyfin or Emby drives watch statistics and "watched" cleanup. Not built: ratings, sync to Trakt, webhook updates | Tautulli (Plex), Jellystat (Jellyfin), Trakt's own API |
| Library cleanup | Built: rules such as "unwatched for a year" with a preview and the recycle bin | Maintainerr |
| Stats | Built: downloads per month, library size over time, watch statistics, indexer success rates. Not built: storage per drive over time | Tautulli for the presentation ideas |
| Notifications | Built, including Apprise for hundreds of services. Not built: Notifiarr | Apprise (used by other self-hosted apps), Notifiarr |
5. Things that work differently than you might expect
- Download folders: each download works in
downloads/incomplete/queue-N(orincomplete/<category folder>/queue-Nfor a torrent with a category) and is imported straight from there. Thedownloads/completefolder is created but not used. - Metrics endpoint:
GET /metrics(and/api/metrics) is for administrators; a Prometheus scrape uses an API key as a bearer token. - Hardlinks and folder mounts: hardlinks only work inside one mounted folder, so the compose file and every platform guide use one
/datamount for downloads, movies and TV. Separate mounts copy files instead. See Install guide. - Install methods: Docker is the only supported install for now. A native Linux program is attached to each release as a preview (there are no Windows or macOS versions; those run the Docker image in Docker Desktop), and the app-store entries are prepared but not submitted (What runs where).
- Backups: the in-app backup is the easy way (Settings > System > Backup and restore). By hand, stop the container first, so no download is writing files while you copy them.
- Tags and folders: tags keep titles apart on your media server (each tag becomes a collection); extra library folders keep them apart on disk. You can use either, or both.
- Optional extras are off until you turn them on: subtitles, music, ebooks and audiobooks, delay profiles, size limits, NFO files, cleanup rules, what's been watched, single sign-on, directory sign-in, IRC announce and import lists all start switched off.
- Trailers: the trailer behind a title page comes from YouTube, so YouTube sees the visit. An administrator can switch it off for everyone.