This PR replaces the APScheduler lib with the Taskiq task queuing lib.
# why
APScheduler doesn't support FastAPI's DI in tasks, this makes them quite
cumbersome to read and write since DB, Repositories and Services all
need to be instanciated manually.
Moreover, Taskiq makes it easier to start background tasks from FastAPI
requests. This enables MM to move to a more event-based architecture.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* App now uses an orchestrated async startup/shutdown and runs
background scheduling via a database-backed task queue; startup enqueues
pre-load/import/update tasks.
* **Bug Fixes**
* Improved torrent client handling with clearer conflict messages and
guidance for manual resolution.
* Enhanced logging around season, episode and metadata update
operations; minor regex/behaviour formatting preserved.
* **Chores**
* Updated dependencies to support the new task queue and connection
pooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Bumps
[@eslint/compat](https://github.com/eslint/rewrite/tree/HEAD/packages/compat)
from 1.4.1 to 2.0.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/releases"><code>@eslint/compat</code>'s
releases</a>.</em></p>
<blockquote>
<h2>compat: v2.0.2</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/compat-v2.0.1...compat-v2.0.2">2.0.2</a>
(2026-01-29)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>add eslint 10 as peer dependency (<a
href="https://redirect.github.com/eslint/rewrite/issues/361">#361</a>)
(<a
href="ecb37dcafc">ecb37dc</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@eslint/core</code> bumped from ^1.0.1 to ^1.1.0</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>migrate-config: v2.0.2</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/migrate-config-v2.0.1...migrate-config-v2.0.2">2.0.2</a>
(2026-01-29)</h2>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@eslint/compat</code> bumped from ^2.0.1 to ^2.0.2</li>
</ul>
</li>
<li>devDependencies
<ul>
<li><code>@eslint/core</code> bumped from ^1.0.1 to ^1.1.0</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>compat: v2.0.1</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/compat-v2.0.0...compat-v2.0.1">2.0.1</a>
(2026-01-08)</h2>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@eslint/core</code> bumped from ^1.0.0 to ^1.0.1</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>migrate-config: v2.0.1</h2>
<h2><a
href="https://github.com/eslint/rewrite/compare/migrate-config-v2.0.0...migrate-config-v2.0.1">2.0.1</a>
(2026-01-08)</h2>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@eslint/compat</code> bumped from ^2.0.0 to ^2.0.1</li>
</ul>
</li>
<li>devDependencies
<ul>
<li><code>@eslint/core</code> bumped from ^1.0.0 to ^1.0.1</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>compat: v2.0.0</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/eslint/rewrite/blob/main/packages/compat/CHANGELOG.md"><code>@eslint/compat</code>'s
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/eslint/rewrite/compare/compat-v2.0.1...compat-v2.0.2">2.0.2</a>
(2026-01-29)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>add eslint 10 as peer dependency (<a
href="https://redirect.github.com/eslint/rewrite/issues/361">#361</a>)
(<a
href="ecb37dcafc">ecb37dc</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@eslint/core</code> bumped from ^1.0.1 to ^1.1.0</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2><a
href="https://github.com/eslint/rewrite/compare/compat-v2.0.0...compat-v2.0.1">2.0.1</a>
(2026-01-08)</h2>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@eslint/core</code> bumped from ^1.0.0 to ^1.0.1</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2><a
href="https://github.com/eslint/rewrite/compare/compat-v1.4.1...compat-v2.0.0">2.0.0</a>
(2025-11-14)</h2>
<h3>⚠ BREAKING CHANGES</h3>
<ul>
<li>Require Node.js ^20.19.0 || ^22.13.0 || >=24 (<a
href="https://redirect.github.com/eslint/rewrite/issues/297">#297</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>patch missing context and SourceCode methods for v10 (<a
href="https://redirect.github.com/eslint/rewrite/issues/311">#311</a>)
(<a
href="a40d8c60af">a40d8c6</a>)</li>
<li>Require Node.js ^20.19.0 || ^22.13.0 || >=24 (<a
href="https://redirect.github.com/eslint/rewrite/issues/297">#297</a>)
(<a
href="acc623c807">acc623c</a>)</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li><code>@eslint/core</code> bumped from ^0.17.0 to ^1.0.0</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7960653fe6"><code>7960653</code></a>
chore: release main (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/compat/issues/356">#356</a>)</li>
<li><a
href="ecb37dcafc"><code>ecb37dc</code></a>
fix: add eslint 10 as peer dependency (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/compat/issues/361">#361</a>)</li>
<li><a
href="074cac2268"><code>074cac2</code></a>
docs: Update README sponsors</li>
<li><a
href="a3b0fd5102"><code>a3b0fd5</code></a>
docs: Update README sponsors</li>
<li><a
href="7abc05147e"><code>7abc051</code></a>
chore: release main (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/compat/issues/336">#336</a>)</li>
<li><a
href="f0b5b68e6d"><code>f0b5b68</code></a>
docs: Update README sponsors</li>
<li><a
href="b65204d085"><code>b65204d</code></a>
docs: Update README sponsors</li>
<li><a
href="5f8bc5b872"><code>5f8bc5b</code></a>
ci: run <code>arethetypeswrong</code> on packages with types (<a
href="https://github.com/eslint/rewrite/tree/HEAD/packages/compat/issues/338">#338</a>)</li>
<li><a
href="d9eb64a30a"><code>d9eb64a</code></a>
docs: Update README sponsors</li>
<li><a
href="7444f36783"><code>7444f36</code></a>
docs: Update README sponsors</li>
<li>Additional commits viewable in <a
href="https://github.com/eslint/rewrite/commits/compat-v2.0.2/packages/compat">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) from 2.0.45
to 2.0.47.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sqlalchemy/sqlalchemy/releases">sqlalchemy's
releases</a>.</em></p>
<blockquote>
<h1>2.0.47</h1>
<p>Released: February 24, 2026</p>
<h2>orm</h2>
<ul>
<li>
<p><strong>[orm] [bug]</strong> Fixed issue when using ORM mappings with
Python 3.14's <a href="https://peps.python.org/pep-0649">PEP 649</a>
feature
that no longer requires "future annotations", where the ORM's
introspection
of the <code>__init__</code> method of mapped classes would fail if
non-present
identifiers in annotations were present. The vendored
<code>getfullargspec()</code>
method has been amended to use <code>Format.FORWARDREF</code> under
Python 3.14 to
prevent resolution of names that aren't present.</p>
<p>References: <a
href="https://www.sqlalchemy.org/trac/ticket/13104">#13104</a></p>
</li>
</ul>
<h2>engine</h2>
<ul>
<li>
<p><strong>[engine] [usecase]</strong> The connection object returned by
<code>_engine.Engine.raw_connection()</code>
now supports the context manager protocol, automatically returning the
connection to the pool when exiting the context.</p>
<p>References: <a
href="https://www.sqlalchemy.org/trac/ticket/13116">#13116</a></p>
</li>
</ul>
<h2>postgresql</h2>
<ul>
<li>
<p><strong>[postgresql] [bug]</strong> Fixed an issue in the PostgreSQL
dialect where foreign key constraint
reflection would incorrectly swap or fail to capture
<code>onupdate</code> and
<code>ondelete</code> values when these clauses appeared in a different
order than
expected in the constraint definition. This issue primarily affected
PostgreSQL-compatible databases such as CockroachDB, which may return
<code>ON DELETE</code> before <code>ON UPDATE</code> in the constraint
definition string. The
reflection logic now correctly parses both clauses regardless of their
ordering.</p>
<p>References: <a
href="https://www.sqlalchemy.org/trac/ticket/13105">#13105</a></p>
</li>
<li>
<p><strong>[postgresql] [bug]</strong> Fixed issue in the
<code>engine_insertmanyvalues</code> feature where using
PostgreSQL's <code>ON CONFLICT</code> clause with
<code>_dml.Insert.returning.sort_by_parameter_order</code> enabled would
generate invalid SQL when the insert used an implicit sentinel
(server-side
autoincrement primary key). The generated SQL would incorrectly declare
a
sentinel counter column in the <code>imp_sen</code> table alias without
providing
corresponding values in the <code>VALUES</code> clause, leading to a
<code>ProgrammingError</code> indicating column count mismatch. The fix
allows batch
execution mode when <code>embed_values_counter</code> is active, as the
embedded
counter provides the ordering capability needed even with upsert
behaviors,
rather than unnecessarily downgrading to row-at-a-time execution.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/sqlalchemy/sqlalchemy/commits">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Fixs for #460
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Improvements**
* Refined keyword matching in indexer queries with case-insensitive,
word-boundary-aware search for more accurate results.
* **Bug Fixes**
* Corrected torrent URL redirect resolution logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The base title scoring rule **avoid_cam** can be extended with more
keyword related to low quality videos similar to CAM.
| Type | Acronyms | Meaning |
|-----------|-------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| CAM | CAM<br>CAMRIP<br>HDCAM | A recording made with a handheld camera
in a movie theater. |
| Screener |
BDSCR<br>DDC<br>DVDSCR<br>DVDSCREENER<br>SCR<br>SCREENER<br>WEBSCREENER
| Screeners are early DVD or BD releases of the theatrical version of a
film, typically sent to movie reviewers, academy members and executives
for review purposes. |
| Telecine | HDTC<br>TC<br>TELECINE | A digital scan of the film print.
|
| Telesync | HDTS<br>TELESYNC<br>TS | Similar to *CAM*, but the camera
is typically placed closer to the projector or on a tripod in the
projection booth. Audio is captured directly from the sound system. |
| TV | TVRIP |
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Chores**
* Improved detection of additional camera-related content format
variants through updated filtering rules.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What
Two-line fix to the quality detection regex in
`media_manager/indexer/schemas.py`.
**UHD pattern**: `\b(4k)\b` → `\b(4k|2160p|uhd)\b`
**FullHD pattern**: `\b(1080p)\b` → `\b(1080p|fullhd|full\s*hd)\b`
## Why
The UHD regex only matched the literal keyword `4k`. Torrent titles
containing `2160p` or `UHD` (but not `4k`) were classified as
`Quality.unknown` (value 5) instead of `Quality.uhd` (value 1). Since
sorting uses quality as the primary key, these 4K releases ended up at
the bottom of search results.
### Example
| Title | Before | After |
|---|---|---|
| `Movie.2013.4K.HDR.2160p.x265` | ✅ `Quality.uhd` | ✅ `Quality.uhd` |
| `Movie.2013.UHD.BluRay.2160p.HDR10.x265` | ❌ `Quality.unknown` | ✅
`Quality.uhd` |
| `Movie.2013.2160p.WEBRip.DDP5.1.x264` | ❌ `Quality.unknown` | ✅
`Quality.uhd` |
All patterns already use `re.IGNORECASE`, so case variants are handled.
Fixes#449
---------
Co-authored-by: GokuPlay609 <GokuPlay609@users.noreply.github.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: maxid <97409287+maxdorninger@users.noreply.github.com>
**Description**
As explained on #322, MediaManager currently only matches torrents that
represent full seasons or season packs.
As a result, valid episode-based releases — commonly returned by
indexers such as EZTV — are filtered out during scoring and never
considered for download.
Initial changes to the season parsing logic allow these torrents to be
discovered.
However, additional changes are required beyond season parsing to
properly support single-episode imports.
This PR is intended as a work-in-progress / RFC to discuss the required
changes and align on the correct approach before completing the
implementation.
**Things planned to do**
[X] Update Web UI to better display episode-level details
[ ] Update TV show import logic to handle single episode files, instead
of assuming full season files (to avoid integrity errors when episodes
are missing)
[ ] Create episode file tables to store episode-level data, similar to
season files
[ ] Implement fetching and downloading logic for single-episode torrents
**Notes / current limitations**
At the moment, the database and import logic assume one file per season
per quality, which works for season packs but not for episode-based
releases.
These changes are intentionally not completed yet and are part of the
discussion this PR aims to start.
**Request for feedback**
This represents a significant change in how TV content is handled in
MediaManager.
Before proceeding further, feedback from @maxdorninger on the overall
direction and next steps would be greatly appreciated.
Once aligned, the remaining tasks can be implemented incrementally.
---------
Co-authored-by: Maximilian Dorninger <97409287+maxdorninger@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Bumps the uv group with 2 updates in the /metadata_relay directory:
[python-multipart](https://github.com/Kludex/python-multipart) and
[urllib3](https://github.com/urllib3/urllib3).
Updates `python-multipart` from 0.0.21 to 0.0.22
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/python-multipart/releases">python-multipart's
releases</a>.</em></p>
<blockquote>
<h2>Version 0.0.22</h2>
<h2>What's Changed</h2>
<ul>
<li>Drop directory path from filename in <code>File</code> <a
href="9433f4bbc9">9433f4b</a>.</li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/Kludex/python-multipart/compare/0.0.21...0.0.22">https://github.com/Kludex/python-multipart/compare/0.0.21...0.0.22</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md">python-multipart's
changelog</a>.</em></p>
<blockquote>
<h2>0.0.22 (2026-01-25)</h2>
<ul>
<li>Drop directory path from filename in <code>File</code> <a
href="9433f4bbc9">9433f4b</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bea7bbb290"><code>bea7bbb</code></a>
Version 0.0.22 (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/222">#222</a>)</li>
<li><a
href="0fb59a9df0"><code>0fb59a9</code></a>
chore: add return type on test (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/221">#221</a>)</li>
<li><a
href="9433f4bbc9"><code>9433f4b</code></a>
Merge commit from fork</li>
<li><a
href="d5c91ecb0a"><code>d5c91ec</code></a>
Bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/219">#219</a>)</li>
<li><a
href="5a90631b48"><code>5a90631</code></a>
bump uv (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/218">#218</a>)</li>
<li>See full diff in <a
href="https://github.com/Kludex/python-multipart/compare/0.0.21...0.0.22">compare
view</a></li>
</ul>
</details>
<br />
Updates `urllib3` from 2.6.2 to 2.6.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/releases">urllib3's
releases</a>.</em></p>
<blockquote>
<h2>2.6.3</h2>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support. If your company or organization uses Python and
would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and
thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Fixed a security issue where decompression-bomb safeguards of the
streaming API were bypassed when HTTP redirects were followed.
(CVE-2026-21441 reported by <a
href="https://github.com/D47A"><code>@D47A</code></a>, 8.9 High,
GHSA-38jv-5279-wg99)</li>
<li>Started treating <code>Retry-After</code> times greater than 6 hours
as 6 hours by default. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3743">urllib3/urllib3#3743</a>)</li>
<li>Fixed <code>urllib3.connection.VerifiedHTTPSConnection</code> on
Emscripten. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3752">urllib3/urllib3#3752</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/blob/main/CHANGES.rst">urllib3's
changelog</a>.</em></p>
<blockquote>
<h1>2.6.3 (2026-01-07)</h1>
<ul>
<li>Fixed a high-severity security issue where decompression-bomb
safeguards of
the streaming API were bypassed when HTTP redirects were followed.
(<code>GHSA-38jv-5279-wg99
<https://github.com/urllib3/urllib3/security/advisories/GHSA-38jv-5279-wg99></code>__)</li>
<li>Started treating <code>Retry-After</code> times greater than 6 hours
as 6 hours by
default. (<code>[#3743](https://github.com/urllib3/urllib3/issues/3743)
<https://github.com/urllib3/urllib3/issues/3743></code>__)</li>
<li>Fixed <code>urllib3.connection.VerifiedHTTPSConnection</code> on
Emscripten.
(<code>[#3752](https://github.com/urllib3/urllib3/issues/3752)
<https://github.com/urllib3/urllib3/issues/3752></code>__)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0248277dd7"><code>0248277</code></a>
Release 2.6.3</li>
<li><a
href="8864ac407b"><code>8864ac4</code></a>
Merge commit from fork</li>
<li><a
href="70cecb27ca"><code>70cecb2</code></a>
Fix Scorecard issues related to vulnerable dev dependencies (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3755">#3755</a>)</li>
<li><a
href="41f249abe1"><code>41f249a</code></a>
Move "v2.0 Migration Guide" to the end of the table of
contents (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3747">#3747</a>)</li>
<li><a
href="fd4dffd2fc"><code>fd4dffd</code></a>
Patch <code>VerifiedHTTPSConnection</code> for Emscripten (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3752">#3752</a>)</li>
<li><a
href="13f0bfd55e"><code>13f0bfd</code></a>
Handle massive values in Retry-After when calculating time to sleep for
(<a
href="https://redirect.github.com/urllib3/urllib3/issues/3743">#3743</a>)</li>
<li><a
href="8c480bf87b"><code>8c480bf</code></a>
Bump actions/upload-artifact from 5.0.0 to 6.0.0 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3748">#3748</a>)</li>
<li><a
href="4b40616e95"><code>4b40616</code></a>
Bump actions/cache from 4.3.0 to 5.0.1 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3750">#3750</a>)</li>
<li><a
href="82b8479663"><code>82b8479</code></a>
Bump actions/download-artifact from 6.0.0 to 7.0.0 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3749">#3749</a>)</li>
<li><a
href="34284cb017"><code>34284cb</code></a>
Mention experimental features in the security policy (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3746">#3746</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/urllib3/urllib3/compare/2.6.2...2.6.3">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/maxdorninger/MediaManager/network/alerts).
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the uv group with 3 updates in the / directory:
[cryptography](https://github.com/pyca/cryptography),
[python-multipart](https://github.com/Kludex/python-multipart) and
[urllib3](https://github.com/urllib3/urllib3).
Updates `cryptography` from 46.0.3 to 46.0.5
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>46.0.5 - 2026-02-10</p>
<pre><code>
* An attacker could create a malicious public key that reveals portions
of your
private key when using certain uncommon elliptic curves (binary curves).
This version now includes additional security checks to prevent this
attack.
This issue only affects binary elliptic curves, which are rarely used in
real-world applications. Credit to **XlabAI Team of Tencent Xuanwu Lab
and
Atuin Automated Vulnerability Discovery Engine** for reporting the
issue.
**CVE-2026-26007**
* Support for ``SECT*`` binary elliptic curves is deprecated and will be
removed in the next release.
<p>.. v46-0-4:</p>
<p>46.0.4 - 2026-01-27<br />
</code></pre></p>
<ul>
<li><code>Dropped support for win_arm64 wheels</code>_.</li>
<li>Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL
3.5.5.</li>
</ul>
<p>.. _v46-0-3:</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="06e120e682"><code>06e120e</code></a>
bump version for 46.0.5 release (<a
href="https://redirect.github.com/pyca/cryptography/issues/14289">#14289</a>)</li>
<li><a
href="0eebb9dbb6"><code>0eebb9d</code></a>
EC check key on cofactor > 1 (<a
href="https://redirect.github.com/pyca/cryptography/issues/14287">#14287</a>)</li>
<li><a
href="bedf6e186b"><code>bedf6e1</code></a>
fix openssl version on 46 branch (<a
href="https://redirect.github.com/pyca/cryptography/issues/14220">#14220</a>)</li>
<li><a
href="e6f44fc8e6"><code>e6f44fc</code></a>
bump for 46.0.4 and drop win arm64 due to CI issues (<a
href="https://redirect.github.com/pyca/cryptography/issues/14217">#14217</a>)</li>
<li>See full diff in <a
href="https://github.com/pyca/cryptography/compare/46.0.3...46.0.5">compare
view</a></li>
</ul>
</details>
<br />
Updates `python-multipart` from 0.0.21 to 0.0.22
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/python-multipart/releases">python-multipart's
releases</a>.</em></p>
<blockquote>
<h2>Version 0.0.22</h2>
<h2>What's Changed</h2>
<ul>
<li>Drop directory path from filename in <code>File</code> <a
href="9433f4bbc9">9433f4b</a>.</li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/Kludex/python-multipart/compare/0.0.21...0.0.22">https://github.com/Kludex/python-multipart/compare/0.0.21...0.0.22</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md">python-multipart's
changelog</a>.</em></p>
<blockquote>
<h2>0.0.22 (2026-01-25)</h2>
<ul>
<li>Drop directory path from filename in <code>File</code> <a
href="9433f4bbc9">9433f4b</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bea7bbb290"><code>bea7bbb</code></a>
Version 0.0.22 (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/222">#222</a>)</li>
<li><a
href="0fb59a9df0"><code>0fb59a9</code></a>
chore: add return type on test (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/221">#221</a>)</li>
<li><a
href="9433f4bbc9"><code>9433f4b</code></a>
Merge commit from fork</li>
<li><a
href="d5c91ecb0a"><code>d5c91ec</code></a>
Bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/219">#219</a>)</li>
<li><a
href="5a90631b48"><code>5a90631</code></a>
bump uv (<a
href="https://redirect.github.com/Kludex/python-multipart/issues/218">#218</a>)</li>
<li>See full diff in <a
href="https://github.com/Kludex/python-multipart/compare/0.0.21...0.0.22">compare
view</a></li>
</ul>
</details>
<br />
Updates `urllib3` from 2.6.2 to 2.6.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/releases">urllib3's
releases</a>.</em></p>
<blockquote>
<h2>2.6.3</h2>
<h2>🚀 urllib3 is fundraising for HTTP/2 support</h2>
<p><a
href="https://sethmlarson.dev/urllib3-is-fundraising-for-http2-support">urllib3
is raising ~$40,000 USD</a> to release HTTP/2 support and ensure
long-term sustainable maintenance of the project after a sharp decline
in financial support. If your company or organization uses Python and
would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and
thousands of other projects <a
href="https://opencollective.com/urllib3">please consider contributing
financially</a> to ensure HTTP/2 support is developed sustainably and
maintained for the long-haul.</p>
<p>Thank you for your support.</p>
<h2>Changes</h2>
<ul>
<li>Fixed a security issue where decompression-bomb safeguards of the
streaming API were bypassed when HTTP redirects were followed.
(CVE-2026-21441 reported by <a
href="https://github.com/D47A"><code>@D47A</code></a>, 8.9 High,
GHSA-38jv-5279-wg99)</li>
<li>Started treating <code>Retry-After</code> times greater than 6 hours
as 6 hours by default. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3743">urllib3/urllib3#3743</a>)</li>
<li>Fixed <code>urllib3.connection.VerifiedHTTPSConnection</code> on
Emscripten. (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3752">urllib3/urllib3#3752</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/urllib3/urllib3/blob/main/CHANGES.rst">urllib3's
changelog</a>.</em></p>
<blockquote>
<h1>2.6.3 (2026-01-07)</h1>
<ul>
<li>Fixed a high-severity security issue where decompression-bomb
safeguards of
the streaming API were bypassed when HTTP redirects were followed.
(<code>GHSA-38jv-5279-wg99
<https://github.com/urllib3/urllib3/security/advisories/GHSA-38jv-5279-wg99></code>__)</li>
<li>Started treating <code>Retry-After</code> times greater than 6 hours
as 6 hours by
default. (<code>[#3743](https://github.com/urllib3/urllib3/issues/3743)
<https://github.com/urllib3/urllib3/issues/3743></code>__)</li>
<li>Fixed <code>urllib3.connection.VerifiedHTTPSConnection</code> on
Emscripten.
(<code>[#3752](https://github.com/urllib3/urllib3/issues/3752)
<https://github.com/urllib3/urllib3/issues/3752></code>__)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0248277dd7"><code>0248277</code></a>
Release 2.6.3</li>
<li><a
href="8864ac407b"><code>8864ac4</code></a>
Merge commit from fork</li>
<li><a
href="70cecb27ca"><code>70cecb2</code></a>
Fix Scorecard issues related to vulnerable dev dependencies (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3755">#3755</a>)</li>
<li><a
href="41f249abe1"><code>41f249a</code></a>
Move "v2.0 Migration Guide" to the end of the table of
contents (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3747">#3747</a>)</li>
<li><a
href="fd4dffd2fc"><code>fd4dffd</code></a>
Patch <code>VerifiedHTTPSConnection</code> for Emscripten (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3752">#3752</a>)</li>
<li><a
href="13f0bfd55e"><code>13f0bfd</code></a>
Handle massive values in Retry-After when calculating time to sleep for
(<a
href="https://redirect.github.com/urllib3/urllib3/issues/3743">#3743</a>)</li>
<li><a
href="8c480bf87b"><code>8c480bf</code></a>
Bump actions/upload-artifact from 5.0.0 to 6.0.0 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3748">#3748</a>)</li>
<li><a
href="4b40616e95"><code>4b40616</code></a>
Bump actions/cache from 4.3.0 to 5.0.1 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3750">#3750</a>)</li>
<li><a
href="82b8479663"><code>82b8479</code></a>
Bump actions/download-artifact from 6.0.0 to 7.0.0 (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3749">#3749</a>)</li>
<li><a
href="34284cb017"><code>34284cb</code></a>
Mention experimental features in the security policy (<a
href="https://redirect.github.com/urllib3/urllib3/issues/3746">#3746</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/urllib3/urllib3/compare/2.6.2...2.6.3">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/maxdorninger/MediaManager/network/alerts).
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [alembic](https://github.com/sqlalchemy/alembic) from 1.17.2 to
1.18.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sqlalchemy/alembic/releases">alembic's
releases</a>.</em></p>
<blockquote>
<h1>1.18.4</h1>
<p>Released: February 10, 2026</p>
<h2>bug</h2>
<ul>
<li>
<p><strong>[bug] [operations]</strong> Reverted the behavior of
<code>Operations.add_column()</code> that would
automatically render the "PRIMARY KEY" keyword inline when a
<code>Column</code> with <code>primary_key=True</code> is added. The
automatic
behavior, added in version 1.18.2, is now opt-in via the new
<code>Operations.add_column.inline_primary_key</code> parameter. This
change restores the ability to render a PostgreSQL SERIAL column, which
is
required to be <code>primary_key=True</code>, while not impacting the
ability to
render a separate primary key constraint. This also provides consistency
with the <code>Operations.add_column.inline_references</code> parameter
and
gives users explicit control over SQL generation.</p>
<p>To render PRIMARY KEY inline, use the
<code>Operations.add_column.inline_primary_key</code> parameter set to
<code>True</code>:</p>
<p>op.add_column(
"my_table",
Column("id", Integer, primary_key=True),
inline_primary_key=True
)References: <a
href="https://redirect.github.com/sqlalchemy/alembic/issues/1232">#1232</a></p>
</li>
</ul>
<h1>1.18.3</h1>
<p>Released: January 29, 2026</p>
<h2>bug</h2>
<ul>
<li>
<p><strong>[bug] [autogenerate]</strong> Fixed regression in version
1.18.0 due to <a
href="https://redirect.github.com/sqlalchemy/alembic/issues/1771">#1771</a>
where autogenerate
would raise <code>NoReferencedTableError</code> when a foreign key
constraint
referenced a table that was not part of the initial table load,
including
tables filtered out by the
<code>EnvironmentContext.configure.include_name</code> callable or
tables
in remote schemas that were not included in the initial reflection
run.</p>
<p>The change in <a
href="https://redirect.github.com/sqlalchemy/alembic/issues/1771">#1771</a>
was a performance optimization that eliminated
additional reflection queries for tables that were only referenced by
foreign keys but not explicitly included in the main reflection run.
However, this optimization inadvertently removed the creation of
<code>Table</code> objects for these referenced tables, causing
autogenerate
to fail when processing foreign key constraints that pointed to
them.</p>
<p>The fix creates placeholder <code>Table</code> objects for foreign
key targets</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/sqlalchemy/alembic/commits">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps
[prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte)
from 3.4.0 to 3.4.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/sveltejs/prettier-plugin-svelte/blob/v3.4.1/CHANGELOG.md">prettier-plugin-svelte's
changelog</a>.</em></p>
<blockquote>
<h2>3.4.1</h2>
<ul>
<li>(fix) externalize all prettier imports</li>
<li>(fix) don't remove parantheses of <code>bind:</code>ings with
<code>as</code> type casts</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/sveltejs/prettier-plugin-svelte/commits/v3.4.1">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps
[@sinclair/typebox](https://github.com/sinclairzx81/typebox-legacy) from
0.34.41 to 0.34.48.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/sinclairzx81/typebox-legacy/commits/0.34.48">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by [GitHub Actions](<a
href="https://www.npmjs.com/~GitHub">https://www.npmjs.com/~GitHub</a>
Actions), a new releaser for <code>@sinclair/typebox</code> since your
current version.</p>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This PR makes the user the container runs as configurable. Before, the
container always tried stepping down (from root) to the mediamanager
user. Now it detects if it's already running as a non-root user and
starts the server directly. Fixes#397
Hi, I've added file names sanitization when saving the torrent file, as
previously the import was failing on torrents with special characters in
names. This fixes#367
Following the discussion in #329 and #115, here's a doc section on using
nix flakes to install MediaManager.
Co-authored-by: lschuetze <lschuetze@mpi-sws.org>
this mostly either removes unused parameters, prefixes them with an
underscore or uses the @override decorator to tell the linter, that that
method comes from a superclass and can't be changed
this mostly adds a timeout=60 to all requests
this does mainly wants a timeout to all requests functions, since when
left out they hang infinitly.
I added a timeout of 60s, which is probably way too high, but since
before this there was none, I guess it's an improvement?
MediaManager is a modern software to manage your TV and movie library. It is designed to be a replacement for Sonarr,
Radarr, Overseer, and Jellyseer.
It supports TVDB and TMDB for metadata, supports OIDC and OAuth 2.0 for authentication and supports Prowlarr and
Jackett.
MediaManager is built first and foremost for deployment with Docker, making it easy to set up.
MediaManager is the modern, easy-to-use successor to the fragmented "Arr" stack. Manage, discover, and automate your TV and movie collection in a single, simple interface.
It also provides an API to interact with the software programmatically, allowing for automation and integration with
MediaManager is the modern, easy-to-use successor to the fragmented "Arr" stack. Manage, discover, and automate your TV and movie collection in a single, simple interface.
@@ -8,9 +8,8 @@ Metadata provider settings are configured in the `[metadata]` section of your `c
TMDB (The Movie Database) is the primary metadata provider for MediaManager. It provides detailed information about movies and TV shows.
{% hint style="info" %}
Other software like Jellyfin use TMDB as well, so there won't be any metadata discrepancies.
{% endhint %}
!!! info
Other software like Jellyfin use TMDB as well, so there won't be any metadata discrepancies.
*`tmdb_relay_url`\
URL of the TMDB relay (MetadataRelay). Default is `https://metadata-relay.dorninger.co/tmdb`. Example: `https://your-own-relay.example.com/tmdb`.
@@ -19,24 +18,21 @@ Other software like Jellyfin use TMDB as well, so there won't be any metadata di
*`default_language`\
TMDB language parameter used when searching and adding. Default is `en`. Format: ISO 639-1 (2 letters).
{% hint style="warning" %}
`default_language` sets the TMDB `language` parameter when searching and adding TV shows and movies. If TMDB does not find a matching translation, metadata in the original language will be fetched with no option for a fallback language. It is therefore highly advised to only use "broad" languages. For most use cases, the default setting is safest.
{% endhint %}
!!! warning
`default_language` sets the TMDB `language` parameter when searching and adding TV shows and movies. If TMDB does not find a matching translation, metadata in the original language will be fetched with no option for a fallback language. It is therefore highly advised to only use "broad" languages. For most use cases, the default setting is safest.
### TVDB Settings (`[metadata.tvdb]`)
{% hint style="warning" %}
The TVDB might provide false metadata and doesn't support some features of MediaManager like showing overviews. Therefore, TMDB is the preferred metadata provider.
{% endhint %}
!!! warning
The TVDB might provide false metadata and doesn't support some features of MediaManager like showing overviews. Therefore, TMDB is the preferred metadata provider.
*`tvdb_relay_url`\
URL of the TVDB relay (MetadataRelay). Default is `https://metadata-relay.dorninger.co/tvdb`. Example: `https://your-own-relay.example.com/tvdb`.
### MetadataRelay
{% hint style="info" %}
To use MediaManager you don't need to set up your own MetadataRelay, as the default relay hosted by the developer should be sufficient for most purposes.
{% endhint %}
!!! info
To use MediaManager you don't need to set up your own MetadataRelay, as the default relay hosted by the developer should be sufficient for most purposes.
The MetadataRelay is a service that provides metadata for MediaManager. It acts as a proxy for TMDB and TVDB, allowing you to use your own API keys if needed, but the default relay means you don't need to create accounts for API keys yourself.
@@ -47,16 +43,14 @@ You might want to use your own relay if you want to avoid rate limits, protect y
* Get a TMDB API key from [The Movie Database](https://www.themoviedb.org/settings/api)
* Get a TVDB API key from [The TVDB](https://thetvdb.com/auth/register)
{% hint style="info" %}
If you want to use your own MetadataRelay, you can set the `tmdb_relay_url` and/or `tvdb_relay_url` to your own relay service.
{% endhint %}
!!! info
If you want to use your own MetadataRelay, you can set the `tmdb_relay_url` and/or `tvdb_relay_url` to your own relay service.
### Example Configuration
Here's a complete example of the metadata section in your `config.toml`:
{% code title="config.toml" %}
```toml
```toml title="config.toml"
[metadata]
# TMDB configuration
[metadata.tmdb]
@@ -66,8 +60,6 @@ Here's a complete example of the metadata section in your `config.toml`:
@@ -9,10 +9,8 @@ Use the following variables to customize behavior:
*`torrents.qbittorrent.category_save_path`\
Save path for the category in qBittorrent. By default, no subdirectory is used. Example: `/data/torrents/MediaManager`.
{% hint style="info" %}
qBittorrent saves torrents to the path specified by `torrents.qbittorrent.category_save_path`, so it must be a valid path that qBittorrent can write to.
{% endhint %}
!!! info
qBittorrent saves torrents to the path specified by `torrents.qbittorrent.category_save_path`, so it must be a valid path that qBittorrent can write to.
{% hint style="warning" %}
For MediaManager to successfully import torrents, you must add the subdirectory to the `misc.torrent_directory` variable.
{% endhint %}
!!! warning
For MediaManager to successfully import torrents, you must add the subdirectory to the `misc.torrent_directory` variable.
@@ -6,23 +6,20 @@ In order to run it on a prefixed path, like `maxdorninger.github.io/media`, the
In short, clone the repository, then run:
{% code title="Build Docker image" %}
```none
```none title="Build Docker image"
docker build \
--build-arg BASE_PATH=/media \
--build-arg VERSION=my-custom-version \
-t MediaManager:my-custom-version \
-f Dockerfile .
```
{% endcode %}
You also need to set the `BASE_PATH` environment variable at runtime in `docker-compose.yaml`:
* `BASE_PATH`\
Base path prefix MediaManager is served under. Example: `/media`. This must match the `BASE_PATH` build arg.
{% code title="docker-compose.yaml (excerpt)" %}
```yaml
```yaml title="docker-compose.yaml (excerpt)"
services:
mediamanager:
image: MediaManager:my-custom-version
@@ -32,10 +29,8 @@ services:
BASE_PATH: /media
...
```
{% endcode %}
{% hint style="info" %}
Make sure to include the base path in the `frontend_url` field in the config file. See [Backend](../configuration/backend.md).
{% endhint %}
!!! info
Make sure to include the base path in the `frontend_url` field in the config file. See [Backend](../configuration/backend.md).
Finally, ensure that whatever reverse proxy you're using leaves the incoming path unchanged; that is, you should not strip the `/media` from `/media/web/`.
So for every config "level", you basically have to take the name of the value and prepend it with the section names in uppercase with 2 underscores as delimiters and `MEDIAMANAGER_` as the prefix.
{% hint style="warning" %}
Note that not every env variable starts with `MEDIAMANAGER_`; this prefix only applies to env variables which replace/overwrite values in the config file. Variables like the `CONFIG_DIR` env variable must not be prefixed.
{% endhint %}
!!! warning
Note that not every env variable starts with `MEDIAMANAGER_`; this prefix only applies to env variables which replace/overwrite values in the config file. Variables like the `CONFIG_DIR` env variable must not be prefixed.
@@ -20,13 +20,11 @@ All authentication settings are configured in the `[auth]` section of your `conf
*`email_password_resets`\
Enables password resets via email. Default is `false`.
{% hint style="info" %}
To use email password resets, you must also configure SMTP settings in the `[notifications.smtp_config]` section.
{% endhint %}
!!! info
To use email password resets, you must also configure SMTP settings in the `[notifications.smtp_config]` section.
{% hint style="info" %}
When setting up MediaManager for the first time, you should add your email to `admin_emails` in the `[auth]` config section. MediaManager will then use this email instead of the default admin email. Your account will automatically be created as an admin account, allowing you to manage other users, media and settings.
{% endhint %}
!!! info
When setting up MediaManager for the first time, you should add your email to `admin_emails` in the `[auth]` config section. MediaManager will then use this email instead of the default admin email. Your account will automatically be created as an admin account, allowing you to manage other users, media and settings.
@@ -127,9 +120,8 @@ You can use special library names in your rulesets:
This allows you to set global rules for all TV or movie content, or provide fallback rules for uncategorized media.
{% hint style="info" %}
You don't need to create lots of libraries with different directories, multiple libraries can share the same directory. You can set multiple (unlimited) libraries to the default directory `/data/movies` or `/data/tv` and use different rulesets with them.
{% endhint %}
!!! info
You don't need to create lots of libraries with different directories, multiple libraries can share the same directory. You can set multiple (unlimited) libraries to the default directory `/data/movies` or `/data/tv` and use different rulesets with them.
The recommended way to install and run Media Manager is using Docker and Docker Compose. Other installation methods are not officially supported, but listed here for convenience.
You probably need to edit the `config.toml` file in the `./config` directory to suit your environment and preferences. [How to configure MediaManager.](configuration/)
{% endstep %}
{% step %}
### Start MediaManager
#### Edit configuration
You probably need to edit the `config.toml` file in the `./config` directory to suit your environment and preferences. [How to configure MediaManager.](../configuration/README.md)
#### Start MediaManager
Bring up the stack:
```bash
docker compose up -d
```
{% endstep %}
{% endstepper %}
* Upon first run, MediaManager will create a default `config.toml` file in the `./config` directory (if not already present).
* Upon first run, MediaManager will also create a default admin user. The credentials of the default admin user will be printed in the logs of the container — it's recommended to change the password of this user after the first login.
* [For more information on the available configuration options, see the Configuration section of the documentation.](configuration/)
* [For more information on the available configuration options, see the Configuration section of the documentation.](../configuration/README.md)
{% hint style="info" %}
When setting up MediaManager for the first time, you should add your email to `admin_emails` in the `[auth]` config section. MediaManager will then use this email instead of the default admin email. Your account will automatically be created as an admin account, allowing you to manage other users, media, and settings.
{% endhint %}
!!! info
When setting up MediaManager for the first time, you should add your email to `admin_emails` in the `[auth]` config section. MediaManager will then use this email instead of the default admin email. Your account will automatically be created as an admin account, allowing you to manage other users, media, and settings.
## MediaManager and MetadataRelay Docker Images
## Docker Images
MediaManager is available as a Docker image on both Red Hat Quay.io and GitHub Container Registry (GHCR):
@@ -70,11 +67,10 @@ MetadataRelay images are also available on both registries:
From v1.12.1 onwards, both MediaManager and MetadataRelay images are available on both Quay.io and GHCR. The reason for the switch to Quay.io as the primary image registry is due to GHCR's continued slow performance: https://github.com/orgs/community/discussions/173607
From v1.12.1 onwards, both MediaManager and MetadataRelay images are available on both Quay.io and GHCR. The reason for the switch to Quay.io as the primary image registry is due to [GHCR's continued slow performance.](https://github.com/orgs/community/discussions/173607)
{% hint style="info" %}
You can use either the Quay.io or GHCR images interchangeably, as they are built from the same source and the tags are the same across both registries.
{% endhint %}
!!! info
You can use either the Quay.io or GHCR images interchangeably, as they are built from the same source and the tags are the same across both registries.
### Tags
@@ -85,4 +81,4 @@ Both registries support the following tags:
* X.Y.Z: Specific version tags (e.g., `1.12.0`).
* X.Y: Points to the latest release in the X.Y series (e.g., `1.12`).
* X: Points to the latest release in the X series (e.g., `1`).
* pr-: Points to the latest commit in the specified pull request (e.g., `pr-67`).
* pr-\<number>: Points to the latest commit in the specified pull request (e.g., `pr-67`).
This is a community contribution and not officially supported by the MediaManager team, but included here for convenience.
*Please report issues with this method at the [corresponding GitHub repository](https://github.com/strangeglyph/mediamanager-nix).*
## Prerequisites
This guide assumes that your system is a flakes-based NixOS installation. Hosting MediaManager on a subpath (e.g. `yourdomain.com/mediamanager`) is currently not supported, though contributions to add support are welcome.
## Importing the community flake
To use the community-provided flake and module, first import it in your own flake, for example:
The flake provides a simple module to set up a MediaManager systemd service. To enable it, set
```nix
{
config={
services.media-manager={
enable=true;
};
};
}
```
You will either want to set `services.media-manager.dataDir`, which will provide sensible defaults for the settings
`misc.{image,movie,tv,torrent}_directory`, or provide specific paths yourself.
The host and port that MediaManager listens on can be set using `services.media-manager.{host,port}`.
To configure MediaManager, use `services.media-manager.settings`, which follows the same structure as the MediaManager
`config.toml`. To provision secrets, set `services.media-manager.environmentFile` to a protected file, for example one
provided by [agenix](https://github.com/ryantm/agenix) or [sops-nix](https://github.com/Mic92/sops-nix).
See [Configuration](../configuration/README.md#configuring-secrets) for guidance on using environment variables.
!!! warning
Do not place secrets in the nix store, as it is world-readable.
## Automatic Postgres Setup
As a convenience feature, the module provides a simple Postgres setup that can be enabled with `services.media-manager.postgres.enable`. This sets up a database user named `services.media-manager.postgres.user` and a database with the same name. Provided the user of the systemd service wasn't changed, authentication should work automatically for unix socket connections (the default mediamanager-nix settings).
For advanced setups, please refer to the NixOS manual.
## Example Configuration
Here is a minimal complete flake for a MediaManager setup:
If you are coming from Radarr or Sonarr you will find that MediaManager does things a bit differently. Instead of completely automatically downloading and managing your media, MediaManager focuses on providing an easy-to-use interface to guide you through the process of finding and downloading media. Advanced features like multiple qualities of a show/movie necessitate such a paradigm shift. So here is a quick step-by-step guide to get you started:
#### Downloading/Requesting a show
{% stepper %}
{% step %}
### Add the show
Add a show on the "Add Show" page. After adding the show you will be redirected to the show's page.
{% endstep %}
{% step %}
### Request season(s)
Click the "Request Season" button on the show's page. Select one or more seasons that you want to download.
{% endstep %}
{% step %}
### Select qualities
Select the "Min Quality" — the minimum resolution of the content to download.\
Select the "Wanted Quality" — the **maximum** resolution of the content to download.
{% endstep %}
{% step %}
### Submit request
Click "Submit request". This is not the last step: an administrator must first approve your request for download. Only after approval will the requested content be downloaded.
{% endstep %}
{% step %}
### Finished
Congratulation! You've downloaded a show (after admin approval).
{% endstep %}
{% endstepper %}
#### Requesting a show (as an admin)
{% stepper %}
{% step %}
### Add the show
Add a show on the "Add Show" page. After adding the show you will be redirected to the show's page.
{% endstep %}
{% step %}
### Request season(s)
Click the "Request Season" button on the show's page. Select one or more seasons that you want to download.
{% endstep %}
{% step %}
### Select qualities
Select the "Min Quality" — the minimum resolution of the content to download.\
Select the "Wanted Quality" — the **maximum** resolution of the content to download.
{% endstep %}
{% step %}
### Submit request (auto-approved)
Click "Submit request". As an admin, your request will be automatically approved.
{% endstep %}
{% step %}
### Finished
Congratulation! You've downloaded a show.
{% endstep %}
{% endstepper %}
#### Downloading a show (admin-only)
You can only directly download a show if you are an admin!
{% stepper %}
{% step %}
### Go to the show's page
Open the show's page that contains the season you wish to download.
{% endstep %}
{% step %}
### Start download
Click the "Download Season" button.
{% endstep %}
{% step %}
### Enter season number
Enter the season number that you want to download.
{% endstep %}
{% step %}
### Optional file path suffix
Optionally select the "File Path Suffix". Note: **it needs to be unique per season per show!**
{% endstep %}
{% step %}
### Choose torrent and download
Click "Download" on the torrent that you want to download.
{% endstep %}
{% step %}
### Finished
Congratulation! You've downloaded a show.
{% endstep %}
{% endstepper %}
#### Managing requests
Users need their requests to be approved by an admin. To manage requests:
{% stepper %}
{% step %}
### Open Requests page
Go to the "Requests" page.
{% endstep %}
{% step %}
### Approve, delete or modify
From the Requests page you can approve, delete, or modify a user's request.
@@ -78,7 +119,7 @@ class IndexerQueryResult(BaseModel):
returnself.size<other.size
def__lt__(self,other)->bool:
def__lt__(self,other:"IndexerQueryResult")->bool:
ifself.quality.value!=other.quality.value:
returnself.quality.value>other.quality.value
ifself.score!=other.score:
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.