Compare commits

...

873 Commits

Author SHA1 Message Date
dependabot[bot]
8da2db42f1 Bump docker/setup-buildx-action from 3 to 4
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-11 16:57:34 +00:00
Maximilian Dorninger
f5253990e0 switch from APScheduler to Taskiq (#461)
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 -->
2026-02-26 21:23:24 +01:00
dependabot[bot]
e529e0c0a3 Bump @eslint/compat from 1.4.1 to 2.0.2 in /web (#465)
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 || &gt;=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 || &gt;=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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@eslint/compat&package-manager=npm_and_yarn&previous-version=1.4.1&new-version=2.0.2)](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>
2026-02-26 21:21:11 +01:00
dependabot[bot]
46a9760376 Bump ruff from 0.14.10 to 0.15.2 (#467)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.14.10 to 0.15.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.15.2</h2>
<h2>Release Notes</h2>
<p>Released on 2026-02-19.</p>
<h3>Preview features</h3>
<ul>
<li>
<p>Expand the default rule set (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23385">#23385</a>)</p>
<p>In preview, Ruff now enables a significantly expanded default rule
set of 412 rules, up from the stable default set of 59 rules. The new
rules are mostly a superset of the stable defaults, with the exception
of these rules, which are removed from the preview defaults:</p>
<ul>
<li><a
href="https://docs.astral.sh/ruff/rules/multiple-imports-on-one-line"><code>multiple-imports-on-one-line</code></a>
(<code>E401</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file"><code>module-import-not-at-top-of-file</code></a>
(<code>E402</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file"><code>module-import-not-at-top-of-file</code></a>
(<code>E701</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/multiple-statements-on-one-line-semicolon"><code>multiple-statements-on-one-line-semicolon</code></a>
(<code>E702</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/useless-semicolon"><code>useless-semicolon</code></a>
(<code>E703</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/none-comparison"><code>none-comparison</code></a>
(<code>E711</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/true-false-comparison"><code>true-false-comparison</code></a>
(<code>E712</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/not-in-test"><code>not-in-test</code></a>
(<code>E713</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/not-is-test"><code>not-is-test</code></a>
(<code>E714</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/type-comparison"><code>type-comparison</code></a>
(<code>E721</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/lambda-assignment"><code>lambda-assignment</code></a>
(<code>E731</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/ambiguous-variable-name"><code>ambiguous-variable-name</code></a>
(<code>E741</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/ambiguous-class-name"><code>ambiguous-class-name</code></a>
(<code>E742</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/ambiguous-function-name"><code>ambiguous-function-name</code></a>
(<code>E743</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/undefined-local-with-import-star"><code>undefined-local-with-import-star</code></a>
(<code>F403</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/undefined-local-with-import-star-usage"><code>undefined-local-with-import-star-usage</code></a>
(<code>F405</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/undefined-local-with-nested-import-star-usage"><code>undefined-local-with-nested-import-star-usage</code></a>
(<code>F406</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/forward-annotation-syntax-error"><code>forward-annotation-syntax-error</code></a>
(<code>F722</code>)</li>
</ul>
<p>If you use preview and prefer the old defaults, you can restore them
with configuration like:</p>
<pre lang="toml"><code>
# ruff.toml
<p>[lint]
select = [&quot;E4&quot;, &quot;E7&quot;, &quot;E9&quot;,
&quot;F&quot;]</p>
<h1>pyproject.toml</h1>
<p>[tool.ruff.lint]
select = [&quot;E4&quot;, &quot;E7&quot;, &quot;E9&quot;, &quot;F&quot;]
</code></pre></p>
<p>If you do give them a try, feel free to share your feedback in the <a
href="https://github.com/astral-sh/ruff/discussions/23203">GitHub
discussion</a>!</p>
</li>
<li>
<p>[<code>flake8-pyi</code>] Also check string annotations
(<code>PYI041</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/19023">#19023</a>)</p>
</li>
</ul>
<h3>Bug fixes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md">ruff's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.2</h2>
<p>Released on 2026-02-19.</p>
<h3>Preview features</h3>
<ul>
<li>
<p>Expand the default rule set (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23385">#23385</a>)</p>
<p>In preview, Ruff now enables a significantly expanded default rule
set of 412
rules, up from the stable default set of 59 rules. The new rules are
mostly a
superset of the stable defaults, with the exception of these rules,
which are
removed from the preview defaults:</p>
<ul>
<li><a
href="https://docs.astral.sh/ruff/rules/multiple-imports-on-one-line"><code>multiple-imports-on-one-line</code></a>
(<code>E401</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file"><code>module-import-not-at-top-of-file</code></a>
(<code>E402</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file"><code>module-import-not-at-top-of-file</code></a>
(<code>E701</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/multiple-statements-on-one-line-semicolon"><code>multiple-statements-on-one-line-semicolon</code></a>
(<code>E702</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/useless-semicolon"><code>useless-semicolon</code></a>
(<code>E703</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/none-comparison"><code>none-comparison</code></a>
(<code>E711</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/true-false-comparison"><code>true-false-comparison</code></a>
(<code>E712</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/not-in-test"><code>not-in-test</code></a>
(<code>E713</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/not-is-test"><code>not-is-test</code></a>
(<code>E714</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/type-comparison"><code>type-comparison</code></a>
(<code>E721</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/lambda-assignment"><code>lambda-assignment</code></a>
(<code>E731</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/ambiguous-variable-name"><code>ambiguous-variable-name</code></a>
(<code>E741</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/ambiguous-class-name"><code>ambiguous-class-name</code></a>
(<code>E742</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/ambiguous-function-name"><code>ambiguous-function-name</code></a>
(<code>E743</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/undefined-local-with-import-star"><code>undefined-local-with-import-star</code></a>
(<code>F403</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/undefined-local-with-import-star-usage"><code>undefined-local-with-import-star-usage</code></a>
(<code>F405</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/undefined-local-with-nested-import-star-usage"><code>undefined-local-with-nested-import-star-usage</code></a>
(<code>F406</code>)</li>
<li><a
href="https://docs.astral.sh/ruff/rules/forward-annotation-syntax-error"><code>forward-annotation-syntax-error</code></a>
(<code>F722</code>)</li>
</ul>
<p>If you use preview and prefer the old defaults, you can restore them
with
configuration like:</p>
<pre lang="toml"><code>
# ruff.toml
<p>[lint]
select = [&quot;E4&quot;, &quot;E7&quot;, &quot;E9&quot;,
&quot;F&quot;]</p>
<h1>pyproject.toml</h1>
<p>[tool.ruff.lint]
select = [&quot;E4&quot;, &quot;E7&quot;, &quot;E9&quot;, &quot;F&quot;]
</code></pre></p>
<p>If you do give them a try, feel free to share your feedback in the <a
href="https://github.com/astral-sh/ruff/discussions/23203">GitHub
discussion</a>!</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9d18ee9115"><code>9d18ee9</code></a>
Hard code workflow name and <code>cancel-in-progress</code> only for PRs
(<a
href="https://redirect.github.com/astral-sh/ruff/issues/23431">#23431</a>)</li>
<li><a
href="7cc15f024b"><code>7cc15f0</code></a>
Bump 0.15.2 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23430">#23430</a>)</li>
<li><a
href="d1b544393a"><code>d1b5443</code></a>
Add extension mapping to configuration file options (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23384">#23384</a>)</li>
<li><a
href="222574af90"><code>222574a</code></a>
Expand the default rule set (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23385">#23385</a>)</li>
<li><a
href="1465b5de38"><code>1465b5d</code></a>
[<code>flake8-async</code>] Fix <code>in_async_context</code> logic (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23426">#23426</a>)</li>
<li><a
href="410902fa40"><code>410902f</code></a>
[<code>pyupgrade</code>] Fix handling of <code>typing.{io,re}</code>
(<code>UP035</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23131">#23131</a>)</li>
<li><a
href="729610acd9"><code>729610a</code></a>
[ty] Fall back to ambiguous for large control flow graphs (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23399">#23399</a>)</li>
<li><a
href="1425c185b0"><code>1425c18</code></a>
[ty] Add code folding support</li>
<li><a
href="97acaaea5f"><code>97acaae</code></a>
[ty] Fix stack overflow for self-referential <code>TypeOf</code> in
annotations (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23407">#23407</a>)</li>
<li><a
href="1f380c8258"><code>1f380c8</code></a>
[ty] Update tests <code>reveal_type</code> and <code>Never</code> (<a
href="https://redirect.github.com/astral-sh/ruff/issues/23418">#23418</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.14.10...0.15.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ruff&package-manager=uv&previous-version=0.14.10&new-version=0.15.2)](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>
2026-02-26 21:20:43 +01:00
dependabot[bot]
8270d1d3ff Bump sqlalchemy from 2.0.45 to 2.0.47 (#471)
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 &quot;future annotations&quot;, 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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=sqlalchemy&package-manager=uv&previous-version=2.0.45&new-version=2.0.47)](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>
2026-02-26 21:20:32 +01:00
dependabot[bot]
6ef200c558 Bump ty from 0.0.9 to 0.0.18 (#470)
Bumps [ty](https://github.com/astral-sh/ty) from 0.0.9 to 0.0.18.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ty/releases">ty's
releases</a>.</em></p>
<blockquote>
<h2>0.0.18</h2>
<h2>Release Notes</h2>
<p>Released on 2026-02-20.</p>
<h3>Bug fixes</h3>
<ul>
<li>Support classes dynamically created via <code>type(...)</code> with
cyclic bases (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22792">#22792</a>)</li>
<li>Fix incorrect types inferred when unpacking mixed tuples (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23437">#23437</a>)</li>
<li>Fix stack overflow for self-referential <code>TypeOf</code> in
annotations (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23407">#23407</a>)</li>
<li>Fix several server panics that could occur when computing semantic
tokens for the current file (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23403">#23403</a>),
<a
href="https://redirect.github.com/astral-sh/ruff/pull/23398">#23398</a>,
<a
href="https://redirect.github.com/astral-sh/ruff/pull/23401">#23401</a>)</li>
</ul>
<h3>LSP server</h3>
<ul>
<li>Add code folding support (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23393">#23393</a>)</li>
<li>Add warning message when running <code>ty server</code>
interactively (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23416">#23416</a>)</li>
<li>Exclude test-related symbols from non-first-party packages in
auto-import completions (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23252">#23252</a>)</li>
<li>Fix bug where diagnostics could disappear after opening an external
file (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23447">#23447</a>)</li>
<li>Remove spurious destination for Go-To Definition on variables
defined in a loop (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23391">#23391</a>)</li>
<li>Use the fully qualified name when &quot;baking&quot; an inlay hint
into the source code if the scope already contains a variable with the
same name as the unqualified name (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23265">#23265</a>)</li>
<li>Resolve TypeVars in <code>call_signature_details</code> parameter
types (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23149">#23149</a>)</li>
</ul>
<h3>CLI</h3>
<ul>
<li>Add <code>--output-format</code> to <code>ty version</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23387">#23387</a>)</li>
</ul>
<h3>Configuration</h3>
<ul>
<li>Add <code>replace-imports-with-any</code> option (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23122">#23122</a>)</li>
<li>Support shellexpand for configuration paths (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23274">#23274</a>)</li>
</ul>
<h3>Type checking</h3>
<ul>
<li>Add a new diagnostic to detect invalid class patterns in
<code>match</code> statements (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22939">#22939</a>)</li>
<li>Allow <code>Self</code> in <code>ClassVar</code> type annotations
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/23362">#23362</a>)</li>
<li>Consider synthesized methods and <code>ClassVar</code>-qualified
declarations when determining whether an abstract method has been
overridden in a subclass (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23381">#23381</a>)</li>
<li>Add a diagnostic when combining <code>Final</code> and
<code>ClassVar</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23365">#23365</a>)</li>
<li>Fix return type of <code>assert_never</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23389">#23389</a>)</li>
<li>Fix <code>assert_type</code> diagnostic messages (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23342">#23342</a>)</li>
<li>Ban PEP-613 type alias values from containing type-qualifier special
forms (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23444">#23444</a>)</li>
<li>Infer <code>LiteralString</code> for <code>f&quot;{literal_str_a}
{literal_str_b}&quot;</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23346">#23346</a>)</li>
<li>Infer precise types for bit-shift operations on integer literals (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23301">#23301</a>)</li>
<li>Make <code>[abstract-method-in-final-class]</code> diagnostics less
verbose for classes with many abstract methods (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23379">#23379</a>)</li>
<li>Improve diagnostics for abstract <code>@final</code> classes (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23376">#23376</a>)</li>
<li>Only perform literal promotion for implicitly inferred literals (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23107">#23107</a>)</li>
<li>Parenthesize callable types when they appear in the return
annotation of other callable types (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23327">#23327</a>)</li>
<li>Consider a call to a generic function returning <code>Never</code>
to terminate control flow (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23419">#23419</a>)</li>
<li>Support calls to intersection types (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22469">#22469</a>)</li>
<li>Validate annotated assignments to attributes on self (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23388">#23388</a>)</li>
<li>Treat a bytes-literal type as a subtype of
<code>Sequence[&lt;constituent integers in the bytestring&gt;]</code>
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/23329">#23329</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ty/blob/main/CHANGELOG.md">ty's
changelog</a>.</em></p>
<blockquote>
<h2>0.0.18</h2>
<p>Released on 2026-02-20.</p>
<h3>Bug fixes</h3>
<ul>
<li>Support classes dynamically created via <code>type(...)</code> with
cyclic bases (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22792">#22792</a>)</li>
<li>Fix incorrect types inferred when unpacking mixed tuples (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23437">#23437</a>)</li>
<li>Fix stack overflow for self-referential <code>TypeOf</code> in
annotations (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23407">#23407</a>)</li>
<li>Fix several server panics that could occur when computing semantic
tokens for the current file (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23403">#23403</a>),
<a
href="https://redirect.github.com/astral-sh/ruff/pull/23398">#23398</a>,
<a
href="https://redirect.github.com/astral-sh/ruff/pull/23401">#23401</a>)</li>
</ul>
<h3>LSP server</h3>
<ul>
<li>Add code folding support (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23393">#23393</a>)</li>
<li>Add warning message when running <code>ty server</code>
interactively (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23416">#23416</a>)</li>
<li>Exclude test-related symbols from non-first-party packages in
auto-import completions (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23252">#23252</a>)</li>
<li>Fix bug where diagnostics could disappear after opening an external
file (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23447">#23447</a>)</li>
<li>Remove spurious destination for Go-To Definition on variables
defined in a loop (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23391">#23391</a>)</li>
<li>Use the fully qualified name when &quot;baking&quot; an inlay hint
into the source code if the scope already contains a variable with the
same name as the unqualified name (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23265">#23265</a>)</li>
<li>Resolve TypeVars in <code>call_signature_details</code> parameter
types (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23149">#23149</a>)</li>
</ul>
<h3>CLI</h3>
<ul>
<li>Add <code>--output-format</code> to <code>ty version</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23387">#23387</a>)</li>
</ul>
<h3>Configuration</h3>
<ul>
<li>Add <code>replace-imports-with-any</code> option (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23122">#23122</a>)</li>
<li>Support shellexpand for configuration paths (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23274">#23274</a>)</li>
</ul>
<h3>Type checking</h3>
<ul>
<li>Add a new diagnostic to detect invalid class patterns in
<code>match</code> statements (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22939">#22939</a>)</li>
<li>Allow <code>Self</code> in <code>ClassVar</code> type annotations
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/23362">#23362</a>)</li>
<li>Consider synthesized methods and <code>ClassVar</code>-qualified
declarations when determining whether an abstract method has been
overridden in a subclass (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23381">#23381</a>)</li>
<li>Add a diagnostic when combining <code>Final</code> and
<code>ClassVar</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23365">#23365</a>)</li>
<li>Fix return type of <code>assert_never</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23389">#23389</a>)</li>
<li>Fix <code>assert_type</code> diagnostic messages (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23342">#23342</a>)</li>
<li>Ban PEP-613 type alias values from containing type-qualifier special
forms (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23444">#23444</a>)</li>
<li>Infer <code>LiteralString</code> for <code>f&quot;{literal_str_a}
{literal_str_b}&quot;</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23346">#23346</a>)</li>
<li>Infer precise types for bit-shift operations on integer literals (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23301">#23301</a>)</li>
<li>Make <code>[abstract-method-in-final-class]</code> diagnostics less
verbose for classes with many abstract methods (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23379">#23379</a>)</li>
<li>Improve diagnostics for abstract <code>@final</code> classes (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23376">#23376</a>)</li>
<li>Only perform literal promotion for implicitly inferred literals (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23107">#23107</a>)</li>
<li>Parenthesize callable types when they appear in the return
annotation of other callable types (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23327">#23327</a>)</li>
<li>Consider a call to a generic function returning <code>Never</code>
to terminate control flow (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23419">#23419</a>)</li>
<li>Support calls to intersection types (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22469">#22469</a>)</li>
<li>Validate annotated assignments to attributes on self (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23388">#23388</a>)</li>
<li>Treat a bytes-literal type as a subtype of
<code>Sequence[&lt;constituent integers in the bytestring&gt;]</code>
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/23329">#23329</a>)</li>
<li>Allow a string-literal argument to match against an
<code>Iterable</code> parameter in type variable inference. (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23326">#23326</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="751672710c"><code>7516727</code></a>
Bump version to 0.0.18 (<a
href="https://redirect.github.com/astral-sh/ty/issues/2869">#2869</a>)</li>
<li><a
href="8e86a5684f"><code>8e86a56</code></a>
Mention code folding on language server feature page</li>
<li><a
href="ca49bf9199"><code>ca49bf9</code></a>
Add shellcheck to pre-commit configuration (<a
href="https://redirect.github.com/astral-sh/ty/issues/2845">#2845</a>)</li>
<li><a
href="532e761e8f"><code>532e761</code></a>
Update PyO3/maturin-action action to v1.50.0 (<a
href="https://redirect.github.com/astral-sh/ty/issues/2823">#2823</a>)</li>
<li><a
href="0211006eb6"><code>0211006</code></a>
Update prek dependencies (<a
href="https://redirect.github.com/astral-sh/ty/issues/2822">#2822</a>)</li>
<li><a
href="60ebbfe853"><code>60ebbfe</code></a>
docs: Add beta status notice to README (<a
href="https://redirect.github.com/astral-sh/ty/issues/2556">#2556</a>)</li>
<li><a
href="31b126a590"><code>31b126a</code></a>
docs: add link for the call hierarchy tracking issue (<a
href="https://redirect.github.com/astral-sh/ty/issues/2816">#2816</a>)</li>
<li><a
href="8cec857182"><code>8cec857</code></a>
[ty] Bump version to 0.0.17 (<a
href="https://redirect.github.com/astral-sh/ty/issues/2806">#2806</a>)</li>
<li><a
href="3650f58ffd"><code>3650f58</code></a>
docs: Clarify that nvim-lspconfig is the recommended way of using ty in
all v...</li>
<li><a
href="55b8ff2055"><code>55b8ff2</code></a>
Add note about fallback behavior to <code>python</code> in
<code>PATH</code> (<a
href="https://redirect.github.com/astral-sh/ty/issues/2787">#2787</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ty/compare/0.0.9...0.0.18">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ty&package-manager=uv&previous-version=0.0.9&new-version=0.0.18)](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>
2026-02-26 21:20:22 +01:00
dependabot[bot]
47d35d4bd7 Bump tailwindcss from 4.2.0 to 4.2.1 in /web (#469)
Bumps
[tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)
from 4.2.0 to 4.2.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">tailwindcss's
releases</a>.</em></p>
<blockquote>
<h2>v4.2.1</h2>
<h3>Fixed</h3>
<ul>
<li>Allow trailing dash in functional utility names for backwards
compatibility (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19696">#19696</a>)</li>
<li>Properly detect classes containing <code>.</code> characters within
curly braces in MDX files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19711">#19711</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">tailwindcss's
changelog</a>.</em></p>
<blockquote>
<h2>[4.2.1] - 2026-02-23</h2>
<h3>Fixed</h3>
<ul>
<li>Allow trailing dash in functional utility names for backwards
compatibility (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19696">#19696</a>)</li>
<li>Properly detect classes containing <code>.</code> characters within
curly braces in MDX files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19711">#19711</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1dce64ee7e"><code>1dce64e</code></a>
4.2.1 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/19714">#19714</a>)</li>
<li><a
href="d15d92ca60"><code>d15d92c</code></a>
Allow trailing dash in functional utility names (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/19696">#19696</a>)</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.2.1/packages/tailwindcss">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=tailwindcss&package-manager=npm_and_yarn&previous-version=4.2.0&new-version=4.2.1)](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>
2026-02-26 21:20:08 +01:00
Juan David Bermudez Celedon
cbd70bd6f3 Fix scoring rules keyword matching (#473)
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 -->
2026-02-26 16:37:29 +01:00
Juan David Bermudez Celedon
d8405fd903 Extend AVOID_CAM scoring rule (#458)
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 -->
2026-02-23 23:21:48 +01:00
Maximilian Dorninger
7824891557 Fix qbittorrent category error (#456)
This PR fixes an error caused by MM trying to set the category save path
to None if the string is empty.
2026-02-22 19:51:10 +01:00
Maximilian Dorninger
a643c9426d remove everything related to requests (#455)
This PR removes the requests feature. The functionality will be replaced
either by Seerr or by reimplementing it in a better way.
2026-02-22 19:46:47 +01:00
GokuPlay609
c2645000e5 fix: improve quality detection regex to match 2160p, UHD, FullHD and other keywords (#450)
## 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>
2026-02-22 16:25:36 +01:00
Maximilian Dorninger
b16f2dce92 migrate season files to episode files and drop legacy table (#454)
This pull request introduces a migration script to transition from
storing file information at the season level to the episode level in the
database.
2026-02-22 16:25:12 +01:00
natarelli22
d8a0ec66c3 Support for handling Single Episode Torrents (#331)
**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>
2026-02-22 15:21:19 +01:00
Maximilian Dorninger
094d0e4eb7 update logo
forgot to update this file
2026-02-21 21:48:37 +01:00
Maximilian Dorninger
4d7f596ffd Rebrand to new MediaManager logo (#452)
I made two new logos because the old one wasn't very recognizable at a
glance.


![1](https://github.com/user-attachments/assets/cb37a709-e80b-4c97-a4d8-cf9ba0dc1613)

![3](https://github.com/user-attachments/assets/c56ded5c-fe15-4c02-bc20-fe2bff06caf9)
2026-02-21 20:29:16 +01:00
dependabot[bot]
300df14c8c Bump svelte from 5.51.0 to 5.53.0 in /web in the npm_and_yarn group across 1 directory (#445)
Bumps the npm_and_yarn group with 1 update in the /web directory:
[svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte).

Updates `svelte` from 5.51.0 to 5.53.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sveltejs/svelte/releases">svelte's
releases</a>.</em></p>
<blockquote>
<h2>svelte@5.53.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p>feat: allow comments in tags (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17671">#17671</a>)</p>
</li>
<li>
<p>feat: allow error boundaries to work on the server (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17672">#17672</a>)</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p>fix: use TrustedHTML to test for customizable <!-- raw HTML omitted
--> support, where necessary (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17743">#17743</a>)</p>
</li>
<li>
<p>fix: ensure head effects are kept in the effect tree (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17746">#17746</a>)</p>
</li>
<li>
<p>chore: deactivate current_batch by default in unset_context (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17738">#17738</a>)</p>
</li>
</ul>
<h2>svelte@5.52.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>feat: support TrustedHTML in <code>{@html}</code> expressions (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17701">#17701</a>)</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p>fix: repair dynamic component truthy/falsy hydration mismatches (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17737">#17737</a>)</p>
</li>
<li>
<p>fix: re-run non-render-bound deriveds on the server (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17674">#17674</a>)</p>
</li>
</ul>
<h2>svelte@5.51.5</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p>fix: check to make sure <code>svelte:element</code> tags are valid
during SSR (<a
href="73098bb26c"><code>73098bb26c6f06e7fd1b0746d817d2c5ee90755f</code></a>)</p>
</li>
<li>
<p>fix: misc option escaping and backwards compatibility (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17741">#17741</a>)</p>
</li>
<li>
<p>fix: strip event handlers during SSR (<a
href="a0c7f28915"><code>a0c7f289156e9fafaeaf5ca14af6c06fe9b9eae5</code></a>)</p>
</li>
<li>
<p>fix: replace usage of <code>for in</code> with <code>for of
Object.keys</code> (<a
href="f89c7ddd7e"><code>f89c7ddd7eebaa1ef3cc540400bec2c9140b330c</code></a>)</p>
</li>
<li>
<p>fix: always escape option body in SSR (<a
href="f7c80da18c"><code>f7c80da18c215e3727c2a611b0b8744cc6e504c5</code></a>)</p>
</li>
<li>
<p>chore: upgrade <code>devalue</code> (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17739">#17739</a>)</p>
</li>
</ul>
<h2>svelte@5.51.4</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p>chore: proactively defer effects in pending boundary (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17734">#17734</a>)</p>
</li>
<li>
<p>fix: detect and error on non-idempotent each block keys in dev mode
(<a
href="https://redirect.github.com/sveltejs/svelte/pull/17732">#17732</a>)</p>
</li>
</ul>
<h2>svelte@5.51.3</h2>
<h3>Patch Changes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md">svelte's
changelog</a>.</em></p>
<blockquote>
<h2>5.53.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p>feat: allow comments in tags (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17671">#17671</a>)</p>
</li>
<li>
<p>feat: allow error boundaries to work on the server (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17672">#17672</a>)</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p>fix: use TrustedHTML to test for customizable
<code>&lt;select&gt;</code> support, where necessary (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17743">#17743</a>)</p>
</li>
<li>
<p>fix: ensure head effects are kept in the effect tree (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17746">#17746</a>)</p>
</li>
<li>
<p>chore: deactivate current_batch by default in unset_context (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17738">#17738</a>)</p>
</li>
</ul>
<h2>5.52.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>feat: support TrustedHTML in <code>{@html}</code> expressions (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17701">#17701</a>)</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p>fix: repair dynamic component truthy/falsy hydration mismatches (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17737">#17737</a>)</p>
</li>
<li>
<p>fix: re-run non-render-bound deriveds on the server (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17674">#17674</a>)</p>
</li>
</ul>
<h2>5.51.5</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p>fix: check to make sure <code>svelte:element</code> tags are valid
during SSR (<a
href="73098bb26c"><code>73098bb26c6f06e7fd1b0746d817d2c5ee90755f</code></a>)</p>
</li>
<li>
<p>fix: misc option escaping and backwards compatibility (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17741">#17741</a>)</p>
</li>
<li>
<p>fix: strip event handlers during SSR (<a
href="a0c7f28915"><code>a0c7f289156e9fafaeaf5ca14af6c06fe9b9eae5</code></a>)</p>
</li>
<li>
<p>fix: replace usage of <code>for in</code> with <code>for of
Object.keys</code> (<a
href="f89c7ddd7e"><code>f89c7ddd7eebaa1ef3cc540400bec2c9140b330c</code></a>)</p>
</li>
<li>
<p>fix: always escape option body in SSR (<a
href="f7c80da18c"><code>f7c80da18c215e3727c2a611b0b8744cc6e504c5</code></a>)</p>
</li>
<li>
<p>chore: upgrade <code>devalue</code> (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17739">#17739</a>)</p>
</li>
</ul>
<h2>5.51.4</h2>
<h3>Patch Changes</h3>
<ul>
<li>chore: proactively defer effects in pending boundary (<a
href="https://redirect.github.com/sveltejs/svelte/pull/17734">#17734</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c2fc95a467"><code>c2fc95a</code></a>
Version Packages (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17747">#17747</a>)</li>
<li><a
href="92e2fc1209"><code>92e2fc1</code></a>
feat: allow comments in tags (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17671">#17671</a>)</li>
<li><a
href="2661513cd3"><code>2661513</code></a>
feat: allow error boundaries to work on the server (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17672">#17672</a>)</li>
<li><a
href="582e4443dc"><code>582e444</code></a>
fix: ensure head effects are kept in the effect tree (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17746">#17746</a>)</li>
<li><a
href="f8bf9bb461"><code>f8bf9bb</code></a>
chore: deactivate current_batch by default in unset_context (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17738">#17738</a>)</li>
<li><a
href="696d97ff3e"><code>696d97f</code></a>
fix: use TrustedHTML to test for customizable &lt;select&gt; support,
where necessa...</li>
<li><a
href="cbf4e246fc"><code>cbf4e24</code></a>
Version Packages (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17742">#17742</a>)</li>
<li><a
href="09c4cb5084"><code>09c4cb5</code></a>
fix: re-run non-render-bound deriveds on the server (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17674">#17674</a>)</li>
<li><a
href="be24b0dca7"><code>be24b0d</code></a>
feat: support TrustedHTML in {<a
href="https://github.com/html"><code>@​html</code></a>} expressions (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17701">#17701</a>)</li>
<li><a
href="9f48e7620f"><code>9f48e76</code></a>
fix: repair dynamic component truthy/falsy hydration mismatches (<a
href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17737">#17737</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/sveltejs/svelte/commits/svelte@5.53.0/packages/svelte">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=svelte&package-manager=npm_and_yarn&previous-version=5.51.0&new-version=5.53.0)](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 <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>
2026-02-20 18:08:06 +01:00
dependabot[bot]
2f102d6c5d Bump the uv group across 1 directory with 2 updates (#446)
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
&lt;https://github.com/urllib3/urllib3/security/advisories/GHSA-38jv-5279-wg99&gt;</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)
&lt;https://github.com/urllib3/urllib3/issues/3743&gt;</code>__)</li>
<li>Fixed <code>urllib3.connection.VerifiedHTTPSConnection</code> on
Emscripten.
(<code>[#3752](https://github.com/urllib3/urllib3/issues/3752)
&lt;https://github.com/urllib3/urllib3/issues/3752&gt;</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 &quot;v2.0 Migration Guide&quot; 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>
2026-02-20 18:07:53 +01:00
dependabot[bot]
3e696c463c Bump the uv group across 1 directory with 3 updates (#448)
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 &gt; 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
&lt;https://github.com/urllib3/urllib3/security/advisories/GHSA-38jv-5279-wg99&gt;</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)
&lt;https://github.com/urllib3/urllib3/issues/3743&gt;</code>__)</li>
<li>Fixed <code>urllib3.connection.VerifiedHTTPSConnection</code> on
Emscripten.
(<code>[#3752](https://github.com/urllib3/urllib3/issues/3752)
&lt;https://github.com/urllib3/urllib3/issues/3752&gt;</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 &quot;v2.0 Migration Guide&quot; 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>
2026-02-20 18:07:39 +01:00
dependabot[bot]
5adb88f9e0 Bump pillow from 12.1.0 to 12.1.1 (#443)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 12.1.0 to
12.1.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/releases">pillow's
releases</a>.</em></p>
<blockquote>
<h2>12.1.1</h2>
<p><a
href="https://pillow.readthedocs.io/en/stable/releasenotes/12.1.1.html">https://pillow.readthedocs.io/en/stable/releasenotes/12.1.1.html</a></p>
<h2>Dependencies</h2>
<ul>
<li>Patch libavif for svt-av1 4.0 compatibility <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9413">#9413</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
</ul>
<h2>Other changes</h2>
<ul>
<li>Fix OOB Write with invalid tile extents <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9427">#9427</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5158d98c80"><code>5158d98</code></a>
12.1.1 version bump</li>
<li><a
href="9000313cc5"><code>9000313</code></a>
Fix OOB Write with invalid tile extents (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/9427">#9427</a>)</li>
<li><a
href="cd0111849f"><code>cd01118</code></a>
Patch libavif for svt-av1 4.0 compatibility</li>
<li>See full diff in <a
href="https://github.com/python-pillow/Pillow/compare/12.1.0...12.1.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pillow&package-manager=uv&previous-version=12.1.0&new-version=12.1.1)](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>
2026-02-20 17:35:11 +01:00
dependabot[bot]
eb277dddac Bump sveltekit-superforms from 2.28.1 to 2.29.1 in /web (#442)
Bumps
[sveltekit-superforms](https://github.com/ciscoheat/sveltekit-superforms)
from 2.28.1 to 2.29.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ciscoheat/sveltekit-superforms/releases">sveltekit-superforms's
releases</a>.</em></p>
<blockquote>
<h2>v2.29.1</h2>
<h3>Fixed</h3>
<ul>
<li>Fixed TypeScript type inference for discriminated unions in
<code>ValidationErrors</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/653">#653</a></li>
<li>Fixed FormData parsing for discriminated unions, so they work
properly without requiring <code>dataType: 'json'</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/655">#655</a></li>
<li><code>reset()</code> function didn't preserve tainted state for
fields that are not being reset when using partial data. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/656">#656</a></li>
<li>Fixed FormData parsing incorrectly coercing empty strings to literal
values (e.g., <code>z.literal(&quot;bar&quot;)</code>). Empty strings
now properly fail validation instead of being replaced with the literal
value. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/664">#664</a></li>
<li>Fixed <code>ReferenceError</code> when using
<code>customValidity</code> with <code>validateForm({ update: true
})</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/669">#669</a></li>
</ul>
<h3>Changed</h3>
<ul>
<li>Replaced deprecated <code>@finom/zod-to-json-schema</code> with
<code>zod-v3-to-json-schema</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/pull/660">#660</a></li>
<li>Migrated Valibot adapter to use the official
<code>@valibot/to-json-schema</code> package. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/pull/668">#668</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ciscoheat/sveltekit-superforms/blob/main/CHANGELOG.md">sveltekit-superforms's
changelog</a>.</em></p>
<blockquote>
<h2>[2.29.1] - 2025-12-16</h2>
<h3>Fixed</h3>
<ul>
<li>Fixed TypeScript type inference for discriminated unions in
<code>ValidationErrors</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/653">#653</a></li>
<li>Fixed FormData parsing for discriminated unions, so they work
properly without requiring <code>dataType: 'json'</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/655">#655</a></li>
<li><code>reset()</code> function didn't preserve tainted state for
fields that are not being reset when using partial data. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/656">#656</a></li>
<li>Fixed FormData parsing incorrectly coercing empty strings to literal
values (e.g., <code>z.literal(&quot;bar&quot;)</code>). Empty strings
now properly fail validation instead of being replaced with the literal
value. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/664">#664</a></li>
<li>Fixed <code>ReferenceError</code> when using
<code>customValidity</code> with <code>validateForm({ update: true
})</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/issues/669">#669</a></li>
</ul>
<h3>Changed</h3>
<ul>
<li>Replaced deprecated <code>@finom/zod-to-json-schema</code> with
<code>zod-v3-to-json-schema</code>. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/pull/660">#660</a></li>
<li>Migrated Valibot adapter to use the official
<code>@valibot/to-json-schema</code> package. <a
href="https://redirect.github.com/ciscoheat/sveltekit-superforms/pull/668">#668</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="22319df44e"><code>22319df</code></a>
2.29.1 changelog</li>
<li><a
href="c1b44308a8"><code>c1b4430</code></a>
2.29.1</li>
<li><a
href="9408124dc9"><code>9408124</code></a>
Incorrect dependency fix</li>
<li><a
href="887aeb6238"><code>887aeb6</code></a>
2.29.0</li>
<li><a
href="ce701fb6fc"><code>ce701fb</code></a>
2.29.0 changelog</li>
<li><a
href="58b41b1e84"><code>58b41b1</code></a>
Linter</li>
<li><a
href="fbbdb90ae7"><code>fbbdb90</code></a>
Fixed build warning</li>
<li><a
href="44a40c6b13"><code>44a40c6</code></a>
Fixed SvelteKit reference warnings</li>
<li><a
href="12bb4d5c32"><code>12bb4d5</code></a>
Using pnpm 10 for build</li>
<li><a
href="f7c87d8898"><code>f7c87d8</code></a>
Package updates</li>
<li>Additional commits viewable in <a
href="https://github.com/ciscoheat/sveltekit-superforms/compare/v2.28.1...v2.29.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=sveltekit-superforms&package-manager=npm_and_yarn&previous-version=2.28.1&new-version=2.29.1)](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>
2026-02-20 17:35:00 +01:00
dependabot[bot]
516d562bd8 Bump uvicorn from 0.40.0 to 0.41.0 (#441)
Bumps [uvicorn](https://github.com/Kludex/uvicorn) from 0.40.0 to
0.41.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/uvicorn/releases">uvicorn's
releases</a>.</em></p>
<blockquote>
<h2>Version 0.41.0</h2>
<h2>Added</h2>
<ul>
<li>Add <code>--limit-max-requests-jitter</code> to stagger worker
restarts (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2707">#2707</a>)</li>
<li>Add socket path to <code>scope[&quot;server&quot;]</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2561">#2561</a>)</li>
</ul>
<h2>Changed</h2>
<ul>
<li>Rename <code>LifespanOn.error_occured</code> to
<code>error_occurred</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2776">#2776</a>)</li>
</ul>
<h2>Fixed</h2>
<ul>
<li>Ignore permission denied errors in watchfiles reloader (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2817">#2817</a>)</li>
<li>Ensure lifespan shutdown runs when <code>should_exit</code> is set
during startup (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2812">#2812</a>)</li>
<li>Reduce the log level of 'request limit exceeded' messages (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2788">#2788</a>)</li>
</ul>
<hr />
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/t-kawasumi"><code>@​t-kawasumi</code></a> made
their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2776">Kludex/uvicorn#2776</a></li>
<li><a href="https://github.com/fardyn"><code>@​fardyn</code></a> made
their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2800">Kludex/uvicorn#2800</a></li>
<li><a href="https://github.com/ewie"><code>@​ewie</code></a> made their
first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2807">Kludex/uvicorn#2807</a></li>
<li><a href="https://github.com/shevron"><code>@​shevron</code></a> made
their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2788">Kludex/uvicorn#2788</a></li>
<li><a href="https://github.com/jonashaag"><code>@​jonashaag</code></a>
made their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2707">Kludex/uvicorn#2707</a></li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/Kludex/uvicorn/compare/0.40.0...0.41.0">https://github.com/Kludex/uvicorn/compare/0.40.0...0.41.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md">uvicorn's
changelog</a>.</em></p>
<blockquote>
<h2>0.41.0 (February 16, 2026)</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--limit-max-requests-jitter</code> to stagger worker
restarts (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2707">#2707</a>)</li>
<li>Add socket path to <code>scope[&quot;server&quot;]</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2561">#2561</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Rename <code>LifespanOn.error_occured</code> to
<code>error_occurred</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2776">#2776</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ignore permission denied errors in watchfiles reloader (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2817">#2817</a>)</li>
<li>Ensure lifespan shutdown runs when <code>should_exit</code> is set
during startup (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2812">#2812</a>)</li>
<li>Reduce the log level of 'request limit exceeded' messages (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2788">#2788</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9283c0f15c"><code>9283c0f</code></a>
Version 0.41.0 (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2821">#2821</a>)</li>
<li><a
href="a01a33eb8f"><code>a01a33e</code></a>
Add <code>--limit-max-requests-jitter</code> to stagger worker restarts
(<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2707">#2707</a>)</li>
<li><a
href="2ce65bde15"><code>2ce65bd</code></a>
Ignore permission denied errors in watchfiles reloader (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2817">#2817</a>)</li>
<li><a
href="654f2ed7d7"><code>654f2ed</code></a>
Ensure lifespan shutdown runs when <code>should_exit</code> is set
during startup (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2812">#2812</a>)</li>
<li><a
href="a03d9f6f0e"><code>a03d9f6</code></a>
Reduce the log level of 'request limit exceeded' messages (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2788">#2788</a>)</li>
<li><a
href="e377de40d0"><code>e377de4</code></a>
Add socket path to scope[&quot;server&quot;] (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2561">#2561</a>)</li>
<li><a
href="0779f7f8a4"><code>0779f7f</code></a>
Poll for readiness in <code>test_multiprocess_health_check</code> and
<code>run_server</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2816">#2816</a>)</li>
<li><a
href="7e9ce2c974"><code>7e9ce2c</code></a>
Poll for PID changes in <code>test_multiprocess_sighup</code> instead of
fixed sleep (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2">#2</a>...</li>
<li><a
href="99f0d8734d"><code>99f0d87</code></a>
Fix grep warning in scripts/sync-version (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2807">#2807</a>)</li>
<li><a
href="7ae2e6375a"><code>7ae2e63</code></a>
chore(deps): bump the python-packages group with 18 updates (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2801">#2801</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/Kludex/uvicorn/compare/0.40.0...0.41.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=uvicorn&package-manager=uv&previous-version=0.40.0&new-version=0.41.0)](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>
2026-02-20 17:34:48 +01:00
dependabot[bot]
dea75841b2 Bump lucide-svelte from 0.564.0 to 0.574.0 in /web (#439)
Bumps
[lucide-svelte](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-svelte)
from 0.564.0 to 0.574.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lucide-icons/lucide/releases">lucide-svelte's
releases</a>.</em></p>
<blockquote>
<h2>Version 0.574.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(icons): changed <code>rocking-chair</code> icon by <a
href="https://github.com/jamiemlaw"><code>@​jamiemlaw</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3445">lucide-icons/lucide#3445</a></li>
<li>fix(icons): flipped <code>coins</code> icon by <a
href="https://github.com/jguddas"><code>@​jguddas</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3158">lucide-icons/lucide#3158</a></li>
<li>feat(icons): added <code>x-line-top</code> icon by <a
href="https://github.com/jguddas"><code>@​jguddas</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2838">lucide-icons/lucide#2838</a></li>
<li>feat(icons): added <code>mouse-left</code> icon by <a
href="https://github.com/marvfash"><code>@​marvfash</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2788">lucide-icons/lucide#2788</a></li>
<li>feat(icons): added <code>mouse-right</code> icon by <a
href="https://github.com/marvfash"><code>@​marvfash</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2787">lucide-icons/lucide#2787</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/marvfash"><code>@​marvfash</code></a>
made their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2788">lucide-icons/lucide#2788</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lucide-icons/lucide/compare/0.572.0...0.574.0">https://github.com/lucide-icons/lucide/compare/0.572.0...0.574.0</a></p>
<h2>Version 0.573.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(icons): changed <code>rocking-chair</code> icon by <a
href="https://github.com/jamiemlaw"><code>@​jamiemlaw</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3445">lucide-icons/lucide#3445</a></li>
<li>fix(icons): flipped <code>coins</code> icon by <a
href="https://github.com/jguddas"><code>@​jguddas</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3158">lucide-icons/lucide#3158</a></li>
<li>feat(icons): added <code>x-line-top</code> icon by <a
href="https://github.com/jguddas"><code>@​jguddas</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2838">lucide-icons/lucide#2838</a></li>
<li>feat(icons): added <code>mouse-left</code> icon by <a
href="https://github.com/marvfash"><code>@​marvfash</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2788">lucide-icons/lucide#2788</a></li>
<li>feat(icons): added <code>mouse-right</code> icon by <a
href="https://github.com/marvfash"><code>@​marvfash</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2787">lucide-icons/lucide#2787</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/marvfash"><code>@​marvfash</code></a>
made their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/2788">lucide-icons/lucide#2788</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lucide-icons/lucide/compare/0.572.0...0.573.0">https://github.com/lucide-icons/lucide/compare/0.572.0...0.573.0</a></p>
<h2>Version 0.572.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(icons): added <code>message-circle-check</code> icon by <a
href="https://github.com/Shrinks99"><code>@​Shrinks99</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3770">lucide-icons/lucide#3770</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Shrinks99"><code>@​Shrinks99</code></a>
made their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3770">lucide-icons/lucide#3770</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lucide-icons/lucide/compare/0.571.0...0.572.0">https://github.com/lucide-icons/lucide/compare/0.571.0...0.572.0</a></p>
<h2>Version 0.571.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(icons): rearange <code>circle</code>-icons path and circle order
by <a
href="https://github.com/adamlindqvist"><code>@​adamlindqvist</code></a>
in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3746">lucide-icons/lucide#3746</a></li>
<li>feat(icons): added <code>shelving-unit</code> icon by <a
href="https://github.com/karsa-mistmere"><code>@​karsa-mistmere</code></a>
in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3041">lucide-icons/lucide#3041</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/adamlindqvist"><code>@​adamlindqvist</code></a>
made their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3746">lucide-icons/lucide#3746</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lucide-icons/lucide/compare/0.570.0...0.571.0">https://github.com/lucide-icons/lucide/compare/0.570.0...0.571.0</a></p>
<h2>Version 0.570.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(icons): added <code>towel-rack</code> icon by <a
href="https://github.com/jguddas"><code>@​jguddas</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3350">lucide-icons/lucide#3350</a></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/lucide-icons/lucide/commits/0.574.0/packages/lucide-svelte">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=lucide-svelte&package-manager=npm_and_yarn&previous-version=0.564.0&new-version=0.574.0)](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>
2026-02-20 17:34:38 +01:00
dependabot[bot]
20e0dbf936 Bump uvicorn from 0.40.0 to 0.41.0 in /metadata_relay (#440)
Bumps [uvicorn](https://github.com/Kludex/uvicorn) from 0.40.0 to
0.41.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/uvicorn/releases">uvicorn's
releases</a>.</em></p>
<blockquote>
<h2>Version 0.41.0</h2>
<h2>Added</h2>
<ul>
<li>Add <code>--limit-max-requests-jitter</code> to stagger worker
restarts (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2707">#2707</a>)</li>
<li>Add socket path to <code>scope[&quot;server&quot;]</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2561">#2561</a>)</li>
</ul>
<h2>Changed</h2>
<ul>
<li>Rename <code>LifespanOn.error_occured</code> to
<code>error_occurred</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2776">#2776</a>)</li>
</ul>
<h2>Fixed</h2>
<ul>
<li>Ignore permission denied errors in watchfiles reloader (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2817">#2817</a>)</li>
<li>Ensure lifespan shutdown runs when <code>should_exit</code> is set
during startup (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2812">#2812</a>)</li>
<li>Reduce the log level of 'request limit exceeded' messages (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2788">#2788</a>)</li>
</ul>
<hr />
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/t-kawasumi"><code>@​t-kawasumi</code></a> made
their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2776">Kludex/uvicorn#2776</a></li>
<li><a href="https://github.com/fardyn"><code>@​fardyn</code></a> made
their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2800">Kludex/uvicorn#2800</a></li>
<li><a href="https://github.com/ewie"><code>@​ewie</code></a> made their
first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2807">Kludex/uvicorn#2807</a></li>
<li><a href="https://github.com/shevron"><code>@​shevron</code></a> made
their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2788">Kludex/uvicorn#2788</a></li>
<li><a href="https://github.com/jonashaag"><code>@​jonashaag</code></a>
made their first contribution in <a
href="https://redirect.github.com/Kludex/uvicorn/pull/2707">Kludex/uvicorn#2707</a></li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/Kludex/uvicorn/compare/0.40.0...0.41.0">https://github.com/Kludex/uvicorn/compare/0.40.0...0.41.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/Kludex/uvicorn/blob/main/docs/release-notes.md">uvicorn's
changelog</a>.</em></p>
<blockquote>
<h2>0.41.0 (February 16, 2026)</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--limit-max-requests-jitter</code> to stagger worker
restarts (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2707">#2707</a>)</li>
<li>Add socket path to <code>scope[&quot;server&quot;]</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2561">#2561</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Rename <code>LifespanOn.error_occured</code> to
<code>error_occurred</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2776">#2776</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ignore permission denied errors in watchfiles reloader (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2817">#2817</a>)</li>
<li>Ensure lifespan shutdown runs when <code>should_exit</code> is set
during startup (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2812">#2812</a>)</li>
<li>Reduce the log level of 'request limit exceeded' messages (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2788">#2788</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9283c0f15c"><code>9283c0f</code></a>
Version 0.41.0 (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2821">#2821</a>)</li>
<li><a
href="a01a33eb8f"><code>a01a33e</code></a>
Add <code>--limit-max-requests-jitter</code> to stagger worker restarts
(<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2707">#2707</a>)</li>
<li><a
href="2ce65bde15"><code>2ce65bd</code></a>
Ignore permission denied errors in watchfiles reloader (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2817">#2817</a>)</li>
<li><a
href="654f2ed7d7"><code>654f2ed</code></a>
Ensure lifespan shutdown runs when <code>should_exit</code> is set
during startup (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2812">#2812</a>)</li>
<li><a
href="a03d9f6f0e"><code>a03d9f6</code></a>
Reduce the log level of 'request limit exceeded' messages (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2788">#2788</a>)</li>
<li><a
href="e377de40d0"><code>e377de4</code></a>
Add socket path to scope[&quot;server&quot;] (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2561">#2561</a>)</li>
<li><a
href="0779f7f8a4"><code>0779f7f</code></a>
Poll for readiness in <code>test_multiprocess_health_check</code> and
<code>run_server</code> (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2816">#2816</a>)</li>
<li><a
href="7e9ce2c974"><code>7e9ce2c</code></a>
Poll for PID changes in <code>test_multiprocess_sighup</code> instead of
fixed sleep (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2">#2</a>...</li>
<li><a
href="99f0d8734d"><code>99f0d87</code></a>
Fix grep warning in scripts/sync-version (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2807">#2807</a>)</li>
<li><a
href="7ae2e6375a"><code>7ae2e63</code></a>
chore(deps): bump the python-packages group with 18 updates (<a
href="https://redirect.github.com/Kludex/uvicorn/issues/2801">#2801</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/Kludex/uvicorn/compare/0.40.0...0.41.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=uvicorn&package-manager=uv&previous-version=0.40.0&new-version=0.41.0)](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>
2026-02-20 17:34:27 +01:00
dependabot[bot]
c8f2a4316e Bump alembic from 1.17.2 to 1.18.4 (#438)
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 &quot;PRIMARY KEY&quot; 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(
&quot;my_table&quot;,
Column(&quot;id&quot;, 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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=alembic&package-manager=uv&previous-version=1.17.2&new-version=1.18.4)](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>
2026-02-20 17:34:15 +01:00
dependabot[bot]
4836e3e188 Bump prettier-plugin-svelte from 3.4.0 to 3.4.1 in /web (#437)
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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier-plugin-svelte&package-manager=npm_and_yarn&previous-version=3.4.0&new-version=3.4.1)](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>
2026-02-20 17:33:54 +01:00
dependabot[bot]
7a6466ea9d Bump @sinclair/typebox from 0.34.41 to 0.34.48 in /web (#436)
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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@sinclair/typebox&package-manager=npm_and_yarn&previous-version=0.34.41&new-version=0.34.48)](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>
2026-02-20 17:33:33 +01:00
Maximilian Dorninger
b427aa5723 Merge pull request #433 from maxdorninger/dependabot/npm_and_yarn/web/npm_and_yarn-e0ba90b5b1
Bump @sveltejs/kit from 2.49.2 to 2.51.0 in /web in the npm_and_yarn group across 1 directory
2026-02-13 19:39:57 +01:00
dependabot[bot]
82aa01a650 Bump @sveltejs/kit in /web in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the /web directory: [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit).


Updates `@sveltejs/kit` from 2.49.2 to 2.51.0
- [Release notes](https://github.com/sveltejs/kit/releases)
- [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.51.0/packages/kit)

---
updated-dependencies:
- dependency-name: "@sveltejs/kit"
  dependency-version: 2.51.0
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 18:25:01 +00:00
Maximilian Dorninger
bc3895ab40 Merge pull request #427 from maxdorninger/dependabot/npm_and_yarn/web/typeschema/class-validator-0.3.0
Bump @typeschema/class-validator from 0.2.0 to 0.3.0 in /web
2026-02-13 19:24:38 +01:00
Maximilian Dorninger
b7ed529f77 Merge pull request #428 from maxdorninger/dependabot/uv/starlette-0.52.1
Bump starlette from 0.50.0 to 0.52.1
2026-02-13 19:24:26 +01:00
Maximilian Dorninger
370df4efa0 Merge pull request #429 from maxdorninger/dependabot/npm_and_yarn/web/vite-7.3.1
Bump vite from 7.2.7 to 7.3.1 in /web
2026-02-13 19:24:12 +01:00
Maximilian Dorninger
a3e85d6338 Merge pull request #431 from maxdorninger/dependabot/npm_and_yarn/web/svelte-5.51.0
Bump svelte from 5.45.8 to 5.51.0 in /web
2026-02-13 19:24:01 +01:00
Maximilian Dorninger
a2816f2dfb Merge pull request #432 from maxdorninger/dependabot/npm_and_yarn/web/lucide-svelte-0.564.0
Bump lucide-svelte from 0.544.0 to 0.564.0 in /web
2026-02-13 19:23:48 +01:00
Maximilian Dorninger
0026b891f5 Merge pull request #430 from maxdorninger/dependabot/uv/cachetools-7.0.1
Bump cachetools from 6.2.4 to 7.0.1
2026-02-13 19:23:34 +01:00
dependabot[bot]
b312d880b7 Bump lucide-svelte from 0.544.0 to 0.564.0 in /web
Bumps [lucide-svelte](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-svelte) from 0.544.0 to 0.564.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.564.0/packages/lucide-svelte)

---
updated-dependencies:
- dependency-name: lucide-svelte
  dependency-version: 0.564.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 18:08:18 +00:00
dependabot[bot]
71e2a08535 Bump svelte from 5.45.8 to 5.51.0 in /web
Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.45.8 to 5.51.0.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/svelte@5.51.0/packages/svelte)

---
updated-dependencies:
- dependency-name: svelte
  dependency-version: 5.51.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 18:08:10 +00:00
dependabot[bot]
f2bf1a2dae Bump cachetools from 6.2.4 to 7.0.1
Bumps [cachetools](https://github.com/tkem/cachetools) from 6.2.4 to 7.0.1.
- [Changelog](https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/tkem/cachetools/compare/v6.2.4...v7.0.1)

---
updated-dependencies:
- dependency-name: cachetools
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 18:08:06 +00:00
dependabot[bot]
6b70980c2a Bump vite from 7.2.7 to 7.3.1 in /web
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.2.7 to 7.3.1.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.1/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 18:08:01 +00:00
dependabot[bot]
e80a516c23 Bump starlette from 0.50.0 to 0.52.1
Bumps [starlette](https://github.com/Kludex/starlette) from 0.50.0 to 0.52.1.
- [Release notes](https://github.com/Kludex/starlette/releases)
- [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md)
- [Commits](https://github.com/Kludex/starlette/compare/0.50.0...0.52.1)

---
updated-dependencies:
- dependency-name: starlette
  dependency-version: 0.52.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 18:07:55 +00:00
dependabot[bot]
280e136209 Bump @typeschema/class-validator from 0.2.0 to 0.3.0 in /web
Bumps [@typeschema/class-validator](https://github.com/decs/typeschema) from 0.2.0 to 0.3.0.
- [Release notes](https://github.com/decs/typeschema/releases)
- [Commits](https://github.com/decs/typeschema/compare/@typeschema/class-validator@0.2.0...@typeschema/class-validator@0.3.0)

---
updated-dependencies:
- dependency-name: "@typeschema/class-validator"
  dependency-version: 0.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 18:07:51 +00:00
maxid
5c62c9f5be Merge remote-tracking branch 'origin/master' 2026-02-13 19:06:44 +01:00
maxid
1e46cdc03b add metadata_relay to dependabot.yml 2026-02-13 19:06:36 +01:00
Maximilian Dorninger
18573fa7d9 Bump actions/setup-python from 5 to 6 (#412)
Bumps [actions/setup-python](https://github.com/actions/setup-python)
from 5 to 6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-python/releases">actions/setup-python's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<h3>Breaking Changes</h3>
<ul>
<li>Upgrade to node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/1164">actions/setup-python#1164</a></li>
</ul>
<p>Make sure your runner is on version v2.327.1 or later to ensure
compatibility with this release. <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">See
Release Notes</a></p>
<h3>Enhancements:</h3>
<ul>
<li>Add support for <code>pip-version</code> by <a
href="https://github.com/priyagupta108"><code>@​priyagupta108</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1129">actions/setup-python#1129</a></li>
<li>Enhance reading from .python-version by <a
href="https://github.com/krystof-k"><code>@​krystof-k</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/787">actions/setup-python#787</a></li>
<li>Add version parsing from Pipfile by <a
href="https://github.com/aradkdj"><code>@​aradkdj</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/1067">actions/setup-python#1067</a></li>
</ul>
<h3>Bug fixes:</h3>
<ul>
<li>Clarify pythonLocation behaviour for PyPy and GraalPy in environment
variables by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1183">actions/setup-python#1183</a></li>
<li>Change missing cache directory error to warning by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1182">actions/setup-python#1182</a></li>
<li>Add Architecture-Specific PATH Management for Python with --user
Flag on Windows by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1122">actions/setup-python#1122</a></li>
<li>Include python version in PyPy python-version output by <a
href="https://github.com/cdce8p"><code>@​cdce8p</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/1110">actions/setup-python#1110</a></li>
<li>Update docs: clarification on pip authentication with setup-python
by <a
href="https://github.com/priya-kinthali"><code>@​priya-kinthali</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1156">actions/setup-python#1156</a></li>
</ul>
<h3>Dependency updates:</h3>
<ul>
<li>Upgrade idna from 2.9 to 3.7 in /<strong>tests</strong>/data by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-python/pull/843">actions/setup-python#843</a></li>
<li>Upgrade form-data to fix critical vulnerabilities <a
href="https://redirect.github.com/actions/setup-python/issues/182">#182</a>
&amp; <a
href="https://redirect.github.com/actions/setup-python/issues/183">#183</a>
by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1163">actions/setup-python#1163</a></li>
<li>Upgrade setuptools to 78.1.1 to fix path traversal vulnerability in
PackageIndex.download by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1165">actions/setup-python#1165</a></li>
<li>Upgrade actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-python/pull/1181">actions/setup-python#1181</a></li>
<li>Upgrade <code>@​actions/tool-cache</code> from 2.0.1 to 2.0.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/setup-python/pull/1095">actions/setup-python#1095</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/krystof-k"><code>@​krystof-k</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-python/pull/787">actions/setup-python#787</a></li>
<li><a href="https://github.com/cdce8p"><code>@​cdce8p</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-python/pull/1110">actions/setup-python#1110</a></li>
<li><a href="https://github.com/aradkdj"><code>@​aradkdj</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-python/pull/1067">actions/setup-python#1067</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v5...v6.0.0">https://github.com/actions/setup-python/compare/v5...v6.0.0</a></p>
<h2>v5.6.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Workflow updates related to Ubuntu 20.04 by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1065">actions/setup-python#1065</a></li>
<li>Fix for Candidate Not Iterable Error by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1082">actions/setup-python#1082</a></li>
<li>Upgrade semver and <code>@​types/semver</code> by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/1091">actions/setup-python#1091</a></li>
<li>Upgrade prettier from 2.8.8 to 3.5.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/1046">actions/setup-python#1046</a></li>
<li>Upgrade ts-jest from 29.1.2 to 29.3.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/1081">actions/setup-python#1081</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v5...v5.6.0">https://github.com/actions/setup-python/compare/v5...v5.6.0</a></p>
<h2>v5.5.0</h2>
<h2>What's Changed</h2>
<h3>Enhancements:</h3>
<ul>
<li>Support free threaded Python versions like '3.13t' by <a
href="https://github.com/colesbury"><code>@​colesbury</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/973">actions/setup-python#973</a></li>
<li>Enhance Workflows: Include ubuntu-arm runners, Add e2e Testing for
free threaded and Upgrade <code>@​action/cache</code> from 4.0.0 to
4.0.3 by <a
href="https://github.com/priya-kinthali"><code>@​priya-kinthali</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1056">actions/setup-python#1056</a></li>
<li>Add support for .tool-versions file in setup-python by <a
href="https://github.com/mahabaleshwars"><code>@​mahabaleshwars</code></a>
in <a
href="https://redirect.github.com/actions/setup-python/pull/1043">actions/setup-python#1043</a></li>
</ul>
<h3>Bug fixes:</h3>
<ul>
<li>Fix architecture for pypy on Linux ARM64 by <a
href="https://github.com/mayeut"><code>@​mayeut</code></a> in <a
href="https://redirect.github.com/actions/setup-python/pull/1011">actions/setup-python#1011</a>
This update maps arm64 to aarch64 for Linux ARM64 PyPy
installations.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a309ff8b42"><code>a309ff8</code></a>
Bump urllib3 from 2.6.0 to 2.6.3 in /<strong>tests</strong>/data (<a
href="https://redirect.github.com/actions/setup-python/issues/1264">#1264</a>)</li>
<li><a
href="bfe8cc55a7"><code>bfe8cc5</code></a>
Upgrade <a href="https://github.com/actions"><code>@​actions</code></a>
dependencies to Node 24 compatible versions (<a
href="https://redirect.github.com/actions/setup-python/issues/1259">#1259</a>)</li>
<li><a
href="4f41a90a1f"><code>4f41a90</code></a>
Bump urllib3 from 2.5.0 to 2.6.0 in /<strong>tests</strong>/data (<a
href="https://redirect.github.com/actions/setup-python/issues/1253">#1253</a>)</li>
<li><a
href="83679a892e"><code>83679a8</code></a>
Bump <code>@​types/node</code> from 24.1.0 to 24.9.1 and update macos-13
to macos-15-intel ...</li>
<li><a
href="bfc4944b43"><code>bfc4944</code></a>
Bump prettier from 3.5.3 to 3.6.2 (<a
href="https://redirect.github.com/actions/setup-python/issues/1234">#1234</a>)</li>
<li><a
href="97aeb3efb8"><code>97aeb3e</code></a>
Bump requests from 2.32.2 to 2.32.4 in /<strong>tests</strong>/data (<a
href="https://redirect.github.com/actions/setup-python/issues/1130">#1130</a>)</li>
<li><a
href="443da59188"><code>443da59</code></a>
Bump actions/publish-action from 0.3.0 to 0.4.0 &amp; Documentation
update for pi...</li>
<li><a
href="cfd55ca824"><code>cfd55ca</code></a>
graalpy: add graalpy early-access and windows builds (<a
href="https://redirect.github.com/actions/setup-python/issues/880">#880</a>)</li>
<li><a
href="bba65e51ff"><code>bba65e5</code></a>
Bump typescript from 5.4.2 to 5.9.3 and update docs/advanced-usage.md
(<a
href="https://redirect.github.com/actions/setup-python/issues/1094">#1094</a>)</li>
<li><a
href="18566f86b3"><code>18566f8</code></a>
Improve wording and &quot;fix example&quot; (remove 3.13) on testing
against pre-releas...</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/setup-python/compare/v5...v6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-python&package-manager=github_actions&previous-version=5&new-version=6)](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>
2026-02-13 19:04:05 +01:00
maxid
6debd7a42d update package-lock.json 2026-02-13 18:54:54 +01:00
dependabot[bot]
cd70ab8711 Bump actions/setup-python from 5 to 6
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 17:08:28 +00:00
Maximilian Dorninger
51b8794e4d Merge pull request #411 from maxdorninger/Dependabot-auto-bump-deps
Configure Dependabot for multiple package ecosystems
2026-02-13 18:07:54 +01:00
Mark Riabov
0cfd1fa724 Fix suffix formatting for with_suffix call (#408)
Fixes issue ValueError: Invalid suffix 'jpg'

Completely prevents downloading posters from metadata provider
2026-02-10 20:29:05 +01:00
Maximilian Dorninger
b5b297e99a add new sponsor syn (#405)
this PR adds the new sponsor syn
2026-02-08 20:10:06 +01:00
maxid
58414cadae update all links to docs 2026-02-08 19:47:17 +01:00
maxid
462794520e update docs workflow 2026-02-08 19:43:13 +01:00
maxid
59afba007d update docs workflow 2026-02-08 19:36:07 +01:00
Maximilian Dorninger
cfa303e4f3 Merge pull request #404 from maxdorninger/mkdocs
This PR replaces Gitbook with Mkdocs to provide documentation
2026-02-08 19:27:15 +01:00
maxid
d3dde9c7eb add docs workflow 2026-02-08 19:22:34 +01:00
maxid
9c94ef6de0 convert gitbook files to mkdocs 2026-02-08 19:16:38 +01:00
Maximilian Dorninger
2665106847 Merge pull request #401 from maxdorninger/fix-env-variables
Fix download clients config being read from env variables
2026-02-08 16:37:15 +01:00
maxid
d029177fc0 hot fix: fix search tag name for episode in jackett 2026-02-04 23:52:07 +01:00
Maximilian Dorninger
1698c404cd Merge pull request #400 from maxdorninger/add-search-by-id-support-to-jackett
Add search by id support to jackett
2026-02-04 23:00:00 +01:00
maxid
abac894a95 fix download clients config being read from env variables without the mediamanager prefix 2026-02-04 22:49:24 +01:00
maxid
12854ff661 format files 2026-02-04 21:34:37 +01:00
maxid
3d52a87302 add id search capabilities to jackett 2026-02-04 21:34:31 +01:00
Maximilian Dorninger
9ee5cc6895 make the container user configurable (#399)
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
2026-02-04 19:01:18 +01:00
Maximilian Dorninger
c45c9e5873 add correlation id to logging (#398)
This PR adds Correlation IDs to logs and request responses.

```
2026-02-04 12:40:32,793 - [afd825081d874d6e835b5c59a6ddb371] DEBUG - media_manager.movies - get_importable_movies(): Found 5 importable movies.
2026-02-04 12:40:32,794 - [afd825081d874d6e835b5c59a6ddb371] INFO - uvicorn.access - send(): 172.19.0.1:64094 - "GET /api/v1/movies/importable HTTP/1.1" 200
2026-02-04 12:40:47,322 - [41d30b7003fd45288c6a4bb1cfba5e7a] INFO - uvicorn.access - send(): 127.0.0.1:52964 - "GET /api/v1/health HTTP/1.1" 200
2026-02-04 12:41:17,408 - [157027ea5dde472a9e620f53739ccd53] INFO - uvicorn.access - send(): 127.0.0.1:39850 - "GET /api/v1/health HTTP/1.1" 200
```
2026-02-04 13:55:05 +01:00
Sergey Khruschak
24fcba6bee Torrent file name sanitizing (#390)
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
2026-02-03 17:09:36 +01:00
Maximilian Dorninger
d5994a9037 Fix docker permission issues (#395)
This PR fixes docker permission issues by first starting as root and
then chown-ing all the volumes. This should fix #388 #389
2026-02-03 13:06:18 +01:00
just_Bri
9e0d0c03c0 feat: add links to media detail pages in requests and torrent tables (#352)
Feature Request: https://github.com/maxdorninger/MediaManager/issues/351

[feat: add links to media detail pages in requests and torrent
tables](ac376c0d6d)
2026-02-02 22:48:14 +01:00
Maximilian Dorninger
70ff8f6ace Fix the broken link to the disable ascii art page (#396)
Fix the broken link to the disable ascii art page
2026-02-02 22:22:11 +01:00
Maximilian Dorninger
e347219721 Merge pull request #394 from juandbc/fix-torznab-process-and-jackett-movies-search
Fix torznab process and jackett movies search
2026-02-02 17:42:49 +01:00
strangeglyph
72a626cb1a Add flag to disable startup ascii art (#369)
Adds an environment variable to disable the colorized splash screen.
2026-02-02 17:39:47 +01:00
Juan David Bermudez Celedon
a1f3f92c10 Enhance size validation for indexer results 2026-02-01 22:14:04 -05:00
Juan David Bermudez Celedon
caaa08fbf4 Fix typo in Jackett log for search_movie 2026-02-01 22:01:42 -05:00
Juan David Bermudez Celedon
5db60141bb Fix bug by typo in jackett log message (#387)
fix typo in the `search_season` function log, which causes an error when searching for torrents.
2026-02-01 18:09:18 +01:00
Marcel Hellwig
96b84d45db Adding some more new lints (#393)
Enable `UP` and `TRY` lint
2026-02-01 18:04:15 +01:00
Marcel Hellwig
311e625eee two hotfixes (#392)
this prevents the app from running correctly
2026-02-01 17:42:15 +01:00
maxidorninger
e22e0394bd GITBOOK-19: No subject 2026-01-09 20:13:39 +00:00
maxid
6377aa8b83 rever "add digital ocean attribution" in GitBook 2026-01-09 21:02:19 +01:00
Maximilian Dorninger
8855204930 add digital ocean attribution (#368) 2026-01-09 20:54:47 +01:00
maxidorninger
7a13326d87 GITBOOK-16: No subject 2026-01-07 19:10:20 +00:00
maxidorninger
15e9cd001f GITBOOK-15: No subject 2026-01-07 18:59:43 +00:00
maxidorninger
e52b84c3c7 GITBOOK-14: No subject 2026-01-07 18:58:37 +00:00
maxidorninger
84a430651f GITBOOK-13: No subject 2026-01-07 18:57:25 +00:00
maxidorninger
463e6914e3 GITBOOK-12: No subject 2026-01-07 18:56:20 +00:00
strangeglyph
e5e85077ae docs: add installation instructions for nix flake (#361)
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>
2026-01-07 19:45:47 +01:00
Maximilian Dorninger
a39e0d204a Ruff enable type annotations rule (#362)
This PR enables the ruff rule for return type annotations (ANN), and
adds the ty package for type checking.
2026-01-06 17:07:19 +01:00
Renan Greca
dd0b439bbe Fix logging bug in jackett indexer (#360)
fix MM trying to access non-existent attribute
2026-01-06 14:49:06 +01:00
Maximilian Dorninger
732b9c0970 make installation guides always link to files of latest release (#359)
make installation guides always link to files of latest release
2026-01-06 11:49:36 +01:00
Maximilian Dorninger
57028991df Merge pull request #341 from hellow554/ruff
enable more Ruff lints
2026-01-05 23:15:38 +01:00
maxid
d5c41430a6 add back hello word message 2026-01-05 23:05:46 +01:00
Maximilian Dorninger
5db3560e9a fix readme 2026-01-05 21:46:12 +01:00
Maximilian Dorninger
13ed291dd4 Revise MediaManager overview (#358)
Updated the description and key features of MediaManager.
2026-01-05 21:44:32 +01:00
Maximilian Dorninger
fd2befd2a1 Migrate to gitbook (#357)
This PR facilities the migration from the old Writerside documentation
platform to Gitbook.

## motivation

Gitbook supports serving multiple versions of the documentation, e.g.
v1.12.1, v1.13.0, and master.
2026-01-05 21:39:18 +01:00
maxidorninger
940c1ea2d1 GITBOOK-10: No subject 2026-01-05 19:41:27 +00:00
maxidorninger
9c7679101f GITBOOK-9: No subject 2026-01-05 19:12:55 +00:00
Marcel Hellwig
75406cbc64 ruff: add RET lint
lints about assign and immediatly returning a variable
2026-01-05 19:30:42 +01:00
Marcel Hellwig
805a6981a6 ruff: enable PTH lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
acd883df21 ruff: enable PIE lint
this just removes needless pass or ...
2026-01-05 19:30:42 +01:00
Marcel Hellwig
f2141ca8b8 ruff: enable PERF lint
this complains a lot about using manual append where a list
comprehension would be more suitable
2026-01-05 19:30:42 +01:00
Marcel Hellwig
7182344036 create list from range directly instead of using append 2026-01-05 19:30:42 +01:00
Marcel Hellwig
a34b0f11a6 use single s since we're ignoring cases anyway 2026-01-05 19:30:42 +01:00
Marcel Hellwig
40812c6040 omit return_type in computed field
it's calculated from the functions return type, so there's no need to
specifify it
2026-01-05 19:30:42 +01:00
Marcel Hellwig
29476e2008 ruff: enable INT and N lint
this renames some files to use snake_case and add Error suffix to custom
exceptions
2026-01-05 19:30:42 +01:00
Marcel Hellwig
29a0d8fe5d ruff: add INP lint
this checks for missing __init__.py files, there was one :)
2026-01-05 19:30:42 +01:00
Marcel Hellwig
55b2dd63d8 ruff: add ARG linter
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
2026-01-05 19:30:42 +01:00
Marcel Hellwig
6e46b482cb ruff: enable A lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
7824828bea ruff: enable T20 lint
and remove a print hello world :)
2026-01-05 19:30:42 +01:00
Marcel Hellwig
5368cad77a ruff: add S linter
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?
2026-01-05 19:30:42 +01:00
Marcel Hellwig
1857cf501c ruff: enable RUF lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
a7bb5e1e04 Make proper use of function overloading
In preparation of the RUFF lint, I rewrote the function to use
typing.overload.
This is the proper way to accept either two arguments or one argument
2026-01-05 19:30:42 +01:00
Marcel Hellwig
ff013ac76e ruff: enable I lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
42502c93fc ruff: enable ISC lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
eac58d2843 ruff: enable FAST lint
this mostly is replacing the response_model attribute with a return type
of that function since that's the more idiomatic way to do
2026-01-05 19:30:42 +01:00
Marcel Hellwig
97cb3b5c1e ruff: enable EM lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
7ef4e52c81 ruff: enable C4 lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
2c36adfd75 ruff: Enable B lint 2026-01-05 19:30:42 +01:00
Marcel Hellwig
0f272052b3 ruff: enable lints that do not complain right now 2026-01-05 19:30:42 +01:00
Marcel Hellwig
0b4b84a4aa add ruff as dev-dependency
since it is mentioned in the development doc, it makes sense to install
it as such
2026-01-05 19:30:34 +01:00
Marcel Hellwig
9ff2dc4b92 rewrite downlaod_post_image function
this now uses the proper functions instead of handling with strings
2026-01-05 19:30:00 +01:00
Marcel Hellwig
593e1828cc remove pillow-avif package
it is possible since 11.3 to use avif in the main pillow package,
therefore the avif package is no longer needed

https://github.com/python-pillow/Pillow/pull/5201#issuecomment-3023668716
2026-01-05 19:29:52 +01:00
Maximilian Dorninger
1b2d99922c Switch to quay and add docker image documentation (#356)
This PR changes all mentions of GHCR to Quay, adds docs about the
registries MM is available on, adds docs about the available docker
image tags, and adds the GHCR permission issue to the troubleshooting
page.
2026-01-05 17:14:32 +01:00
Maximilian Dorninger
e647c99722 Add Contributor Covenant Code of Conduct (#355)
This document outlines the standards of behavior expected from community
members and the consequences for violations.
2026-01-05 13:00:42 +01:00
Maximilian Dorninger
3cd750b882 fix build workflows (#354)
this PR fixes the build workflows, so the QUAY_ORG environment variable
is populated even when run by a PR from a fork
2026-01-05 11:18:51 +01:00
Maximilian Dorninger
87f10e2508 remove old docs (#353)
removes settings which were removed with the v1.12.0 release
2026-01-04 23:44:25 +01:00
Maximilian Dorninger
fc691f95bb fix bugs in MovieService
fix some small bugs in MovieService that were caused by the refactor
2026-01-04 23:37:33 +01:00
Maximilian Dorninger
7e334ffbb1 push docker images to quay.io as well (#346)
This PR adjusts the GH Workflows to also push the container images to
quay.io
2026-01-04 22:31:58 +01:00
Maximilian Dorninger
1f12a7cc3b add sponsor @seferino-fernandez (#343)
add sponsor @seferino-fernandez
2026-01-04 14:47:42 +01:00
Maximilian Dorninger
3ffc28b723 Merge pull request #342 from maxdorninger/maxdorninger-patch-1
Include show year in season search query
2026-01-04 14:35:05 +01:00
Maximilian Dorninger
21495653d2 Include show year in season search query 2026-01-04 14:20:38 +01:00
Maximilian Dorninger
2674d8e018 Merge pull request #339 from maxdorninger/deduplicate-frontend-code
deduplicate code in the download movie/season dialogs
2026-01-03 16:30:20 +01:00
maxid
30ccd0e128 fix torrents title text overflowing 2026-01-03 16:04:38 +01:00
maxid
e6daba279c fix torrents table sorting by always returning a new array 2026-01-03 16:04:21 +01:00
maxid
76d9d47a44 deduplicate code in download movie/season dialogs 2026-01-03 14:54:48 +01:00
Maximilian Dorninger
5caf9169bf Merge pull request #338 from maxdorninger/deduplicate-frontend-code
Organize frontend components into folders
2026-01-03 13:30:01 +01:00
maxid
54b99a67e5 fix import paths 2026-01-03 13:24:25 +01:00
maxid
be3f66c817 move file path suffix components to download dialogs folder 2026-01-03 12:13:42 +01:00
maxid
93711ed1d9 delete unused components 2026-01-03 12:13:13 +01:00
maxid
bd7e9090b2 create torrent components folder 2026-01-03 12:10:24 +01:00
maxid
fc79563be3 create request dialog components folder 2026-01-03 12:08:52 +01:00
maxid
4de6ab9acb create auth components folder 2026-01-03 12:03:33 +01:00
maxid
d9d6f944e8 create nav components folder 2026-01-03 11:56:01 +01:00
maxid
ea30abf1a1 create download dialogs folder 2026-01-03 11:53:29 +01:00
Maximilian Dorninger
6f8e73c90e Merge pull request #334 from hellow554/sort_by_score
allow sorting of torrent search results in web ui
2026-01-02 21:23:11 +01:00
maxid
063072f25c fix: keep column width when no sort is applied 2026-01-02 21:12:45 +01:00
maxid
4ea4275440 change sort indicators to lucid-svelte icons and clean up code 2026-01-02 20:57:40 +01:00
Maximilian Dorninger
d420a2714c Merge pull request #333 from strangeglyph/master
Allow frontend files to be followed through symlinks
2026-01-02 18:00:18 +01:00
maxid
e785b871df add docs 2026-01-02 17:56:05 +01:00
maxid
f144ce1bdf format files after merge 2026-01-02 16:25:41 +01:00
maxid
2d2afaba50 Merge branch 'master' into fork/strangeglyph/master
# Conflicts:
#	media_manager/main.py
2026-01-02 16:24:18 +01:00
maxid
a253ffd946 only accept TRUE 2026-01-02 16:21:58 +01:00
Maximilian Dorninger
3937441e84 Merge pull request #325 from maxdorninger/refactor-code
Refactor code, update dependencies, improve exception handling and more
2026-01-02 15:21:09 +01:00
maxid
4841d1ed11 fix tvdb search not working 2026-01-02 14:38:58 +01:00
Marcel Hellwig
8f6b4ec36c allow sorting of torrent results in web ui 2026-01-02 13:43:16 +01:00
strangeglyph
64f01cc919 Allow frontend files to be followed through symlinks 2026-01-02 12:33:15 +01:00
maxid
edb2001cdc fix tvdb search: use get method for safe access to image_url and overview 2026-01-02 11:13:23 +01:00
maxid
5f7aa928ed remove comment 2026-01-02 11:08:57 +01:00
maxid
88464e76dd remove debug print statement 2026-01-02 11:07:29 +01:00
maxid
02480f1420 fix: add ConflictError exception handler 2026-01-01 21:05:20 +01:00
maxid
3f500eccc6 fix: replace ValueError with ConflictError in movie route 2026-01-01 14:22:19 +01:00
maxid
dd1e5d6621 refactor: update metadata methods to include optional language parameter 2026-01-01 14:21:51 +01:00
maxid
dc7cc98a1a refactor: enhance error handling in check_if_movie_exists method 2026-01-01 14:01:44 +01:00
maxid
a695a5e3ee fix: update image endpoint 2026-01-01 14:01:14 +01:00
maxid
86130f0a6e update dependencies 2025-12-30 00:32:39 +01:00
maxid
e14f19bd45 format files 2025-12-30 00:19:28 +01:00
maxid
7c488e4fae refactor: improve logging and correct directory deletion in service.py 2025-12-30 00:17:45 +01:00
maxid
95c22fa854 Merge branch 'master' into refactor-code
# Conflicts:
#	media_manager/movies/service.py
#	media_manager/tv/service.py
2025-12-30 00:14:24 +01:00
maxid
40130c6a37 refactor: rename AllEncompassingConfig to MediaManagerConfig 2025-12-29 23:38:17 +01:00
maxid
90c2a1d65b refactor: split up main.py into multiple files 2025-12-29 23:37:22 +01:00
maxid
51560ae1e9 refactor: remove unneeded comments 2025-12-29 23:01:34 +01:00
maxid
009f743259 refactor: enhance exception handling 2025-12-29 22:54:45 +01:00
maxid
8de3a71bfd refactor: standardize parameter usage in movie router and service 2025-12-29 22:45:50 +01:00
maxid
35880231e0 refactor: standardize parameter usage in tv router and service 2025-12-29 22:39:39 +01:00
Maximilian Dorninger
d3e12579ac Merge pull request #324 from briandipalma/extra-spaces
fix: only add one space between release year and release ID and fix formatting of dev guide docs
2025-12-29 22:14:14 +01:00
Brian Di Palma
57c94dbd57 feat(importing): Only add one space between release year and release ID 2025-12-29 20:05:51 +00:00
maxid
3c67705275 refactor movie/router.py 2025-12-29 13:17:20 +01:00
maxid
11ff6cd981 reorganize tv/router.py 2025-12-29 13:06:42 +01:00
maxid
499d6a2b3f refactor: update movie handling in router.py to use movie_dep 2025-12-29 12:58:15 +01:00
Maximilian Dorninger
ef0662d584 Merge pull request #323 from maxdorninger/reduce-amount-of-logs
Reduce amount of logs and add log level variable
2025-12-29 12:18:44 +01:00
maxid
63a65c85bd add log level env variable 2025-12-29 11:57:00 +01:00
maxid
4cc4ff3629 refactor: improve logging for deleted torrents in service.py 2025-12-29 11:54:56 +01:00
maxid
9e6851d055 remove unnecessary logs in the torrents module 2025-12-29 11:43:35 +01:00
Maximilian Dorninger
a508b7dabd Merge pull request #320 from maxdorninger/fix-import-success-logic
fix: set success variable when importing movie
2025-12-29 01:01:33 +01:00
maxid
12ce02473d fix: set success variable when importing movie 2025-12-29 00:35:54 +01:00
Maximilian Dorninger
530ff01caf Merge pull request #317 from maxdorninger/improve-indexer-accuracy
Improve indexer accuracy
2025-12-29 00:17:39 +01:00
maxid
1f53f51be7 remove reject_torrents_on_url_error and follow_redirects setting from configuration files 2025-12-29 00:04:48 +01:00
maxid
c2724659d9 improve default scoring rules in config.example.toml 2025-12-28 23:42:18 +01:00
maxid
8b8559a50f format main.py 2025-12-28 23:41:52 +01:00
maxid
4f74a5bee6 improve logging of evaluation of IndexerQueryResults 2025-12-28 23:41:41 +01:00
maxid
7ea1984d6c refactor indexer search: streamline result evaluation by using raw torrent list 2025-12-28 23:41:06 +01:00
maxid
8c380da3b4 refactor logging configuration: use constant for log level 2025-12-28 23:39:14 +01:00
maxid
733c7f78de refactor indexers: add TorznabMixin for improved search result processing and use Torznab Prowlarr endpoint 2025-12-28 23:24:53 +01:00
maxid
0da3e53bcb fix api client context manager 2025-12-28 14:01:54 +01:00
maxid
6993ec8752 fix: use name attribute instead of title 2025-12-28 13:42:21 +01:00
maxid
cf7de07120 fix Dockerfile: ensure recursive ownership for app directory 2025-12-28 11:47:28 +01:00
maxid
91ed5e34dc refactor indexer service: streamline movie and season search methods 2025-12-28 11:20:51 +01:00
maxid
b05c255a53 refactor metadata providers: remove special character removal from search queries 2025-12-28 11:12:58 +01:00
maxid
a29e53bbe5 enhance Prowlarr indexer: add query and type parameters for TV and movie searches 2025-12-28 11:12:26 +01:00
maxid
db54f3b2f2 indexer service: add movie and season search methods 2025-12-28 11:12:13 +01:00
maxid
0a3e7a973f increase max limit of search results 2025-12-27 22:24:46 +01:00
maxid
09cad60673 format files 2025-12-27 22:22:32 +01:00
maxid
b510b1a6e4 enhance Prowlarr indexer: use tmdb, imdb, tvdb id, and season number for searches 2025-12-27 22:22:19 +01:00
maxid
edb6aab77d add abstract search methods for movies and seasons to generic indexer class 2025-12-27 19:59:53 +01:00
maxid
e723fdae96 close import dialog after invalidateAll 2025-12-27 15:26:31 +01:00
Maximilian Dorninger
6eb8979bed Merge pull request #314 from yangqi/fix-non-root-execution
fix: allow container to run as non-root user
2025-12-27 14:40:27 +01:00
Maximilian Dorninger
4763a5a771 Merge pull request #313 from maxdorninger/add-more-metadata-ids
Add IMDb id's
2025-12-27 12:52:03 +01:00
maxid
61fc87e577 fix bug: actually save imdb_id to database 2025-12-27 12:42:36 +01:00
maxid
4cd320a5c2 fix typo in api route 2025-12-27 12:32:11 +01:00
maxid
28e3707e47 fix order of MetadataRelay API routes 2025-12-27 11:09:07 +01:00
Qi
e405c9f8c2 fix: allow container to run as non-root user
- Create mediamanager user and group (UID/GID 1000)
- Set ownership of /app and /data to mediamanager
- Configure uv to use writable cache directory in home
- Set UV_LINK_MODE=copy for better compatibility
- Closes #96
2025-12-23 22:55:03 -08:00
maxid
e4cb7d55cb regenerate code 2025-12-23 20:31:32 +01:00
maxid
9c6676f1f3 feat: add imdb_id parameter to update movie and show methods 2025-12-23 20:29:51 +01:00
maxid
ff3797e1c4 feat: add IMDb ID retrieval for movies and TV shows 2025-12-23 20:24:16 +01:00
maxid
3b920135c2 format files 2025-12-23 19:54:27 +01:00
maxid
0c30ede537 feat: add imdb_id fields to movies and shows 2025-12-23 19:54:17 +01:00
maxid
db37e7373e feat: add external IDs endpoints for TV shows and movies 2025-12-23 19:53:48 +01:00
Maximilian Dorninger
b66410142d Merge pull request #270 from aasmoe/feat/multi-language-metadata
Add Feature: multi language metadata
2025-12-22 20:07:57 +01:00
Maximilian Dorninger
242efa744f Merge pull request #312 from maxdorninger/fix-workflows
fix: extract version number without 'v'
2025-12-22 19:12:45 +01:00
maxid
fabcc26095 fix: extract version number without 'v' prefix in build workflows in order to use correct image tag for inspecting the image 2025-12-22 19:05:11 +01:00
Maximilian Dorninger
e1a7c5fe5d fix login with oauth button not displaying (#311)
fixes oauth button not displaying
2025-12-22 18:50:29 +01:00
aasmoe
688ca8ab9e Update docs with primary_languages and default_language and remove instructions form config example 2025-12-21 21:30:31 +00:00
Maximilian Dorninger
c7c6158a3f disable caching in build and metadata relay workflows (#309)
this pr disables caching in build and metadata relay workflows because it doesn't actually make the workflows any faster.
2025-12-21 20:53:47 +01:00
Maximilian Dorninger
b87a23b5b4 Merge pull request #308 from maxdorninger/display-movie-files
display movie files
2025-12-21 19:37:05 +01:00
maxid
f184def9ad display movie files 2025-12-21 19:24:35 +01:00
Maximilian Dorninger
4e8dbdd128 Merge pull request #302 from maxdorninger/improve-frontend-code-quality
Improve frontend code quality
2025-12-21 19:11:02 +01:00
maxid
cc6e77deb7 move imports to top 2025-12-21 17:04:49 +01:00
maxid
a974a3484b refactor: data handling with derived 2025-12-21 17:03:01 +01:00
maxid
bf84cc0a06 refactor: enhance data invalidation 2025-12-21 16:54:32 +01:00
maxid
7a44463982 convert layout load function into page load function 2025-12-21 16:40:11 +01:00
maxid
0d45eae6e8 remove all occurrences of base 2025-12-21 16:32:31 +01:00
maxid
888186a084 fix handling of state 2025-12-21 16:24:16 +01:00
Maximilian Dorninger
e5efeaddf9 Merge pull request #301 from maxdorninger/maxdorninger-fix-torrent-deletion
Fix torrent deletion logic
2025-12-21 16:19:31 +01:00
maxid
4b7d5eea54 refactor: improve async data fetching in load functions 2025-12-21 16:16:34 +01:00
maxid
9187617530 refactor: improve data handling in show and movie components 2025-12-21 16:06:49 +01:00
maxid
2493b43d4f only start searching for torrents when clicking on search button 2025-12-21 16:01:08 +01:00
maxid
45208105c0 remove unused import 2025-12-21 16:01:05 +01:00
maxid
c56bf705ac use resolve instead of base on about page 2025-12-21 16:00:53 +01:00
maxid
8c584626f1 use resolve instead of base on movie pages 2025-12-21 16:00:53 +01:00
Maximilian Dorninger
2b21915b1f Fix torrent deletion logic 2025-12-21 15:25:42 +01:00
aasmoe
3574a0a08e Merge branch 'master' into feat/multi-language-metadata 2025-12-21 14:43:17 +01:00
Maximilian Dorninger
e21e74a9ea Merge pull request #299 from maxdorninger/add-contributing.md
Create CONTRIBUTING.md for project guidelines
2025-12-21 14:37:17 +01:00
Maximilian Dorninger
4fc033828e Update CONTRIBUTING.md with developer guide link
Added a link to the developer guide for setting up the dev environment.
2025-12-21 14:36:55 +01:00
Maximilian Dorninger
7d7f7b4fd5 Create CONTRIBUTING.md for project guidelines
Added a contributing guide to help users understand how to contribute to the project.
2025-12-21 14:34:47 +01:00
Maximilian Dorninger
e0fdca082c Merge pull request #297 from maxdorninger/improve-importing
Improve importing
2025-12-20 21:39:22 +01:00
maxid
1293cc692c fix: rename source directory before importing existing movies and TV shows 2025-12-20 21:16:52 +01:00
maxid
6b2f426ff9 update docs 2025-12-20 21:10:54 +01:00
maxid
e0a04bb040 fix: filter out non-directory items from import suggestions 2025-12-20 21:01:55 +01:00
Maximilian Dorninger
b854a13338 Update media_manager/torrent/utils.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-20 20:59:28 +01:00
Maximilian Dorninger
5c8cff00a9 Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-20 20:58:06 +01:00
maxid
12fe84017c fix bug: hidden directories included in import suggestions 2025-12-20 20:31:31 +01:00
maxid
ecc030238e fix bug: importable shows saves to importable movies variable 2025-12-20 20:30:33 +01:00
maxid
ed78bde604 reduce logs 2025-12-20 20:22:35 +01:00
maxid
d5c649d5bf refactor search queries to remove special characters and parentheses 2025-12-20 20:05:02 +01:00
maxid
cfe34358a0 refactor title processing to remove special characters and brackets 2025-12-20 20:00:27 +01:00
maxid
1f50b18b9f refactor media detection functions to improve accuracy 2025-12-20 19:37:34 +01:00
maxid
b20d2ed09d update api.d.ts 2025-12-20 14:55:56 +01:00
maxid
eb7a15d32d Merge branch 'refs/heads/master' into fork/aasmoe/feat/multi-language-metadata
# Conflicts:
#	metadata_relay/app/tmdb.py
#	web/src/lib/api/api.d.ts
2025-12-20 14:53:41 +01:00
Maximilian Dorninger
4bb3064779 Merge pull request #294 from maxdorninger/fix-deleted-torrents-leaving-stray-season-files
Fix deleted torrents leaving stray season files
2025-12-20 14:29:47 +01:00
Maximilian Dorninger
edcc238cdd Merge pull request #295 from maxdorninger/direct-indexer-mode
Add option to skip following redirects
2025-12-20 13:15:56 +01:00
maxid
c78bc05627 format files 2025-12-20 13:08:32 +01:00
maxid
bfd9196f5e add support for handling invalid URL schemas and following redirects for torrent downloads 2025-12-20 13:08:05 +01:00
maxid
1cfc90e4ac fix typo 2025-12-19 19:06:49 +01:00
maxid
322b868996 add configuration option to enable following redirects in prowlarr 2025-12-19 19:06:49 +01:00
maxid
2e95798e04 add configuration option to enable following redirects in prowlarr 2025-12-19 19:06:49 +01:00
maxid
1edb2cae9b format files 2025-12-19 18:42:46 +01:00
maxid
bcd1ccfd21 enhance torrent deletion to remove associated media files if the torrent was not imported 2025-12-19 18:42:38 +01:00
Maximilian Dorninger
63ff29f024 Merge pull request #293 from maxdorninger/improve-docs
Improve troubleshooting section of docs
2025-12-19 18:12:55 +01:00
maxid
bfa13762d5 add note about restarting MediaManager for config changes to take effect 2025-12-19 18:08:20 +01:00
maxid
a2462aa964 update formatting of docs and expand on hard linking issues 2025-12-19 18:06:03 +01:00
maxid
7f5363ffb2 add troubleshooting steps for qBittorrent file import issues 2025-12-19 17:58:12 +01:00
maxid
157e8ee77d format frontend code 2025-12-19 16:48:10 +01:00
maxid
c3e9eec5f7 update package-lock.json 2025-12-19 16:47:58 +01:00
Maximilian Dorninger
0443981d5f Merge pull request #278 from xNinjaKittyx/delete_shows_and_movies
Delete shows and movies (and fix lint errors)
2025-12-18 22:17:49 +01:00
Maximilian Dorninger
224644f9af Merge pull request #275 from aasmoe/remove-adult-search-results
Remove adult search results
2025-12-18 22:16:58 +01:00
maxid
32def988ad update package-lock.json 2025-12-18 22:08:43 +01:00
Maximilian Dorninger
a40077a5b1 remove unnecessary check of movie.library 2025-12-18 22:06:16 +01:00
maxid
6ed3c91bde extract delete-media-dialog from movies and shows pages 2025-12-18 22:02:57 +01:00
aasmoe
90dafbd2e5 update package-lock 2025-12-18 11:22:36 +00:00
aasmoe
1afa13a954 Merge branch 'master' into feat/multi-language-metadata 2025-12-18 12:00:54 +01:00
xNinjaKittyx
28915a5484 fix: use the right functions and also make sure the 2 checkboxes are on movies too. 2025-12-16 02:41:04 +00:00
xNinjaKittyx
380de78b51 feature: delete files and torrents. 2025-12-15 21:14:16 +00:00
xNinjaKittyx
796de41fd7 fix: lint 2025-12-15 18:27:41 +00:00
xNinjaKittyx
c1d8810614 fix: change the title 2025-12-15 18:26:07 +00:00
xNinjaKittyx
f4178a7792 fix: not sure how the str wrap came back. 2025-12-15 18:20:16 +00:00
xNinjaKittyx
ec077c7f26 fix: lint and fix wrong text. 2025-12-15 18:18:11 +00:00
xNinjaKittyx
56fa5bed17 fix: fixing some lints. 2025-12-15 18:06:04 +00:00
xNinjaKittyx
18dd20d93e feature: add basic delete capability. 2025-12-15 18:06:04 +00:00
Maximilian Dorninger
d14aae1fa0 Merge pull request #273 from aasmoe/fix/dashboard-svelte5-reactivity
Make recommendations reactive for Svelte 5
2025-12-15 19:01:58 +01:00
Maximilian Dorninger
f71f7f3efd Merge pull request #271 from xNinjaKittyx/various-fixes
Address various different fixes regarding search UI experience.
2025-12-15 19:00:25 +01:00
xNinjaKittyx
db044d9351 fix: change id to movieID/ShowID type. 2025-12-15 17:54:31 +00:00
aasmoe
e12ff1d67b remove include_adult=True from tmdb relay 2025-12-15 09:26:09 +00:00
aasmoe
c1f733dd9b Make recommendations reactive for Svelte 5 2025-12-14 20:32:17 +00:00
xNinjaKittyx
a098b172ca Address various different fixes regarding search UI experience. 2025-12-14 00:10:38 +00:00
aasmoe
5271acb51d Use previous definition of config 2025-12-13 20:53:17 +00:00
aasmoe
b3a10df70c Update config.example.toml 2025-12-13 20:46:25 +00:00
aasmoe
fda59e49b2 Pass language as a value in show and movie objects. DB migration to add original_langauge column. Removes workarounds 2025-12-13 19:30:02 +00:00
aasmoe
8695d26ad9 Removed language parameter in favour of adding original_language to movie and show object. A couple of temporary workaround while there is no original_language column in db. 2025-12-13 19:30:02 +00:00
aasmoe
68f9d71bfa feat: wire up original_language to be passed when adding shows/movies
- Add original_language field to MetaDataProviderSearchResult schema
- Update frontend to pass original_language as language parameter when adding media
- This ensures media metadata is fetched in the correct language based on original_language
2025-12-13 19:30:02 +00:00
aasmoe
1caff77412 WIP: current progress 2025-12-13 19:30:02 +00:00
aasmoe
266d81688c feat: Add multi-language metadata support
- Add primary_languages config setting (ISO 639-1 codes)
- Fetch metadata in original language when in primary_languages
- Display original titles in search results for configured languages
- Download language-specific posters when available
2025-12-13 19:30:02 +00:00
Maximilian Dorninger
53091e7204 Merge pull request #263 from maxdorninger/fix-search-torrents
Fix search torrents
2025-12-12 19:07:46 +01:00
maxid
2a8573a2ba remove wrong Table.Cell tags 2025-12-11 22:53:53 +01:00
maxid
6d025b835d improve download-movie-dialog.svelte 2025-12-11 22:53:30 +01:00
Maximilian Dorninger
c96f5b8f40 Merge pull request #255 from maxdorninger/fix-stats-card-loading
Fix stats card loading
2025-12-10 22:43:34 +01:00
Maximilian Dorninger
c0ef386905 Update web/src/lib/components/stats/animated-card.svelte
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-10 22:40:29 +01:00
maxid
45e934a260 improve stat-cards 2025-12-10 22:06:25 +01:00
maxid
014f239e19 format files 2025-12-10 21:42:30 +01:00
maxid
30a07691a2 improve formating of new version available stat card 2025-12-10 21:41:22 +01:00
maxid
a55c58da2b improve stat loading 2025-12-10 21:41:02 +01:00
maxid
23041cbd09 improve how movies and tv shows are loaded 2025-12-10 21:36:29 +01:00
Maximilian Dorninger
5a274f58b8 Merge pull request #248 from maxdorninger/fix-imports-loading
Fix imports loading
2025-12-10 20:57:08 +01:00
maxid
7fbf80d1fd update build-push-backend.yml 2025-12-10 20:50:49 +01:00
maxid
703c11271d npm update 2025-12-10 20:25:03 +01:00
maxid
4dfb0bbadb update prettier and eslint ignore patterns 2025-12-10 20:12:57 +01:00
maxid
eda1f9c13d update components to fix compile time error 2025-12-10 20:02:25 +01:00
maxid
c37f406074 update how importable media data state is managed 2025-12-10 20:02:02 +01:00
Maximilian Dorninger
2d80198d6c Merge pull request #246 from maxdorninger/increase-timeout
Add timeout config variable
2025-12-10 18:13:08 +01:00
maxid
dda9be13bb fix typos 2025-12-10 18:12:05 +01:00
maxid
c984d40fd3 format code 2025-12-10 17:50:11 +01:00
maxid
8f2f016b61 add timeout to docs 2025-12-10 17:50:04 +01:00
maxid
1ddcef0676 add timeout config value to example configs 2025-12-10 17:15:43 +01:00
maxid
fe3b77a889 add a config variable for jackett and prowlarr to change timeout time 2025-12-10 17:13:24 +01:00
Maximilian Dorninger
51f05c4a8a Fix version display format in stat-cards component 2025-12-10 14:31:11 +01:00
maxid
807ed1b17b forgot to git add new image 2025-12-09 21:07:27 +01:00
Maximilian Dorninger
b7030c4483 Merge pull request #239 from maxdorninger/update-oauth-docs
Update oauth docs
2025-12-09 20:59:50 +01:00
Maximilian Dorninger
647b211ef7 Merge pull request #238 from maxdorninger/fix-logic-for-version-update
Fix "new version available" card to always be displayed
2025-12-09 20:58:10 +01:00
maxid
509c937b0d update authentik example oauth config 2025-12-09 20:57:46 +01:00
maxid
84879600d0 update documentation for oauth 2025-12-09 20:52:31 +01:00
maxid
7f4d73ed9d remove leading 'v' from installed version 2025-12-09 20:42:19 +01:00
Maximilian Dorninger
9c529bd9d0 Replace old screenshots with new ones
Updated screenshots in the README with new images.
2025-12-08 00:49:39 +01:00
Maximilian Dorninger
06dadd29b0 Merge pull request #225 from maxdorninger/remove-unnecessary-logs
Remove unnecessary logs
2025-12-08 00:38:59 +01:00
Maximilian Dorninger
b819d3b1d9 Update media_manager/movies/repository.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 00:38:26 +01:00
Maximilian Dorninger
a603c65fd3 Update media_manager/tv/repository.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 00:38:15 +01:00
Maximilian Dorninger
d479cc84f3 Update media_manager/movies/repository.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 00:37:58 +01:00
Maximilian Dorninger
bed2fe8fa7 Update media_manager/tv/repository.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-08 00:37:27 +01:00
maxid
53fbc703bf reduce logs in routers 2025-12-08 00:32:47 +01:00
maxid
643d2448b1 reduce logs 2025-12-08 00:30:59 +01:00
Maximilian Dorninger
9f6d43d7de Merge pull request #224 from maxdorninger/improve-frontend-for-imports
Improve frontend for imports
2025-12-08 00:05:08 +01:00
maxid
6ab897b899 feat: add importable shows and movies count to stats cards 2025-12-07 23:55:52 +01:00
maxid
1963af4da8 bug fix: use derived instead of state 2025-12-07 23:22:08 +01:00
Maximilian Dorninger
e5c0690470 Merge pull request #220 from maxdorninger/fix-indexers
Make indexers for error resistant
2025-12-07 22:56:53 +01:00
Maximilian Dorninger
5610398e15 Merge pull request #223 from maxdorninger/add-import-of-existing-media
Add feature: import of existing media
2025-12-07 22:56:33 +01:00
Maximilian Dorninger
63f77124cb Update web/src/routes/dashboard/movies/+page.svelte
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-07 22:51:28 +01:00
Maximilian Dorninger
c17efaa306 Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-07 22:50:07 +01:00
Maximilian Dorninger
1d1e678890 Update media_manager/movies/service.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-07 22:45:11 +01:00
Maximilian Dorninger
d680099a0b Update media_manager/tv/service.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-07 22:44:43 +01:00
Maximilian Dorninger
fd457049af Update media_manager/movies/router.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-07 22:43:18 +01:00
maxid
20100441d2 bug fix: make movie importing create necessary directories 2025-12-07 22:24:33 +01:00
maxid
7aabc307c5 add good to know section to docs 2025-12-07 21:13:45 +01:00
maxid
3128c68ecb return error on failed movie import 2025-12-07 21:09:15 +01:00
maxid
417de8b289 save movie_files after successfully importing movies 2025-12-07 21:04:06 +01:00
maxid
c8347f19e9 save season_files after successfully importing tv shows 2025-12-07 21:00:52 +01:00
maxid
2a1bd7199d format frontend files 2025-12-07 20:43:49 +01:00
maxid
9bdb711195 remove unneeded imports 2025-12-07 20:43:03 +01:00
maxid
902f471917 add file criteria to documentation 2025-12-07 20:42:24 +01:00
maxid
161f9ca06a add documentation for import feature 2025-12-07 20:26:39 +01:00
maxid
4c60037a17 add frontend code for movie imports 2025-12-07 19:57:13 +01:00
maxid
d2e8d5eeb7 make movies be importable 2025-12-07 19:56:54 +01:00
maxid
ec93c1abc4 remove argument self 2025-12-07 18:54:57 +01:00
maxid
5cdfb96717 break up movie torrent import function 2025-12-07 18:44:45 +01:00
maxid
b5a7263489 fix bug that prevents notification when multiple video files were found in a movie's directory 2025-12-07 18:32:54 +01:00
maxid
dadd850524 extract functions and schemas from tv module 2025-12-07 18:30:23 +01:00
maxid
1f7dd795d1 remove year at the end of directory name in order to improve search results 2025-12-07 18:04:01 +01:00
maxid
087f4b9f15 prefix imported directories with a dot and ignore such directories 2025-12-07 17:55:32 +01:00
maxid
13b32e7104 add ability to import unknown tv shows 2025-12-07 17:38:37 +01:00
maxid
aca60cd9b7 make explicit any only warn instead of error 2025-12-07 17:37:10 +01:00
maxid
bfe4b05ca3 add spinner component 2025-12-07 17:36:45 +01:00
maxid
d65e00206d fix bug that causes saving of notifications to fail 2025-12-07 17:22:18 +01:00
maxid
247a562f7b remove stray code from notification schemas 2025-12-07 17:15:41 +01:00
maxid
9bbd6ee6df add show_id part to route 2025-12-07 17:13:56 +01:00
maxid
64bcd85287 make add_show endpoint always return the show 2025-12-07 16:05:10 +01:00
maxid
579ceb6e87 remove response model from route which doe not return anything 2025-12-07 15:31:29 +01:00
maxid
fdaaf099cb add ability to import existing media 2025-12-07 15:29:03 +01:00
Maximilian Dorninger
8e719ef94f Merge pull request #222 from maxdorninger/hotfix-fix-frontend-url
fix bug where extra slash is appended to the frontend_url
2025-12-07 00:52:45 +01:00
Maximilian Dorninger
1b03a57c3e Merge pull request #221 from maxdorninger/add-stats-to-dashboard
Add stats to dashboard
2025-12-07 00:29:40 +01:00
maxid
1f60db20f3 fix bug where extra slash is appended to the frontend_url, causing oauth to not work 2025-12-07 00:29:17 +01:00
maxid
5200821b60 update formatting of welcome message 2025-12-07 00:23:16 +01:00
maxid
92b9bff892 update package-lock.json 2025-12-06 23:49:40 +01:00
maxid
30f5ecd997 make eslint svelte resolve rule only warn 2025-12-06 23:33:53 +01:00
maxid
e117bed738 make counters animated with animejs 2025-12-06 23:33:03 +01:00
maxid
961c89e4e2 format frontend files 2025-12-06 22:39:09 +01:00
maxid
d1eee14b79 add card to inform user of new versions 2025-12-06 22:38:28 +01:00
maxid
e522fa9801 add stats to dashboard 2025-12-06 21:05:13 +01:00
maxid
11cafa800a add route which returns the total count of all episodes 2025-12-06 21:04:58 +01:00
maxid
bdeb60ab30 add default node url to cors urls of dev config 2025-12-06 19:49:47 +01:00
maxid
24b735439c move logfile to /dev/null to stop backend from reloading because of changes in the logfile 2025-12-06 19:37:44 +01:00
maxid
4eb78bd495 add healthcheck to db container in docker-compose.dev.yaml 2025-12-06 19:00:22 +01:00
maxid
751c4558a2 refactor and improve prowlarr search result processing 2025-12-06 15:57:51 +01:00
maxid
d8948e4462 make jackett torrent search more error resistant 2025-12-06 15:48:50 +01:00
maxid
0554fee85f make prowlarr torrent search more error resistant 2025-12-06 15:48:50 +01:00
Maximilian Dorninger
ffb86324c4 Merge pull request #219 from maxdorninger/copilot/add-user-delete-feature
Add ability to delete users
2025-11-29 18:22:34 +01:00
copilot-swe-agent[bot]
83932d6c99 Add delete button for user management in admin settings
Co-authored-by: maxdorninger <97409287+maxdorninger@users.noreply.github.com>
2025-11-29 16:59:45 +00:00
copilot-swe-agent[bot]
9e76fc9b8b Initial plan 2025-11-29 16:51:12 +00:00
Maximilian Dorninger
a36b161a38 Merge pull request #218 from maxdorninger/add-sponsor
add new sponsor @PuppiestDoggo
2025-11-29 17:38:43 +01:00
maxDorninger
3ac8b7588a add new sponsor @PuppiestDoggo 2025-11-29 17:34:23 +01:00
Maximilian Dorninger
c477e3d656 Merge pull request #217 from maxdorninger/improve-gh-workflows
stop saving of docker build cache when run by PRs from forks and build x86 and arm64 image in parallel
2025-11-29 17:19:23 +01:00
maxDorninger
ff0eae31dc use arm gh workflow runner instead of qemu with x86 runner 2025-11-29 17:13:00 +01:00
maxDorninger
5e3afee676 fix workflow file paths for metadata relay 2025-11-29 17:01:30 +01:00
maxDorninger
606109d629 stop saving of docker build cache when run by PRs from forks and build x86 and arm64 image in parallel 2025-11-29 16:57:23 +01:00
Maximilian Dorninger
cc9fecc09a Merge pull request #211 from colinmarc/basepath
improve ergonomics of `BASE_PATH`
2025-11-29 16:26:51 +01:00
Maximilian Dorninger
a85cf9f8af Clarify frontend_url trailing slash requirement
Update documentation to specify that the frontend URL must not include a trailing slash.
2025-11-29 16:26:24 +01:00
Maximilian Dorninger
85738a13e6 Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-29 16:09:53 +01:00
maxDorninger
bb5c61ac79 remove /web prefix from the frontend_url variable 2025-11-29 15:54:01 +01:00
maxDorninger
9b0fac3a8b improve format of documentation 2025-11-29 15:52:29 +01:00
Maximilian Dorninger
af13c0eb59 Revert changes to redirect URLs in main.py
The BASE_PATH is already configured when the FastAPI object is created.
2025-11-29 15:32:08 +01:00
Colin Marc
e62f6d4511 docs: clarify usage of frontend_url and BASE_PATH
I initially thought that `frontend_url` would control the prefix. The
docs on `BASE_PATH` weren't enough to get started, either.
2025-11-17 15:11:18 +01:00
Colin Marc
31a23dd781 fix: redirect correctly when using a base path
FastAPI doesn't automatically do this for you.
2025-11-17 14:53:20 +01:00
Maximilian Dorninger
4ea70a4f2e Merge pull request #199 from maxdorninger/rework-metadata-relay
remove valkey caching functionality from metadata relay
2025-11-02 21:53:51 +01:00
maxDorninger
252f8c2f65 remove valkey caching functionality from metadata relay in favour of caching by a cdn like cloudflare 2025-11-02 21:24:41 +01:00
Maximilian Dorninger
f9bceffa18 Merge pull request #198 from maxdorninger/fix-faulty-gh-workflow
fix the gh container build workflows
2025-11-02 20:55:52 +01:00
Maximilian Dorninger
5871400986 Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-02 20:53:50 +01:00
Maximilian Dorninger
a741baded5 Add step to set repository name to lowercase 2025-11-02 20:53:20 +01:00
maxDorninger
c38995579c fix the gh container build workflows 2025-11-02 20:44:19 +01:00
Maximilian Dorninger
ecdfc38470 Merge pull request #197 from maxdorninger/improve-file-logging
update logfile config and add env var to configure logfile location
2025-11-02 20:37:12 +01:00
maxDorninger
e8563b25e2 extend .gitignore; update logfile config and add env var to configure the location of the log file; add accompanying docs 2025-11-02 20:31:12 +01:00
Maximilian Dorninger
70ac88b2c2 Merge pull request #195 from maxdorninger/improve-container-startup-behaviour
Improve container startup behaviour and DB handling
2025-11-02 15:16:33 +01:00
Maximilian Dorninger
ea8c72ed8e Merge branch 'master' into improve-container-startup-behaviour 2025-11-02 14:29:57 +01:00
maxDorninger
780edf1aff update startup script to properly create a development mode variable 2025-11-02 14:19:26 +01:00
maxDorninger
b89320f25d prevent circular imports 2025-11-02 14:19:01 +01:00
Maximilian Dorninger
bc59eac490 remove log related to the removed init_db call in media_manager/main.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-02 13:41:17 +01:00
Maximilian Dorninger
92fdac1f7f Merge pull request #194 from JasperJuergensen/193-build-database-url
Build database URL using sqlalchemy URL create instead of string concatination
2025-11-02 13:23:35 +01:00
maxDorninger
a5c55cc591 remove database initialization function which conflicts with alembic 2025-11-02 13:22:07 +01:00
Jasper Jürgensen
45fc771c16 Build database URL using sqlalchemy URL create
String concatination can cause issues with special characters and can be
a risk for URL parameter injection.

fixes https://github.com/maxdorninger/MediaManager/issues/193
2025-11-02 12:20:35 +01:00
maxDorninger
faee405c8d improve startup script error handling 2025-11-02 11:56:24 +01:00
maxDorninger
2f35cebce3 add health check dependency for database service in docker-compose files 2025-11-02 11:49:22 +01:00
maxDorninger
8e9947652d add new sponsors 2025-11-01 20:42:02 +01:00
Maximilian Dorninger
9932331123 Merge pull request #184 from tylersatre/master
Improve local development experience
2025-11-01 19:16:33 +01:00
Maximilian Dorninger
910b49a66d Merge pull request #187 from maxdorninger/improve-github-workflows
Improve GitHub workflows
2025-11-01 19:16:16 +01:00
Maximilian Dorninger
c68462396b Remove unneeded docker image tags
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-01 19:15:06 +01:00
Maximilian Dorninger
568eaa88fe wrap version variable to prevent script injection
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-01 18:58:53 +01:00
maxDorninger
e2f3cfd173 only tag docker images as latest when they are created as part of a release; replace the hash value in the dev tag with the current date and the workflow run number; fix bug which would cause the build-and-push step to run even though the lint-backend-step failed 2025-11-01 18:41:31 +01:00
maxDorninger
221a4c3506 only push docker images and docs when a pr does not come from a fork 2025-11-01 16:29:05 +01:00
maxDorninger
8a04a7aa41 reformat docs for consistency 2025-11-01 13:28:20 +01:00
Tyler Satre
c71ba85c1c Merge branch 'master' of github.com:maxdorninger/MediaManager 2025-10-31 12:20:24 -04:00
Tyler Satre
106190d7ac Improve local dev experience 2025-10-31 12:19:23 -04:00
Maximilian Dorninger
32aae83875 Remove roadmap section from README
Removed the roadmap section detailing planned features and improvements.
2025-10-31 11:35:55 +01:00
Maximilian Dorninger
7c7c1b90ea Merge pull request #173 from maxdorninger/multithread-indexer-module
Speedup torrent searching and disable useless logs
2025-10-30 19:00:35 +01:00
maxDorninger
8346ed9fa5 add config option to accept/reject torrents from prowlarr with a possibly broken url 2025-10-30 18:20:57 +01:00
maxDorninger
571dcd1cf8 rework follow_redirects_to_final_torrent_url(); prevent infinite, or at least very long, loops by setting a max redirect count of 10 2025-10-30 18:05:52 +01:00
maxDorninger
d460bc10c8 improve prowlarr logging 2025-10-30 18:04:47 +01:00
maxDorninger
68bb500fe7 increase max connections of requests.Session() from 10 to 100 2025-10-30 17:48:43 +01:00
maxDorninger
724d358107 deactivate transmission logs 2025-10-30 17:47:58 +01:00
Maximilian Dorninger
aabfe24063 Merge pull request #171 from maxdorninger/rework-torrent-handling
Add ability to manually mark torrent as imported and speed up eslint
2025-10-30 16:36:38 +01:00
Maximilian Dorninger
855385b097 Apply suggestion from @Copilot
raise exception rather than return it and fix var name switch up

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-30 16:25:44 +01:00
maxDorninger
bbebbe92d9 format schemas.py 2025-10-30 16:20:20 +01:00
maxDorninger
790eca9858 speed up torrent searching by multithreading it and using the same requests session everywhere 2025-10-30 16:20:06 +01:00
maxDorninger
6f4423e501 disable useless logs 2025-10-30 16:17:49 +01:00
maxDorninger
079ac1b130 enable concurrency of eslint linting 2025-10-29 17:30:15 +01:00
maxDorninger
22c4ddc869 add ability to change imported state of a torrent 2025-10-29 17:29:46 +01:00
Maximilian Dorninger
3173803ac8 Merge pull request #170 from maxdorninger/rework-torrent-handling
Rework torrent handling
2025-10-29 16:57:50 +01:00
maxDorninger
abfae4f1f3 format files 2025-10-29 16:34:51 +01:00
Maximilian Dorninger
19c3300342 Update web/src/lib/components/torrent-table.svelte
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-29 16:19:20 +01:00
Maximilian Dorninger
3fb85c766f Fix alembic mirgration which was broken by the IDE's refactor feature
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-29 16:18:12 +01:00
Maximilian Dorninger
1a1d38aa29 Update media_manager/indexer/schemas.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-29 16:17:20 +01:00
maxDorninger
e01402d992 remove python rests since they didn't really test anything anyways 2025-10-29 15:59:22 +01:00
maxDorninger
82700abeb6 improve UX of downloading torrents by splitting the dialogs into two steps; deduplicate code; fix bug which causes the directory preview to be incorrect 2025-10-29 15:56:00 +01:00
maxDorninger
49f8886db1 cleanup code 2025-10-29 14:24:00 +01:00
maxDorninger
8053867db3 update how oauth is handled in the backend, in order for the api docs to always include the oauth endpoints 2025-10-29 14:23:25 +01:00
maxDorninger
39c88a0519 add retry and delete buttons to torrents table 2025-10-29 14:22:22 +01:00
maxDorninger
30b710e618 improve how the download_url field is excluded from the response model 2025-10-28 22:49:10 +01:00
maxDorninger
931f06e825 fix bug that causes a downloading of a torrent even though it could not be saved to database because of a duplicate key exception 2025-10-28 22:47:37 +01:00
maxDorninger
bae3906063 add indexer field to IndexerQueryResult and update related components; display indexer name to use 2025-10-28 22:17:00 +01:00
Maximilian Dorninger
ee7cbe2866 pins base image of MetadataRelay to Python 3.13 variant (#169)
This pull request updates the base image used in the
`metadata_relay/Dockerfile` to ensure compatibility with Python 3.13.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-28 20:15:02 +01:00
Maximilian Dorninger
fdffa38c92 Merge pull request #168 from maxdorninger/enhance-frontend
Miscellaneous frontend enhancements
2025-10-28 09:00:18 +01:00
maxDorninger
9ac16e5ab9 fix eslint rule comments 2025-10-27 23:06:17 +01:00
maxDorninger
bb566e6eb9 format files 2025-10-27 22:26:59 +01:00
maxDorninger
b846480b84 create function for displaying query result toasts to reduce code duplication 2025-10-27 21:49:26 +01:00
maxDorninger
994e558090 fix torrent table using id and not torrent_id as identifying property 2025-10-27 21:48:30 +01:00
maxDorninger
89965e65e1 update verify page; replace goto dashboard button with logout button 2025-10-27 21:25:54 +01:00
Maximilian Dorninger
6c2ebc6c4c Merge pull request #167 from maxdorninger/enhance-frontend
[CHORE] replace all usages of base with resolve() and pin python version to 3.13
2025-10-27 21:19:34 +01:00
maxDorninger
702e89b8b5 update base uv docker image 2025-10-27 20:56:11 +01:00
maxDorninger
fd434ec544 fix resolve import 2025-10-27 20:45:46 +01:00
maxDorninger
8540149a97 Merge remote-tracking branch 'origin/enhance-frontend' into enhance-frontend
# Conflicts:
#	web/src/routes/+layout.svelte
2025-10-27 20:41:10 +01:00
maxDorninger
b5ac036103 replace asset() with resolve() 2025-10-27 20:40:20 +01:00
maxDorninger
3dac3caa68 replace asset() with resolve() 2025-10-27 20:39:15 +01:00
maxDorninger
0cae36dcac replace mime-types with media-types and mailcap in the main Dockerfile 2025-10-27 20:29:17 +01:00
maxDorninger
18c97c3526 pin python version of GHA to 3.13 2025-10-27 20:23:57 +01:00
maxDorninger
f62394fdb7 replace base with resolve 2025-10-27 20:06:10 +01:00
Maximilian Dorninger
91df5cec26 Merge pull request #160 from maxdorninger/add-sponsor
add HadrienKerlero to sponsor mentions
2025-09-25 21:32:40 +02:00
maxDorninger
5910b047b3 format files 2025-09-25 21:26:16 +02:00
maxDorninger
b53e9fde9b add HadrienKerlero to sponsor mentions 2025-09-25 21:21:53 +02:00
Maximilian Dorninger
7eb4ff8902 Merge pull request #158 from maxdorninger/clean-up-deps
update dependencies, add back lucide-svelte, fix auth being enabled regardless of the config
2025-09-18 20:53:20 +02:00
maxDorninger
98ee8d265d disable svelte no navigation without resolve eslint rule 2025-09-18 12:47:10 +02:00
maxDorninger
b6ff4e917f fix oauth being enabled regardless of the config 2025-09-18 12:01:48 +02:00
maxDorninger
124357ec9c update package-lock.json 2025-09-13 22:57:10 +02:00
maxDorninger
3d00809634 update dependencies and add back lucide-svelte 2025-09-13 22:48:39 +02:00
Maximilian Dorninger
b59d42f0eb Merge pull request #157 from maxdorninger/fix-credentials-being-leaked-in-logs
Fix credentials being leaked in logs
2025-09-13 22:02:43 +02:00
maxDorninger
bebd55a211 remove changes dict from logging message 2025-09-13 22:00:04 +02:00
maxDorninger
ed6271ab35 update default email to admin@example.com 2025-09-13 21:57:04 +02:00
Maximilian Dorninger
16014392a1 Merge pull request #156 from maxdorninger/clean-up-deps
remove unused node dependencies
2025-09-13 21:53:58 +02:00
maxDorninger
f6dea2b8be remove unused node dependencies 2025-09-13 21:41:28 +02:00
Maximilian Dorninger
3b3aaed05d Merge pull request #155 from maxdorninger/pin-postgres-version
pin postgres to version 17 in example docker-compose files
2025-09-13 21:31:29 +02:00
maxDorninger
a941dee22f pin postgres to version 17 in example docker-compose files 2025-09-13 21:29:54 +02:00
Maximilian Dorninger
c02061a99f Merge pull request #138 from maxdorninger/add-openapi-generator-to-frontend
Rework how OAuth is handled; Generate Code with openapi-ts; Switch away from standard JS fetch to openapi-fetch
2025-09-13 21:07:40 +02:00
Maximilian Dorninger
3a553d32e6 Remove unneeded methods from allowed CORS methods
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-13 21:06:00 +02:00
maxDorninger
d099c7aab9 update developer docs 2025-09-13 20:49:39 +02:00
maxDorninger
9e91f71bd1 fix no error message being displayed when login fails because of bad credentials 2025-09-13 20:47:17 +02:00
maxDorninger
ec2897b134 fix get_openid_router function by switching to the correct get_user_manager function 2025-09-13 20:33:00 +02:00
maxDorninger
8f5cc9329c update how oauth is handled 2025-09-13 18:42:34 +02:00
maxDorninger
1c81083e23 fix typo when accessing auth metadata 2025-09-13 18:03:47 +02:00
maxDorninger
d8b81ded43 add hot reload to docker container if dev mode is enabled 2025-09-12 20:43:36 +02:00
maxDorninger
9125bddf12 remove stray parentheses 2025-09-12 20:43:16 +02:00
maxDorninger
0ac34c0834 fix hardcoded url of images 2025-09-12 20:41:58 +02:00
maxDorninger
6203ec5ce0 format files 2025-09-12 20:09:44 +02:00
maxDorninger
6f8d3eea4e update type of the library parameter to string, instead of generating a list of possible values dynamically 2025-09-12 20:05:02 +02:00
maxDorninger
d6c1a03d78 migrate all .svelte files to new types created with openapi-ts 2025-09-12 19:58:53 +02:00
maxDorninger
3eaa3dd233 update how login is handled in the frontend 2025-09-07 21:01:24 +02:00
maxDorninger
340186a3fc prevent infinite recursion of autoLogoutMiddleware 2025-09-04 21:37:25 +02:00
maxDorninger
786b14527c update cors middleware 2025-09-04 21:36:52 +02:00
maxDorninger
a012a0cc67 add logging to display which config file is being read 2025-09-04 21:36:32 +02:00
maxDorninger
1f544e55e8 add support for multiple oauth providers 2025-09-04 20:05:45 +02:00
maxDorninger
c367e3d898 update dockerfile to remove hardcoded /api/v1 prefix in api urls 2025-08-30 23:09:01 +02:00
maxDorninger
c9ecc9c5b4 add line that copilot in its infinite wisdom deleted 2025-08-30 22:34:02 +02:00
Maximilian Dorninger
43206971d8 Move user id from query to path parameters in saveUser() in user-data-table
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-30 22:26:33 +02:00
Maximilian Dorninger
ee7d514c13 Remove misplaced ! that inverts login in season-requests-table 2025-08-30 22:24:55 +02:00
Maximilian Dorninger
a397264944 Fix recommended-tv endpoint being called instead of movie one in add-movie component
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-30 22:22:57 +02:00
maxDorninger
62da720944 convert handleLogout() to use openapi-fetch 2025-08-30 22:06:57 +02:00
maxDorninger
ef634af4ba remove unnused types.ts 2025-08-30 22:02:53 +02:00
maxDorninger
e4b8596468 format files 2025-08-30 21:53:00 +02:00
Maximilian Dorninger
36643bb6d1 Merge pull request #147 from chadsr/fix/hardlink-unsupported
Handle hardlink_to UnsupportedOperation/NotImplementedError exceptions
2025-08-30 21:27:59 +02:00
maxDorninger
18c0b38c8d replace all occurrences of fetch with openapi-fetch in components 2025-08-30 20:09:06 +02:00
maxDorninger
ded9503169 replace all occurrences of fetch with openapi-fetch in routes 2025-08-30 11:55:38 +02:00
Maximilian Dorninger
a599832c00 Update license information for MediaManager 2025-08-29 22:24:38 +02:00
Ross
d34ac0e0b5 handle NotImplementedError for backwards compatibility 2025-08-29 20:36:22 +02:00
Ross
4f6829ae9c handle hardlink_to UnsupportedOperation exception the same as OSError + type fixes 2025-08-29 20:32:24 +02:00
Maximilian Dorninger
871b6133f3 Merge pull request #139 from maxdorninger/switch-to-dorninger.co
Change all URLs containing maxid.me to dorninger.co
2025-08-23 18:12:50 +02:00
maxDorninger
cd5b16a4e5 Change all URLs containing maxid.me to dorninger.co 2025-08-23 17:54:57 +02:00
maxDorninger
5a71246623 format generated file, use openapi fetch in login route and fix linting errors 2025-08-21 21:26:18 +02:00
maxDorninger
ea6ece3286 add middlewares to openapi-fetch 2025-08-21 21:25:06 +02:00
maxDorninger
b147bb8434 add openapi-typescript and openapi-fetch to project and generate types with it 2025-08-21 20:13:39 +02:00
Maximilian Dorninger
6c4b6a52cf Merge pull request #133 from almarzn/patch-1
add a prefix for environment variables
2025-08-11 22:24:31 +02:00
maxDorninger
35a4b4a14c add MEDIAMANAGER prefix to documentation 2025-08-11 22:22:42 +02:00
Maximilian Dorninger
41531b3807 Merge pull request #129 from maxdorninger/enhance-frontend
Enhance frontend
2025-08-11 22:04:10 +02:00
maxDorninger
b2973cf2f2 format files 2025-08-11 21:41:45 +02:00
maxDorninger
dfa58b8f71 format files 2025-08-11 21:40:13 +02:00
maxDorninger
82edbe73d8 fix weird typescript linting errors 2025-08-11 21:39:51 +02:00
maxDorninger
611e066473 fix linting errors 2025-08-11 21:16:14 +02:00
maxDorninger
cd549cfc84 remove unused imports 2025-08-11 20:24:41 +02:00
Alma
f9747816db add a prefix for environment variables 2025-08-10 15:42:56 +02:00
maxDorninger
1a489dc71d replace divs with main, header and footer tags to make html more semantic 2025-08-02 14:40:40 +02:00
maxDorninger
174c675992 add autocomplete flag to login/signup forms 2025-08-02 14:34:21 +02:00
maxDorninger
d381fdddce break up login page and form component into separate signup and login card/page 2025-08-02 14:27:09 +02:00
maxDorninger
79ccfe701d rework login page, deduplicate code by using layouts 2025-08-02 14:18:18 +02:00
maxDorninger
2eaa1b94c0 add No torrents found error message 2025-08-02 13:18:35 +02:00
maxDorninger
0cd9cc8851 add search button to basic mode, instead of searching for torrents everytime season number changes 2025-08-02 13:18:21 +02:00
maxDorninger
9f2ec53d23 add the max width of the content to other pages too 2025-08-02 12:45:55 +02:00
maxDorninger
35824af5d4 fix pictures clipping and thus being displayed in a 9/20 aspect ratio 2025-08-02 12:23:16 +02:00
maxDorninger
7035507a57 add score column to the download dialogues 2025-08-02 11:57:37 +02:00
maxDorninger
f755589258 add new sponsor https://github.com/SeimusS 2025-08-02 03:36:40 +02:00
maxDorninger
56a215de97 update shadcn components 2025-08-02 03:24:13 +02:00
maxDorninger
fb095e61cb update from tailwindcss 3 to 4 2025-08-02 02:56:28 +02:00
maxDorninger
8cf62004a2 update package lock 2025-08-02 02:29:35 +02:00
maxDorninger
60f129af3a make tv and movie page use cards 2025-08-02 01:50:45 +02:00
maxDorninger
9fcb7b1d20 organize the controls on the movie and tv pages in cards 2025-08-02 01:19:55 +02:00
maxDorninger
233044a429 make layout of the movie and tv show page better, i.e. set the content's max width to 80em instead of the full width of the page; replace checkbox for continuous download of show with switch 2025-08-02 01:08:01 +02:00
maxDorninger
0046fc473c add torrents field to public movie schema, and fix movie's torrents not correctly displaying in the web ui 2025-08-01 23:15:38 +02:00
maxDorninger
29ee6ed53b add library field to PublicShow schema 2025-08-01 22:52:13 +02:00
maxDorninger
9f9431dbaf add new sponsor https://github.com/brandon-dacrib to docs, about page and readme 2025-08-01 15:47:54 +02:00
Maximilian Dorninger
89f4a76825 Fix regex for importing episodes (#128)
This pull request makes a small but significant change to the
`import_torrent_files` method in `media_manager/movies/service.py`. The
change updates the regular expression used to match subtitle file names,
making it more flexible in recognizing language codes.

*
[`media_manager/movies/service.py`](diffhunk://#diff-57cfa309860beba31573487107eba3f7ef8ef60429c48c02fb262b9f4ff9b8d3L527-R527):
Updated the regular expression in `import_torrent_files` to match
language codes in subtitle file names that are separated by either a dot
(`.`) or a space (` `), instead of only a dot.

It fixes #124.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-01 15:21:55 +02:00
Maximilian Dorninger
2bcec538a3 Merge pull request #127 from maxdorninger/remove-special-chars-from-media-file-names
Remove certain special chars from file names
2025-08-01 14:31:01 +02:00
Maximilian Dorninger
35de9629ec Update media_manager/torrent/utils.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-31 22:48:15 +02:00
maxDorninger
a095e1987f add function remove_special_characters and use it in the import torrent files functions, it removes characters that break SMB or jellyfin 2025-07-31 22:42:31 +02:00
maxDorninger
f8f21df913 add warning to the callback uri documentation, reminding users to set the correct one 2025-07-31 14:31:43 +02:00
maxDorninger
818dd4428f add callback uri to troubleshooting.md 2025-07-31 14:28:17 +02:00
maxDorninger
405f807c1e add callback uri for oidc auth to documentation, also add screenshots of Authentik and PocketId configuration 2025-07-31 14:25:57 +02:00
Maximilian Dorninger
1862707ae3 Merge pull request #119 from maxdorninger/make-prowlarr-follow-redirects
make prowlarr follow redirects for every url
2025-07-31 12:54:40 +02:00
maxDorninger
c8d0ec2a5f raise Runtime error instead of returning None when final url could not be determined 2025-07-30 22:37:57 +02:00
Maximilian Dorninger
6c20f7f026 Update media_manager/indexer/utils.py
use redirect_url instead of final_url

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-30 22:34:45 +02:00
Maximilian Dorninger
e2c65c9231 Update media_manager/indexer/utils.py
use redirect_url instead of final_url

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-30 22:34:37 +02:00
maxDorninger
9c84e04de2 make prowlarr follow redirects for every url 2025-07-30 22:29:30 +02:00
Maximilian Dorninger
369ae87f88 Merge pull request #117 from maxdorninger/fix-password-updating-instead-of-email
fix password being set to new email when trying to update oneself's email
2025-07-29 16:21:44 +02:00
maxDorninger
c773bf41b6 keep users who change their email verified status 2025-07-29 16:20:11 +02:00
maxDorninger
99c0a7dafa remove duplicate input field 2025-07-29 16:04:44 +02:00
maxDorninger
bb294225f2 fix formatting 2025-07-29 15:36:50 +02:00
maxDorninger
a83a7d8c08 fix password being set to new email when trying to update oneself's email 2025-07-29 15:22:23 +02:00
maxDorninger
73e2ecefeb update troubleshooting.md with second default email 2025-07-29 14:40:14 +02:00
maxDorninger
799d7ea240 fix formatting of frontend files 2025-07-29 13:53:23 +02:00
maxDorninger
0ac029d5c9 update troubleshooting page 2025-07-29 13:52:09 +02:00
maxDorninger
6cdb2dbfe3 add footer to docs 2025-07-29 13:31:23 +02:00
maxDorninger
68c1634ef5 add sitemap to docs 2025-07-29 13:10:55 +02:00
maxDorninger
ace5ac3f9b format startup script 2025-07-29 13:03:20 +02:00
maxDorninger
575efddf53 improve error message that appears when trying to add duplicate filepath suffix for a season/movie file 2025-07-29 13:02:50 +02:00
Maximilian Dorninger
e6319c8893 Merge pull request #112 from maxdorninger/add-magnet-link-support
This pull request introduces several updates to improve torrent handling, streamline code, and enhance functionality in the MediaManager project. Key changes include the addition of a utility function for calculating torrent hashes, refactoring of download logic to reduce redundancy, and updates to dependencies and environment configurations.
2025-07-29 12:49:35 +02:00
maxDorninger
61c6f50c5c add algolia index variable to writerside build config 2025-07-28 23:08:45 +02:00
maxDorninger
7886d86c72 update algolia index name 2025-07-28 22:55:04 +02:00
maxDorninger
7e6b4652f2 fix formatting of build-docs.yml GH workflow 2025-07-28 22:38:02 +02:00
Maximilian Dorninger
afe42d084d Merge pull request #114 from maxdorninger/add-search-and-startpage-to-docs
Rework the docs, Make proper introduction page, replace BuyMeACoffee button with Get MediaManager button, add Algolia Search to the docs
2025-07-28 22:35:00 +02:00
Maximilian Dorninger
2905651bd7 Apply suggestion from @Copilot to fix formatting
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-28 22:34:31 +02:00
Maximilian Dorninger
7f431d29e9 Apply suggestion from @Copilot to fix formatting
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-28 22:34:23 +02:00
maxDorninger
fb3e64359f remove badges from sponsor cades on start page 2025-07-28 22:30:50 +02:00
maxDorninger
80a58d4a02 replace donation call to action with download mediamanager button 2025-07-28 22:30:26 +02:00
maxDorninger
0abc09f130 Rework introduction topic to use the writerside section-starting-page tag. Also add sponsors and sponsoring call to action to introduction topic. 2025-07-28 22:12:31 +02:00
maxDorninger
9735fce4ae move screenshots to a separate topic 2025-07-28 22:10:28 +02:00
maxDorninger
ed2ff16dd6 add algolia deploy step and env variables to gh workflow 2025-07-28 21:25:57 +02:00
maxDorninger
b2635cc650 add algolia config to build config 2025-07-28 21:10:20 +02:00
maxDorninger
d3c8e6ea1f make prowlarr use the guid (magnet link) instead of the weird http url that's stored in the magnetUrl field 2025-07-27 15:19:05 +02:00
Maximilian Dorninger
4a3dea3cab Update media_manager/torrent/download_clients/qbittorrent.py
initialize answer instead of marking it with global

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-27 15:03:02 +02:00
maxDorninger
c56aebd85d extract logic for downloading torrent file and parsing the magnetlink/torrent file into separate function 2025-07-27 14:42:26 +02:00
maxDorninger
558d18163c add libtorrent as dependency 2025-07-27 13:41:15 +02:00
maxDorninger
a8b962f450 fix docker image not working when building on my pc 2025-07-27 13:41:01 +02:00
maxDorninger
efab99473a make comment better 2025-07-26 18:28:03 +02:00
Maximilian Dorninger
038cfdd079 Merge pull request #109 from maxdorninger/add-magnet-link-support
add support for magnet urls to indexers
2025-07-26 16:24:14 +02:00
maxDorninger
6610a01769 fix syntax to check if result dictionary has the key "downloadUrl" 2025-07-26 15:28:23 +02:00
maxDorninger
ad08be52a7 edit tests 2025-07-26 14:11:34 +02:00
maxDorninger
e7863c7a6c add support for magnet urls to indexers 2025-07-26 13:14:22 +02:00
Maximilian Dorninger
be97c5133c Merge pull request #105 from maxdorninger/make-qbit-categories-customizable
Fix some qBitorrent bugs and make Sabnzbd api path configurable
2025-07-26 12:43:34 +02:00
maxDorninger
73496f9450 make the import_file function skip files which already exist 2025-07-26 12:42:39 +02:00
Maximilian Dorninger
64873d9eee Update media_manager/torrent/download_clients/qbittorrent.py
Remove duplicate 'moving' state from DOWNLOADING_STATE tuple.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-26 10:04:24 +02:00
maxDorninger
1507044809 make base_path of sabnzbd configurable 2025-07-25 20:55:38 +02:00
maxDorninger
97d0e140b7 add undocumented states to qbittorent's DOWNLOADING_STATE and FINISHED_STATE 2025-07-25 19:24:50 +02:00
maxDorninger
7c9b8d53fd fix qbittorrent not being able to initialize due to error when trying to update the Qbittorrent category 2025-07-25 19:23:56 +02:00
Maximilian Dorninger
04371a2a50 Merge pull request #100 from maxdorninger/make-qbit-categories-customizable
Miscellaneous features and fixes
2025-07-23 00:09:28 +02:00
maxDorninger
1fca7b083a fix duplicate apscheduler jobs and add postgres to docker image 2025-07-23 00:02:23 +02:00
maxDorninger
b9dfb07cf7 make API return HTTP Conflict 409 on Unique Violation/Integrity Error in DB 2025-07-22 22:49:49 +02:00
maxDorninger
e5a69d521b rename startup script and make the mediamanager logo look cooler on startup 2025-07-22 22:04:25 +02:00
maxDorninger
d82c2efbe5 fix bug report template 2025-07-22 19:55:43 +02:00
maxDorninger
d59b4a1ec1 make port customizable via env variable 2025-07-22 18:02:59 +02:00
maxDorninger
a2982e12c0 remove outdated comment 2025-07-22 17:54:44 +02:00
maxDorninger
3e5f43a5d3 make qbittorrent category save path and name customizable 2025-07-22 17:54:25 +02:00
maxDorninger
6a273da054 fix http always being used as protocol for the callback url when using oauth 2025-07-22 16:53:13 +02:00
maxDorninger
7c2048b32f update the documenation and template config to include http protocol prefix in sabnzbd url 2025-07-19 21:55:01 +02:00
maxDorninger
d8b0ee0001 remove image_dir env variable from docker container 2025-07-19 17:13:17 +02:00
maxDorninger
f38c825105 add auto_download_movie_requests to scheduler 2025-07-19 17:13:01 +02:00
Maximilian Dorninger
06db92feac Merge pull request #89 from maxdorninger/enhance-frontend
Enhance frontend
2025-07-19 15:17:14 +02:00
Maximilian Dorninger
507560f8c3 Update web/src/lib/components/user-data-table.svelte
correct the id that the email label references

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-19 14:55:31 +02:00
Maximilian Dorninger
7731016868 update web/src/routes/dashboard/settings/+page.svelte
remove debugging print statements

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-19 14:54:54 +02:00
maxDorninger
c4deda96fb Merge remote-tracking branch 'origin/master' 2025-07-19 14:51:01 +02:00
maxDorninger
8f31841130 expand download dialogues max torrent table height 2025-07-19 14:48:55 +02:00
maxDorninger
608bdf32e7 fix movie request page not loading 2025-07-19 14:40:53 +02:00
maxDorninger
6224d418be fix breadcrumbs in movie torrents page linking to show page 2025-07-19 14:17:49 +02:00
maxDorninger
9eb2411bce fix error message displaying when adding a movie request 2025-07-19 14:13:13 +02:00
maxDorninger
cc554164c3 make settings page properly reactive and add feature for admins to be able to change other user's emails 2025-07-19 13:44:18 +02:00
maxDorninger
f8e7b80a9b make users table only display other users 2025-07-19 13:27:55 +02:00
maxDorninger
b404ab13e7 hopefully fix blank settings page by using $derived instead of $state 2025-07-19 13:15:28 +02:00
maxDorninger
97b894a9a0 update dev docker compose file 2025-07-19 13:01:27 +02:00
Maximilian Dorninger
2c02f50c86 Rename config.yaml to config.yml 2025-07-19 12:54:27 +02:00
Maximilian Dorninger
a3e3d6a30d Deactivate blank issues 2025-07-19 12:53:31 +02:00
Maximilian Dorninger
6ed86616aa Update bug_report.md 2025-07-18 22:20:15 +02:00
Maximilian Dorninger
d75621bb22 add starhistory to readme 2025-07-18 21:48:41 +02:00
Maximilian Dorninger
c35042ade8 Update bug_report.md 2025-07-18 21:38:22 +02:00
Maximilian Dorninger
7721ea6fab Merge pull request #81 from maxdorninger/enhance-dev-experience
Enhance dev experience
2025-07-18 21:33:22 +02:00
Maximilian Dorninger
c13ae25d3d Update config.dev.toml
change default nodejs origin listed in cors urls to http

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-18 21:32:54 +02:00
Maximilian Dorninger
c15b83f77e Update Writerside/topics/developer-guide.md
update option flag order of docker compose command

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-18 21:32:26 +02:00
Maximilian Dorninger
0870cdc2a1 Fix spelling error in Writerside/topics/developer-guide.md
everytime -> every time

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-18 21:32:00 +02:00
maxDorninger
ac749474bf update bug report issue template 2025-07-18 21:27:51 +02:00
maxDorninger
6ad0e4caca update developer guide 2025-07-18 21:20:42 +02:00
maxDorninger
26753d9c7f modify dev docker-compose 2025-07-18 21:13:08 +02:00
maxDorninger
794f001a53 add config.dev.toml 2025-07-18 21:12:02 +02:00
maxDorninger
c1c94ea8ef updating installation guide, rename config.toml to config.example.toml 2025-07-18 21:11:45 +02:00
maxDorninger
4ab22bf1ca updating installation guide 2025-07-18 21:05:33 +02:00
maxDorninger
d352a8546a updating developer information/guide 2025-07-18 21:03:30 +02:00
Maximilian Dorninger
cd8b3abf70 Merge pull request #70 from Milanzor/remove-db-port-exposure
Remove db port exposure from the docker-compose.yml
2025-07-18 18:24:46 +02:00
Maximilian Dorninger
874a6934fb Merge pull request #71 from wjbeckett/master
Complete Setup Experience Overhaul: Auto-Config, User Creation, and Volume Improvements
2025-07-18 17:56:17 +02:00
maxDorninger
d4d0b99f45 change default db host from localhost to db 2025-07-18 14:35:48 +02:00
maxDorninger
f1a01b4d43 automatically create all directories 2025-07-18 14:33:12 +02:00
maxDorninger
56db3cc008 remove tv,movie, image and torrent env vars from container and move them to the config file 2025-07-18 14:32:21 +02:00
maxDorninger
1a02168fe6 update documentation regarding the config file 2025-07-18 14:22:50 +02:00
maxDorninger
b17641df0d Merge remote-tracking branch 'wjbeckett/master' into fork/wjbeckett/master 2025-07-18 14:19:48 +02:00
maxDorninger
eacdd5b74f update documentation of the config file 2025-07-18 14:01:40 +02:00
maxDorninger
c529f6f273 update backend config page 2025-07-18 13:55:20 +02:00
Maximilian Dorninger
eb971bb601 Update Dockerfile
Include env vars that set default directories for media and images
2025-07-18 13:50:38 +02:00
Maximilian Dorninger
c7a951eacf Update media_manager/config.py
make /data/images default directory for images
2025-07-18 13:48:48 +02:00
Maximilian Dorninger
a2ec7886f4 Update docker-compose.yaml to include volume for images 2025-07-18 13:48:22 +02:00
maxDorninger
0df004df6f fix and move create default user function to auth.users 2025-07-18 13:45:51 +02:00
Backslash
859281d193 Update port and base path
Co-authored-by: Maximilian Dorninger <97409287+maxdorninger@users.noreply.github.com>
2025-07-18 21:02:55 +10:00
Backslash
c0d0cb5e54 Update frontend urls
Co-authored-by: Maximilian Dorninger <97409287+maxdorninger@users.noreply.github.com>
2025-07-18 21:02:13 +10:00
Backslash
56d5faaec5 Route redirects
Redirect routes to /web for front end.

Co-authored-by: Maximilian Dorninger <97409287+maxdorninger@users.noreply.github.com>
2025-07-18 21:01:04 +10:00
Maximilian Dorninger
b9bf190c1b Update config.toml
I forgot to change the config when merging a previous PR that merged the frontend and backend container.
2025-07-18 12:36:09 +02:00
Backslash
a2d717b022 Merge pull request #1 from wjbeckett/feat/container-enhancements
Complete Setup Experience Overhaul: Auto-Config, User Creation, and Volume Improvements
2025-07-18 17:57:48 +10:00
Milan van As
bad037b598 Updated configuration to connect to the db host instead of through the previously exposed port 2025-07-18 09:07:39 +02:00
Milan van As
687e84ce86 Updated the README file to use the added docker-compose.dev.yaml file in the Developer Quick Start guide + fixed paths 2025-07-18 09:04:36 +02:00
Milan van As
d19e451f85 Moved the port exposure for the db service to a seperate docker-compose file 2025-07-18 09:04:30 +02:00
wjbeckett
0158ac1040 fix: Add default values to config classes to resolve test validation errors
- Add default instances to all nested config classes (TorrentConfig, NotificationConfig, IndexerConfig, MetadataProviderConfig, AuthConfig)
- Add default values to AllEncompassingConfig fields to prevent validation errors during testing
- Update GitHub workflow to copy config.example.toml before running tests
- Ensures tests can run without requiring complete configuration files while maintaining production functionality

Fixes test collection errors where pydantic validation failed due to missing required config sections.
2025-07-18 16:56:19 +10:00
wjbeckett
31c6f415d0 fix build. 2025-07-18 16:44:54 +10:00
wjbeckett
a4d31d9ac9 fix: linting. 2025-07-18 16:32:33 +10:00
wjbeckett
431d0e7689 removed docs. 2025-07-18 16:23:15 +10:00
wjbeckett
4177409b59 feat: Add default admin user creation and root route redirects
- Auto-create admin user on first startup (admin@example.com/admin)
- Add redirects from /, /dashboard, /login to /web/ for better UX
- Enhanced startup logging with login credentials
- Improved config documentation for admin_emails

Fixes initial setup UX issues with web UI access and authentication.
2025-07-18 16:04:01 +10:00
wjbeckett
df7d00ad99 feat: improve container setup and fix deployment issues
- Move images directory from /data/images to /app/images to separate app data from user media
- Implement config folder approach instead of direct file mounting
- Add automatic config initialization with example config on first boot
- Remove hardcoded media directory environment variables from Dockerfile
- Update startup script to handle config folder setup and validation
- Only create application-managed directories, not user media directories
- Update docker-compose.yaml to use config folder volume mapping

Fixes container startup failures when config.toml doesn't exist and improves
separation between application data and user media directories.
2025-07-18 12:54:08 +10:00
maxDorninger
aaa025c2bb remove link to removed reverse proxy documentation 2025-07-17 23:05:25 +02:00
Maximilian Dorninger
69023d9662 Merge pull request #65 from maxdorninger/switch-sveltekit-to-static-adapter
Merge Frontend and Backend Container
2025-07-17 22:58:34 +02:00
maxDorninger
d5f09736f8 format files 2025-07-17 21:09:48 +02:00
maxDorninger
fe525a9397 fix HTTP error 404 exception handler 2025-07-17 21:07:36 +02:00
maxDorninger
cb73c9e14f fix images not working 2025-07-17 20:46:03 +02:00
maxDorninger
2681c111e5 change container name in template docker compose file 2025-07-17 19:37:52 +02:00
maxDorninger
1339c9d61d fix invalid URL error 2025-07-17 19:37:10 +02:00
maxDorninger
d0c6f36df9 update dockerfile 2025-07-17 18:26:22 +02:00
maxDorninger
776e74a8ad update dependencies of frontend 2025-07-17 18:21:20 +02:00
maxDorninger
f94d231316 add missing BASE_PATH docker build argument to GHA workflow 2025-07-17 18:13:14 +02:00
maxDorninger
ce786d2b63 fix error which causes caching GHA workflow to not work because of upper case repo name 2025-07-17 18:03:31 +02:00
maxDorninger
88e9ccdfa6 remove Reverse-Proxy topic from documentation 2025-07-17 17:59:58 +02:00
maxDorninger
674545de8c remove unneeded gha workflow 2025-07-17 17:59:40 +02:00
maxDorninger
7b1bd7f98a update default docker compose file 2025-07-17 17:59:27 +02:00
maxDorninger
2c995ae29c remove base_api_path field from template config.toml 2025-07-17 17:56:49 +02:00
maxDorninger
10b4f5baca update documentation 2025-07-17 17:49:41 +02:00
maxDorninger
bb1e7ef170 update github workflows 2025-07-17 17:36:58 +02:00
maxDorninger
a232d5e935 format files 2025-07-17 17:20:49 +02:00
maxDorninger
e051001ea5 fix typo 2025-07-17 17:18:44 +02:00
maxDorninger
5ff55f1a1d add base url to all the redirects and links 2025-07-17 17:18:37 +02:00
Maximilian Dorninger
e26c2931ce Merge pull request #64 from EmilZackrisson/master
Fix typo in quick start command
2025-07-17 17:09:40 +02:00
maxDorninger
ea7556de39 combine Dockerfiles of backend and frontend 2025-07-17 16:56:10 +02:00
Emil Zackrisson
463470ee95 Update README.md 2025-07-17 16:50:06 +02:00
maxDorninger
c2b7440bdd adjust config options of backend 2025-07-17 16:38:25 +02:00
maxDorninger
81c8381a90 adjust backend to serve static frontend files 2025-07-17 16:04:57 +02:00
maxDorninger
6016e3c155 make frontend support static adapter in SPA mode 2025-07-17 15:17:40 +02:00
Maximilian Dorninger
fcc84c35b1 Update Roadmap 2025-07-17 12:37:43 +02:00
Maximilian Dorninger
82c8be085b Merge pull request #63 from maxdorninger/add-custom-formats
Add custom formats
2025-07-17 12:32:52 +02:00
Maximilian Dorninger
96dbcf564c Update media_manager/indexer/indexers/jackett.py
add default values to global values

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-17 12:31:46 +02:00
maxDorninger
a230fcaa43 fix logic of evaluate_indexer_query_results 2025-07-17 12:31:12 +02:00
maxDorninger
a3a15573f9 remove irrelevant test 2025-07-17 12:25:31 +02:00
maxDorninger
bac4cb9000 add documentation for the scoring rules 2025-07-17 12:13:05 +02:00
maxDorninger
45b1b397a6 edit default config 2025-07-17 11:44:03 +02:00
maxDorninger
b6f5f8b253 format files 2025-07-17 11:37:58 +02:00
maxDorninger
dcf3d1907a add proper logging to the Indexer query result evaluation functions 2025-07-17 11:37:35 +02:00
maxDorninger
acfa3d3b75 add support for indexer flags when using jackett 2025-07-17 11:36:44 +02:00
maxDorninger
9254a5ab10 update sorting algorithm of IndexerQueryResult 2025-07-17 00:36:49 +02:00
maxDorninger
c4db283c63 add evaluate_indexer_query_results function to process query results based on scoring rules and use this function in tv and movie modules 2025-07-17 00:29:30 +02:00
maxDorninger
387e5e1095 add scoring rulesets to config 2025-07-17 00:02:29 +02:00
maxDorninger
83a09ebb94 add score field to db table and add alembic migration for the field 2025-07-16 23:27:54 +02:00
maxDorninger
d01e5f5ee2 add scoring rules to config and add evaluate indexer query result function 2025-07-16 23:23:15 +02:00
maxDorninger
9264d74d51 add score field to indexer query result 2025-07-16 23:06:45 +02:00
maxDorninger
4d0443b337 improve regex to determine the quality of a Indexer query result 2025-07-16 23:06:28 +02:00
Maximilian Dorninger
1aa6cb4f35 Merge pull request #62 from maxdorninger/add-multiple-libraries
Add support multiple libraries
2025-07-16 15:11:45 +02:00
maxDorninger
bbe786e063 rearrange stuff in config.toml 2025-07-16 15:05:33 +02:00
maxDorninger
882755fb56 update order of chapters in documentation 2025-07-16 15:00:37 +02:00
maxDorninger
8806c7caed update installation guide 2025-07-16 14:59:54 +02:00
maxDorninger
14942f9653 add frontend code for selecting/setting the library 2025-07-16 14:32:21 +02:00
maxDorninger
b18b11c682 change string value for default/no library from empty string to "Default" 2025-07-16 14:24:42 +02:00
maxDorninger
e0a7e115e4 add library field to types in types.ts 2025-07-16 13:43:29 +02:00
maxDorninger
26d0ca567f add proper error handling if no usenet/torrent download client is available when getting all torrents 2025-07-16 13:23:26 +02:00
maxDorninger
c186df94b8 add error handling to automatic imports of torrents and add proper db session handling to scheduled tasks 2025-07-16 12:03:46 +02:00
maxDorninger
d5c092e08d add backend code for setting/getting the libraries for movies 2025-07-16 11:00:48 +02:00
maxDorninger
49b95df59d add backend code to get/set tv library 2025-07-16 02:00:20 +02:00
maxDorninger
d60f8bd89b add alembic migration for new columns 2025-07-16 01:19:26 +02:00
maxDorninger
4ca910ec98 add library to config and to models and schemas 2025-07-16 01:19:07 +02:00
maxDorninger
94e5c12762 add important note to the transmission documentation 2025-07-15 20:50:08 +02:00
Maximilian Dorninger
3df5bde201 Merge pull request #61 from maxdorninger/add-support-for-transmission
Add support for transmission
2025-07-15 20:38:17 +02:00
maxDorninger
7528a354f6 Merge remote-tracking branch 'origin/add-support-for-transmission' into add-support-for-transmission
# Conflicts:
#	Writerside/topics/download-client-configuration.md
2025-07-15 20:28:28 +02:00
maxDorninger
be809dd5eb add transmission to documentation 2025-07-15 20:25:47 +02:00
maxDorninger
b38c979fa9 add transmission to documentation 2025-07-15 20:24:54 +02:00
maxDorninger
831f9dc1ac format files 2025-07-15 20:05:37 +02:00
maxDorninger
0400954339 fix test 2025-07-15 20:05:07 +02:00
maxDorninger
b3c762040d add support for transmission 2025-07-15 19:56:46 +02:00
maxDorninger
d404663f16 fix overriding of filepath suffix not working for seasons 2025-07-15 19:56:09 +02:00
maxDorninger
42d42920a5 correct sorting of torrents in tv service 2025-07-15 18:49:09 +02:00
maxDorninger
d9ea02fdc5 fix show pages not loading if download client is not reachable 2025-07-15 18:35:54 +02:00
Maximilian Dorninger
8b4a9d4097 Merge pull request #59
Fix: remove hardcoded colours from setting's dialogues
2025-07-13 18:00:32 +02:00
maxDorninger
1626f975f4 remove hardcoded colors from setting's dialogs 2025-07-13 17:54:22 +02:00
Maximilian Dorninger
788bc79a1e Merge pull request #56
Fix: Session cookie not being transmitted when using http
2025-07-13 17:36:05 +02:00
maxDorninger
c8425d7949 apply the same changes to the redirecting cookie transport 2025-07-13 17:23:05 +02:00
maxDorninger
e2704b6b1f fix session cookie not being transmitted when using http instead of https 2025-07-13 17:21:24 +02:00
Maximilian Dorninger
ae121b903d Merge pull request #54 from maxdorninger/add-configuration-via-toml-file
Hotfix: fix downloads from Sabnzbd being in the wrong folders
2025-07-13 16:28:52 +02:00
maxDorninger
4b09471988 fix bug which causes Sabnzbd to put downloads into folders with wrong names 2025-07-13 15:48:17 +02:00
Maximilian Dorninger
3788eedb8b Merge pull request #53
Hotfix: fix qbittorrent not working
2025-07-13 01:01:40 +02:00
maxDorninger
be1dc0d03b fix qbittorrent client initialisation failing 2025-07-13 00:58:42 +02:00
Maximilian Dorninger
e741c0ea2e Merge pull request #52 from maxdorninger/add-configuration-via-toml-file
Hotfix: make alembic use new config class
2025-07-13 00:38:51 +02:00
maxDorninger
d9c6f2d068 remove unused import 2025-07-13 00:38:21 +02:00
maxDorninger
9a0b1f88bd remove print statement which leaks credentials 2025-07-13 00:37:26 +02:00
maxDorninger
f8745ab2ce fix alembic usenet migration 2025-07-13 00:28:58 +02:00
maxDorninger
41cd43d182 update documentation 2025-07-13 00:04:35 +02:00
maxDorninger
b5580b4fcc fix alembic not using new config 2025-07-13 00:01:16 +02:00
Maximilian Dorninger
f1b457e421 Merge pull request #50 from MahdiAkrami01/patch-1
Fix config mount path
2025-07-12 12:48:30 +02:00
Mahdi Akrami
0ebeca3d0f Fix config mount path 2025-07-12 08:50:40 +02:00
Maximilian Dorninger
9b3286391f Merge pull request #49 from maxdorninger/add-configuration-via-toml-file
hotfix: make delimiter 2 underscores instead of one for env variables
2025-07-11 19:31:40 +02:00
maxDorninger
3b16f8b3c3 fix wrong env variable name in docker file 2025-07-11 19:22:25 +02:00
maxDorninger
dc981b7d21 hotfix: make delimiter 2 underscores instead of one for env variables 2025-07-11 18:58:58 +02:00
Maximilian Dorninger
60fa1f9873 Merge pull request #48 from maxdorninger/add-configuration-via-toml-file
Add configuration via toml file and enhance documentation
2025-07-11 13:42:51 +02:00
maxDorninger
661e31eb50 update tests 2025-07-11 13:35:38 +02:00
maxDorninger
cdc3434b17 expand troubleshooting.md 2025-07-11 13:17:28 +02:00
maxDorninger
0aaf78e36e add reverse proxy examples to documentation 2025-07-11 13:14:06 +02:00
maxDorninger
8b9d355761 update README.md, template docker-compose.yaml and the documentation 2025-07-11 12:23:15 +02:00
maxDorninger
9aea4a9601 update README.md, template docker-compose.yaml and the documentation 2025-07-11 12:22:38 +02:00
maxDorninger
517042973b refine toml.config 2025-07-11 11:27:49 +02:00
maxDorninger
4cae93abeb refine toml.config and add back default value for host 2025-07-11 11:19:59 +02:00
maxDorninger
caccf48b65 refine the example config.toml 2025-07-11 10:44:43 +02:00
Maximilian Dorninger
4044c9c190 Update README.md 2025-07-11 10:34:29 +02:00
Maximilian Dorninger
94e604e151 Update README.md 2025-07-11 10:33:59 +02:00
Maximilian Dorninger
30dd1fb3a6 Update README.md 2025-07-11 10:33:04 +02:00
Maximilian Dorninger
90e874a927 Update README.md 2025-07-11 10:32:09 +02:00
Maximilian Dorninger
7a29c8554d Update README.md 2025-07-11 10:31:08 +02:00
maxDorninger
608bb338b2 refine the example config.toml 2025-07-11 01:05:08 +02:00
maxDorninger
fa7e03a640 add pydantic[toml] as dependency 2025-07-11 00:56:25 +02:00
maxDorninger
8f7c1035c0 remove instantiation calls from settings models 2025-07-11 00:56:04 +02:00
maxDorninger
9db9c85fc6 make all var names lower case and fix circular imports 2025-07-11 00:47:29 +02:00
maxDorninger
9173c3ad83 format files 2025-07-10 23:54:24 +02:00
maxDorninger
c446ec06c9 add template config.toml file 2025-07-10 23:49:47 +02:00
maxDorninger
d986f91e5e modify notification module config 2025-07-10 23:48:29 +02:00
maxDorninger
8a89a24f25 remove unused usenet_directory var and fix types of the configs 2025-07-10 22:33:44 +02:00
maxDorninger
7ce6de7f85 replace all the other config usages with allencompassing config 2025-07-10 22:25:05 +02:00
maxDorninger
1b784c35c1 add allencompassing config, replace basic config usage with allencompassing config usage 2025-07-10 21:47:37 +02:00
Maximilian Dorninger
fa0672c860 Update README.md 2025-07-10 21:02:08 +02:00
Maximilian Dorninger
4055f671f3 Merge pull request #43 from maxdorninger/add-usenet-support
Add usenet support and fix jackett using magnet link
2025-07-10 18:19:02 +02:00
maxDorninger
ce44a26aa6 fix formatting 2025-07-10 18:14:07 +02:00
maxDorninger
2b92ff1c13 fix sabnzbd 2025-07-10 18:11:28 +02:00
Maximilian Dorninger
05d30fd292 Update README.md 2025-07-10 15:44:01 +02:00
Maximilian Dorninger
65a0302635 Update README.md 2025-07-10 15:42:04 +02:00
Maximilian Dorninger
1cf4f8715e Update README.md 2025-07-10 15:41:28 +02:00
Maximilian Dorninger
471635f08a Merge pull request #45 from maxdorninger/add-supporters
add sponsors to "about page" and README.md
2025-07-10 15:36:23 +02:00
maxDorninger
f1f4033515 add github sponsors button to README.md 2025-07-10 15:33:15 +02:00
maxDorninger
469161ebc3 add donate button to sidebar 2025-07-10 15:30:03 +02:00
maxDorninger
9ef611df79 add sponsors to about page 2025-07-10 15:22:28 +02:00
maxDorninger
ffbf25a248 add sponsors to readme 2025-07-10 15:06:57 +02:00
Maximilian Dorninger
8e5e069263 Merge branch 'master' into add-usenet-support 2025-07-10 01:44:12 +02:00
maxDorninger
ee9575bb2b format files 2025-07-10 01:31:48 +02:00
maxDorninger
3c6f5710de add usenet information to frontend 2025-07-10 01:29:39 +02:00
maxDorninger
5935fbb584 fix switch up of True and False 2025-07-10 01:15:20 +02:00
maxDorninger
8812b8e25c add if's for adding download clients to the torrent manager class 2025-07-10 01:07:30 +02:00
maxDorninger
a41f106478 fix type conversion bug 2025-07-10 00:55:31 +02:00
maxDorninger
40fc8d4323 add torrent manager class and update torrent service class 2025-07-10 00:31:09 +02:00
maxDorninger
28349641c0 format files 2025-07-09 23:56:34 +02:00
maxDorninger
5fd563944f extracting qbittorrent logic into separate class 2025-07-09 23:10:53 +02:00
maxDorninger
d67e2019a8 add alembic migration for new usenet specific columns 2025-07-09 20:58:33 +02:00
maxDorninger
b6a5385864 format files 2025-07-09 20:54:50 +02:00
maxDorninger
1cf22b56d3 modify tests to use new indexer query result schema 2025-07-09 20:52:53 +02:00
maxDorninger
f2edfb076c add usenet support to indexer module, add make jackett and prowlarr search for either tv or movies 2025-07-09 20:52:01 +02:00
maxDorninger
47ef1bdc36 update readme 2025-07-06 16:56:33 +02:00
Maximilian Dorninger
01ba264697 Merge pull request #28 from JTCorrin/chore/improve-dev-experience
Chore/improve dev experience
2025-07-06 16:51:06 +02:00
Maximilian Dorninger
09eb86a97a Merge branch 'master' into chore/improve-dev-experience 2025-07-06 16:45:35 +02:00
maxDorninger
e17e6d8271 add usenet bool to various schemas/models 2025-07-06 15:17:16 +02:00
Maximilian Dorninger
1b90b0fd87 Merge pull request #38 from maxdorninger/change-github-workflows
push containers on PR's too
2025-07-06 13:13:52 +02:00
maxDorninger
ae13809275 push containers on PR's too 2025-07-06 12:24:49 +02:00
Maximilian Dorninger
9a6d4c77d0 Merge pull request #31 from jimmyhiggs337/postgres-fix
add healthcheck to postgres container in template docker-compose.yaml
2025-07-06 12:03:29 +02:00
Maximilian Dorninger
af5ae9e118 Merge pull request #37 from maxdorninger/fix-initial-migration
fix initial migration
2025-07-06 11:39:10 +02:00
maxDorninger
6336aa1c82 fix initial migration 2025-07-06 11:26:40 +02:00
Maximilian Dorninger
cc7781edba Merge pull request #36 from maxdorninger/increase-max-access-token-length-supported
Increase max access and refresh token length supported
2025-07-06 11:07:30 +02:00
maxDorninger
7fce31772f increase max refresh token length to 4096 2025-07-06 10:57:25 +02:00
maxDorninger
5364c73377 increase max access token length to 4096 2025-07-06 10:52:58 +02:00
James Higginbotham IV
4a0ae29aef fix postgres section docker-compose.yaml
add healthcheck to ensure postgres db is properly created
2025-07-04 14:04:52 -05:00
Joe Thomas
361288e6bd had a crack at fixing the initial migration 2025-07-04 12:31:07 +02:00
Joe Thomas
7dff3111bf updated gitignore 2025-07-03 17:48:59 +02:00
Joe Thomas
5e3b40bb43 updated some setup steps 2025-07-03 15:45:00 +02:00
Maximilian Dorninger
5b6111fb8b fix typo in docker-compose.yaml
remove trailing 'cat' from AUTH_ADMIN_EMAILS which breaks pydantics base-settings from correctly parsing the value
2025-07-03 13:59:52 +02:00
Maximilian Dorninger
1b2eb55c83 Add Screenshots to README 2025-07-02 21:03:44 +02:00
maxDorninger
80d2b25038 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	media_manager/metadataProvider/tvdb.py
2025-07-02 19:14:34 +02:00
maxDorninger
91f64b11b4 tvdb hotfix: getting wrong id 2025-07-02 19:13:54 +02:00
maxDorninger
51b81e6faf tvdb hotfix: getting wrong id 2025-07-02 19:13:13 +02:00
Maximilian Dorninger
25831f5f87 Update README.md 2025-07-02 17:41:53 +02:00
Maximilian Dorninger
bb54491f06 Merge pull request #18 from maxdorninger/add-notifications
Enhance Notifications, expand documentations and fix small bugs
2025-07-02 17:05:41 +02:00
maxDorninger
1c57830cfa remove unused function from notifications page 2025-07-02 16:54:57 +02:00
maxDorninger
82d327b76c add readme to metadata-relay 2025-07-02 16:51:32 +02:00
maxDorninger
5ed6080977 fix tvdb incorrectly parsing the json sometimes 2025-07-02 16:46:50 +02:00
maxDorninger
18edeba089 fix notifications page 2025-07-01 23:13:18 +02:00
maxDorninger
82ddadf8f7 format code and change schedule on which certain tasks are executed 2025-07-01 21:20:08 +02:00
maxDorninger
e8a04a1d71 remove obsolete code 2025-07-01 21:14:52 +02:00
maxDorninger
d25e4c86b8 update example docker compose 2025-07-01 21:14:43 +02:00
maxDorninger
892054c81b add a simple sequence diagram to the docs 2025-07-01 21:11:51 +02:00
maxDorninger
01f6c48583 update documentation to include the configuration of the notification module 2025-07-01 20:28:08 +02:00
Maximilian Dorninger
2bb2e6f471 Merge pull request #17 from maxdorninger/add-notifications
Add notifications
2025-07-01 19:05:09 +02:00
maxDorninger
96cd9a4d01 format files 2025-07-01 18:00:54 +02:00
maxDorninger
a43748d7b5 fix bugs in the backend 2025-07-01 17:54:33 +02:00
maxDorninger
8d512f665e add notifications to frontend 2025-07-01 17:54:23 +02:00
maxDorninger
9c27825532 fix the dockerfile of the frontend 2025-07-01 17:36:53 +02:00
maxDorninger
19bc4ca5e3 update frontend Dockerfile 2025-07-01 16:12:48 +02:00
maxDorninger
efc3846860 format files 2025-07-01 16:03:17 +02:00
maxDorninger
27c3c58cd9 update readme 2025-07-01 16:02:33 +02:00
maxDorninger
92e00f118c add notifications for movies and tv module 2025-07-01 16:01:57 +02:00
maxDorninger
c5da032506 add notifications for movies module 2025-07-01 15:28:59 +02:00
maxDorninger
4e04e11d8c add notification manager 2025-07-01 15:28:47 +02:00
maxDorninger
179dec0a7a add notificaton service providers (email, ntfy.sh, gotify and pushover) 2025-07-01 15:09:03 +02:00
maxDorninger
89b4fbb056 add notificaton module 2025-07-01 14:15:13 +02:00
maxDorninger
3088c65b09 fix bugs which causes imported torrents to not be marked as such, add try-except to extract archive function which prevents the import from stopping if the archives are already extracted, 2025-07-01 11:52:23 +02:00
maxDorninger
e008a34fc7 update dockerfile to include archive extraction tools 2025-07-01 11:52:23 +02:00
maxDorninger
b953445fc2 update detection of archives to be more accurate 2025-06-30 22:34:01 +02:00
maxDorninger
3799ae8712 format files 2025-06-30 21:32:34 +02:00
maxDorninger
40a1bbf904 format files and remove unused import 2025-06-30 20:55:36 +02:00
maxDorninger
7389db0d4c fix entrypoint.sh not being copied correctly 2025-06-30 20:49:05 +02:00
maxDorninger
ad7d6aab60 add healthcheck 2025-06-30 20:48:50 +02:00
maxDorninger
a7c582ee5c break up scheduled tasks 2025-06-30 20:48:39 +02:00
maxDorninger
690e4c2c1a fix missing mimetypes by adding mime-support package to backend docker image 2025-06-30 20:02:48 +02:00
maxDorninger
350d500993 fix movie repository 2025-06-30 19:36:20 +02:00
maxDorninger
1abec67144 update dockerfiles 2025-06-30 18:49:24 +02:00
maxDorninger
ba92399d8c fix wrong keyword being used for the argument 2025-06-30 18:47:27 +02:00
maxDorninger
b3d93bcbe2 Merge remote-tracking branch 'origin/master' 2025-06-30 18:08:52 +02:00
maxDorninger
aeab3b1bd1 fix small bug in the seasons page 2025-06-30 17:48:15 +02:00
Maximilian Dorninger
bf70fb7a2c Merge pull request #16 from maxdorninger/add-versions
Fix the dockerfiles and startup scripts
2025-06-30 17:18:33 +02:00
maxDorninger
4d67db6545 fix the docker files and startup scripts, also fix a bug in the hello world route of the backend 2025-06-30 17:17:21 +02:00
maxDorninger
a3a61710d3 trying to optimize runtime of worklfow building the frontend containers 2025-06-30 15:46:59 +02:00
495 changed files with 26775 additions and 13521 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
github: maxdorninger
buy_me_a_coffee: maxdorninger

View File

@@ -1,8 +1,8 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
title: '[BUG] '
labels: 'bug'
assignees: ''
---
@@ -23,9 +23,35 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Server Logs**
If applicable, add logs to help explain your problem.
**Browser Logs**
If applicable, add logs to help explain your problem.
**Version**
Frontend vX.X
Frontend vX.X
vX.X
**Additional context**
Add any other context about the problem here.
**docker-compose.yaml**
```yaml
YOUR DOCKER-COMPOSE HERE
```
**config.toml**
```toml
YOUR CONFIG HERE
```
- [ ] I understand, that without logs and/or screenshots and a detailed description of the problem, it is very hard to fix bugs.
- [ ] I have checked the [documentation](https://maxdorninger.github.io/MediaManager/) for help.
- [ ] I have searched the [issues](https://github.com/maxdorninger/MediaManager/issues) for similar issues and found none.

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

31
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- package-ecosystem: "npm"
directory: "/web"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
- package-ecosystem: "uv"
directory: "/metadata_relay"
schedule:
interval: "weekly"
open-pull-requests-limit: 5

View File

@@ -1,107 +0,0 @@
name: Build documentation
on:
push:
branches: [ "master" ]
paths:
- 'Writerside/**'
- '.github/workflows/build-docs.yml'
workflow_dispatch:
permissions:
contents: read
id-token: write
pages: write
env:
INSTANCE: 'Writerside/mm'
DOCKER_VERSION: '2025.04.8412'
jobs:
build:
runs-on: ubuntu-latest
outputs:
algolia_artifact: ${{ steps.define-ids.outputs.algolia_artifact }}
artifact: ${{ steps.define-ids.outputs.artifact }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Define instance id and artifacts
id: define-ids
run: |
INSTANCE=${INSTANCE#*/}
INSTANCE_ID_UPPER=$(echo "$INSTANCE" | tr '[:lower:]' '[:upper:]')
ARTIFACT="webHelp${INSTANCE_ID_UPPER}2-all.zip"
ALGOLIA_ARTIFACT="algolia-indexes-${INSTANCE_ID_UPPER}.zip"
# Print the values
echo "INSTANCE_ID_UPPER: $INSTANCE_ID_UPPER"
echo "ARTIFACT: $ARTIFACT"
echo "ALGOLIA_ARTIFACT: $ALGOLIA_ARTIFACT"
# Set the environment variables and outputs
echo "INSTANCE_ID_UPPER=$INSTANCE_ID_UPPER" >> $GITHUB_ENV
echo "ARTIFACT=$ARTIFACT" >> $GITHUB_ENV
echo "ALGOLIA_ARTIFACT=$ALGOLIA_ARTIFACT" >> $GITHUB_ENV
echo "artifact=$ARTIFACT" >> $GITHUB_OUTPUT
echo "algolia_artifact=$ALGOLIA_ARTIFACT" >> $GITHUB_OUTPUT
- name: Build docs using Writerside Docker builder
uses: JetBrains/writerside-github-action@v4
with:
instance: ${{ env.INSTANCE }}
docker-version: ${{ env.DOCKER_VERSION }}
- name: Save artifact with build results
uses: actions/upload-artifact@v4
with:
name: docs
path: |
artifacts/${{ steps.define-ids.outputs.artifact }}
artifacts/report.json
artifacts/${{ steps.define-ids.outputs.algolia_artifact }}
retention-days: 7
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: docs
path: artifacts
- name: Test documentation
uses: JetBrains/writerside-checker-action@v1
with:
instance: ${{ env.INSTANCE }}
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: [ build, test ]
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: docs
path: artifacts
- name: Unzip artifact
run: unzip -O UTF-8 -qq "artifacts/${{ needs.build.outputs.artifact }}" -d dir
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Package and upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: dir
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@@ -4,8 +4,6 @@ on:
push:
branches:
- master
tags:
- 'v*.*.*'
paths:
- 'media_manager/**'
- 'alembic/**'
@@ -15,6 +13,8 @@ on:
- 'uv.lock'
- '.github/workflows/build-push-backend.yml'
- 'tests/**'
- 'web/**'
pull_request:
paths:
- 'media_manager/**'
@@ -25,53 +25,153 @@ on:
- 'uv.lock'
- '.github/workflows/build-push-backend.yml'
- 'tests/**'
- 'web/**'
release:
types: [published]
workflow_dispatch:
jobs:
lint-code:
lint-backend:
name: Lint Python Code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v3
with:
src: "./media_manager"
run-tests:
needs: lint-code
name: Run Python Tests
lint-frontend:
name: Lint Frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Install the project
run: uv sync --locked --all-extras --dev
- name: Run tests
run: uv run pytest tests
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: './web/package-lock.json'
- name: Install dependencies
run: npm ci
working-directory: ./web
- name: Lint code
run: npm run lint
working-directory: ./web
build-and-push:
needs: run-tests
runs-on: ubuntu-latest
needs: [lint-frontend, lint-backend]
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
- arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
packages: write
env:
QUAY_ORG: ${{ secrets.QUAY_ORG || github.repository_owner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set repository name to lowercase
id: repo_name
run: echo "name=$(echo '${{ github.event.repository.name }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
with:
install: true
driver-opts: image=moby/buildkit:rootless
- name: Log in to GitHub Container Registry
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Quay
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Extract version
id: version
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
VERSION="${{ github.event.release.tag_name }}"
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
VERSION="${{ github.ref_name }}"
else
DATE_STAMP=$(date -u +'%Y.%m.%d')
VERSION="dev-${DATE_STAMP}-${{ github.run_number }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
VERSION_NO_V=${VERSION#v}
echo "version_no_v=$VERSION_NO_V" >> $GITHUB_OUTPUT
- name: Extract metadata (tags + labels)
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/mediamanager
quay.io/${{ env.QUAY_ORG }}/mediamanager
tags: |
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=raw,value=${{ steps.version.outputs.version }},enable=${{ github.event_name != 'release' }}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
flavor: |
suffix=-${{ matrix.arch }},onlatest=true
- name: Build and push arch image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/${{ matrix.arch }}
push: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ steps.version.outputs.version }}
BASE_PATH=
publish-manifests:
needs: build-and-push
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
env:
QUAY_ORG: ${{ secrets.QUAY_ORG }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set repository name to lowercase
id: repo_name
run: echo "name=$(echo '${{ github.event.repository.name }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
@@ -80,38 +180,60 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
- name: Log in to Quay
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Extract version
id: version
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
VERSION="${{ github.event.release.tag_name }}"
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
VERSION="${{ github.ref_name }}"
else
DATE_STAMP=$(date -u +'%Y.%m.%d')
VERSION="dev-${DATE_STAMP}-${{ github.run_number }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
VERSION_NO_V=${VERSION#v}
echo "version_no_v=$VERSION_NO_V" >> $GITHUB_OUTPUT
- name: Extract metadata (tags + labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/backend
images: |
ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/mediamanager
quay.io/${{ env.QUAY_ORG }}/mediamanager
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=ref,event=tag
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=raw,value=${{ steps.version.outputs.version }},enable=${{ github.event_name != 'release' }}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Extract version
id: version
- name: Create and push multi-arch manifests
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
else
VERSION="dev-${GITHUB_SHA::7}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
set -euo pipefail
mapfile -t TAGS <<< "${{ steps.meta.outputs.tags }}"
for TAG in "${TAGS[@]}"; do
docker buildx imagetools create \
--tag "${TAG}" \
"${TAG}-amd64" \
"${TAG}-arm64"
done
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ steps.version.outputs.version }}
- name: Inspect image (GHCR)
run: |
docker buildx imagetools inspect ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/mediamanager:${{ steps.version.outputs.version_no_v }}
- name: Inspect image (Quay)
run: |
docker buildx imagetools inspect quay.io/${{ env.QUAY_ORG }}/mediamanager:${{ steps.version.outputs.version_no_v }}

View File

@@ -1,93 +0,0 @@
name: Build and Push Frontend Docker Image
on:
push:
branches:
- master
tags:
- 'v*.*.*'
paths:
- 'web/**'
- '.github/workflows/build-push-frontend.yml'
pull_request:
paths:
- 'web/**'
- '.github/workflows/build-push-frontend.yml'
workflow_dispatch:
jobs:
lint:
name: Lint Frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
working-directory: ./web
- name: Lint code
run: npm run lint
working-directory: ./web
build-and-push:
needs: lint
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/frontend
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=ref,event=tag
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Extract version
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
else
VERSION="dev-${GITHUB_SHA::7}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: ./web
file: ./web/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ steps.version.outputs.version }}

View File

@@ -4,74 +4,200 @@ on:
push:
branches:
- master
tags:
- 'v*.*.*'
paths:
- 'metadata_relay/**'
- '.github/workflows/python-lint_metadata_relay.yaml'
- '.github/workflows/build-push-metadata_relay.yml'
pull_request:
paths:
- 'metadata_relay/**'
- '.github/workflows/python-lint_metadata_relay.yaml'
- '.github/workflows/build-push-metadata_relay.yml'
release:
types: [ published ]
workflow_dispatch:
jobs:
lint-code:
name: Lint Python Code
name: Lint Python Code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v3
- uses: astral-sh/ruff-action@v3
with:
src: "./metadata_relay"
build-and-push:
needs: lint-code
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
- arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
packages: write
env:
QUAY_ORG: ${{ secrets.QUAY_ORG || github.repository_owner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set repository name to lowercase
id: repo_name
run: echo "name=$(echo '${{ github.event.repository.name }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
install: true
driver-opts: image=moby/buildkit:rootless
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Quay
uses: docker/login-action@v3
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Extract version
id: version
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
VERSION="${{ github.event.release.tag_name }}"
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
VERSION="${{ github.ref_name }}"
else
DATE_STAMP=$(date -u +'%Y.%m.%d')
VERSION="dev-${DATE_STAMP}-${{ github.run_number }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
VERSION_NO_V=${VERSION#v}
echo "version_no_v=$VERSION_NO_V" >> $GITHUB_OUTPUT
- name: Extract metadata (tags + labels)
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay
quay.io/${{ env.QUAY_ORG }}/metadata_relay
tags: |
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=raw,value=${{ steps.version.outputs.version }},enable=${{ github.event_name != 'release' }}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
flavor: |
suffix=-${{ matrix.arch }},onlatest=true
- name: Build and push arch image
uses: docker/build-push-action@v6
with:
context: ./metadata_relay
file: ./metadata_relay/Dockerfile
platforms: linux/${{ matrix.arch }}
push: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ steps.version.outputs.version }}
publish-manifests:
needs: build-and-push
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
env:
QUAY_ORG: ${{ secrets.QUAY_ORG || github.repository_owner }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set repository name to lowercase
id: repo_name
run: echo "name=$(echo '${{ github.event.repository.name }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
- name: Log in to Quay
uses: docker/login-action@v3
with:
images: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}/metadata_relay
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Extract version
id: version
run: |
if [[ "${{ github.event_name }}" == "release" ]]; then
VERSION="${{ github.event.release.tag_name }}"
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
VERSION="${{ github.ref_name }}"
else
DATE_STAMP=$(date -u +'%Y.%m.%d')
VERSION="dev-${DATE_STAMP}-${{ github.run_number }}"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
VERSION_NO_V=${VERSION#v}
echo "version_no_v=$VERSION_NO_V" >> $GITHUB_OUTPUT
- name: Extract metadata (tags + labels)
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay
quay.io/${{ env.QUAY_ORG }}/metadata_relay
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=ref,event=tag
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=raw,value=${{ steps.version.outputs.version }},enable=${{ github.event_name != 'release' }}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: ./metadata_relay
file: ./metadata_relay/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ steps.meta.outputs.version }}
- name: Create and push multi-arch manifests
run: |
set -euo pipefail
mapfile -t TAGS <<< "${{ steps.meta.outputs.tags }}"
for TAG in "${TAGS[@]}"; do
docker buildx imagetools create \
--tag "${TAG}" \
"${TAG}-amd64" \
"${TAG}-arm64"
done
- name: Inspect image (GHCR)
run: |
docker buildx imagetools inspect ghcr.io/${{ github.repository_owner }}/${{ steps.repo_name.outputs.name }}/metadata_relay:${{ steps.version.outputs.version_no_v }}
- name: Inspect image (Quay)
run: |
docker buildx imagetools inspect quay.io/${{ env.QUAY_ORG }}/metadata_relay:${{ steps.version.outputs.version_no_v }}

62
.github/workflows/docs.yml vendored Normal file
View File

@@ -0,0 +1,62 @@
name: Publish docs via GitHub Pages
on:
push:
branches:
- master
tags:
- v*
workflow_dispatch:
inputs:
set_default_alias:
description: 'Alias to set as default (e.g. latest, master)'
required: false
default: 'latest'
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure Git Credentials
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
- uses: actions/setup-python@v6
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v4
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- name: Install dependencies
run: pip install mkdocs-material mike
- name: Deploy (master)
if: github.ref == 'refs/heads/master'
run: |
mike deploy --push --update-aliases master
- name: Deploy (tag)
if: startsWith(github.ref, 'refs/tags/v')
run: |
version=${GITHUB_REF#refs/tags/}
mike deploy --push --update-aliases $version latest --title "$version"
mike set-default --push latest
- name: Set Default (Manual)
if: github.event_name == 'workflow_dispatch' && github.event.inputs.set_default_alias != ''
run: |
mike set-default --push ${{ github.event.inputs.set_default_alias }}

View File

@@ -1,29 +0,0 @@
name: Ruff
on:
push:
branches:
- master
paths:
- 'media_manager/**'
- 'alembic/**'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/python-lint.yaml'
- 'tests/**'
pull_request:
paths:
- 'media_manager/**'
- 'alembic/**'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/python-lint.yaml'
- 'tests/**'
workflow_dispatch:
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v3
with:
src: "./media_manager"

View File

@@ -1,21 +0,0 @@
name: Ruff Metadata Relay
on:
push:
branches:
- master
paths:
- 'metadata_relay/**'
- '.github/workflows/python-lint_metadata_relay.yaml'
pull_request:
paths:
- 'metadata_relay/**'
- '.github/workflows/python-lint_metadata_relay.yaml'
workflow_dispatch:
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v3
with:
src: "./metadata_relay"

View File

@@ -1,31 +0,0 @@
name: Run Python Tests
on:
pull_request:
branches: [ master ]
paths:
- 'media_manager/**'
- 'alembic/**'
- 'alembic.ini'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/python-tests.yml'
- 'tests/**'
workflow_dispatch:
jobs:
run-tests:
name: Run Python Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Install the project
run: uv sync --locked --all-extras --dev
- name: Run tests
run: uv run pytest tests

View File

@@ -1,31 +0,0 @@
name: Lint Frontend
on:
pull_request:
paths:
- 'web/**'
- '.github/workflows/web-lint.yml'
push:
branches:
- master
paths:
- 'web/**'
- '.github/workflows/web-lint.yml'
jobs:
lint:
name: Lint Frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
working-directory: ./web
- name: Lint code
run: npm run lint
working-directory: ./web

16
.gitignore vendored
View File

@@ -9,6 +9,13 @@ tv/*
log.txt
res/*
media_manager/indexer/indexers/prowlarr.http
*.egg-info
.env
config
images
data
res
web/cache/
@@ -35,3 +42,12 @@ web/!.env.test
# Vite
web/vite.config.js.timestamp-*
web/vite.config.ts.timestamp-*
# pycache
__pycache__
# Postgres
/postgres
# MkDocs
site/

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
97409287+maxdorninger@users.noreply.github.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

33
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,33 @@
# Contributing to MediaManager
First off, thank you for considering contributing to MediaManager.
## Why
Following this guide helps me merge your PRs faster, prevents unnecessary back-and-forth and wasted effort.
## How to suggest a feature or enhancement
Open an issue which describes the feature you would like to
see, why you need it, and how it should work.
There we can discuss its scope and implementation.
## How to contribute
Generally, if you have any questions or need help on the implementation side of MediaManager,
just ask in the issue, or in a draft PR.
Also, see the contribution guide in the docs for information on how to setup the dev environment:
https://maxdorninger.github.io/MediaManager/
### For something that is a one or two line fix:
Make the change, and open a PR with a short description of what you changed and why.
### For something that is bigger than a one or two line fix:
Explain why you are making the change.
Be sure to give a rough overview on how your implementation works, and maybe any design decisions you made.
Also include any relevant limitations or trade-offs you made.
It's best to also open an issue first to discuss larger changes before you start working on them.

View File

@@ -1,40 +1,67 @@
FROM ghcr.io/astral-sh/uv:debian-slim AS builder
WORKDIR /app
FROM node:24-alpine AS frontend-build
WORKDIR /frontend
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates gcc python3-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY web/package*.json ./
RUN npm ci && npm cache clean --force
COPY pyproject.toml uv.lock ./
COPY web/ ./
RUN uv sync --locked
FROM ghcr.io/astral-sh/uv:debian-slim
ARG VERSION
LABEL version=${VERSION}
LABEL description="Docker image for the backend of MediaManager"
ARG BASE_PATH=""
RUN env PUBLIC_VERSION=${VERSION} PUBLIC_API_URL=${BASE_PATH} BASE_PATH=${BASE_PATH}/web npm run build
ENV IMAGE_DIRECTORY=/data/images \
TV_SHOW_DIRECTORY=/data/tv \
MOVIE_DIRECTORY=/data/movies \
TORRENT_DIRECTORY=/data/torrents \
OPENID_ENABLED=FALSE \
PUBLIC_VERSION=${VERSION}
FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim AS base
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates && \
apt-get install -y ca-certificates bash libtorrent21 gcc bc locales postgresql media-types mailcap curl gzip unzip tar 7zip bzip2 unar gosu && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
RUN locale-gen
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
# Create a non-root user and group
RUN groupadd -g 1000 mediamanager && \
useradd -m -u 1000 -g mediamanager mediamanager
FROM base AS dependencies
WORKDIR /app
# Ensure mediamanager owns /app
RUN chown -R mediamanager:mediamanager /app
COPY --from=builder /usr/local/lib/python3.*/site-packages /usr/local/lib/python3.*/site-packages/
USER mediamanager
COPY --chmod=755 mediamanager-backend-startup.sh .
COPY media_manager ./media_manager
COPY alembic ./alembic
COPY alembic.ini .
ENV UV_CACHE_DIR=/home/mediamanager/.cache/uv \
UV_LINK_MODE=copy
COPY --chown=mediamanager:mediamanager pyproject.toml uv.lock ./
RUN --mount=type=cache,target=/home/mediamanager/.cache/uv,uid=1000,gid=1000 \
uv sync --locked
FROM dependencies AS app
ARG VERSION
ARG BASE_PATH=""
LABEL author="github.com/maxdorninger"
LABEL version=${VERSION}
LABEL description="Docker image for MediaManager"
USER root
ENV PUBLIC_VERSION=${VERSION} \
CONFIG_DIR="/app/config" \
BASE_PATH=${BASE_PATH} \
FRONTEND_FILES_DIR="/app/web/build"
COPY --chown=mediamanager:mediamanager --chmod=755 mediamanager-startup.sh .
COPY --chown=mediamanager:mediamanager config.example.toml .
COPY --chown=mediamanager:mediamanager media_manager ./media_manager
COPY --chown=mediamanager:mediamanager alembic ./alembic
COPY --chown=mediamanager:mediamanager alembic.ini .
HEALTHCHECK CMD curl -f http://localhost:8000${BASE_PATH}/api/v1/health || exit 1
EXPOSE 8000
CMD ["/app/mediamanager-backend-startup.sh"]
CMD ["/app/mediamanager-startup.sh"]
FROM app AS production
COPY --chown=mediamanager:mediamanager --from=frontend-build /frontend/build /app/web/build

View File

@@ -629,8 +629,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
MediaManager, an automatic media downloader and organizer.
Copyright (C) 2025 Maximilian Dorninger
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published

49
Makefile Normal file
View File

@@ -0,0 +1,49 @@
SHELL := /bin/bash
# Docker Compose command (override if needed)
COMPOSE ?= docker compose
DC := $(COMPOSE) -f docker-compose.dev.yaml
# Log args passthrough, e.g.:
# make logs ARGS="--follow --tail=100"
ARGS ?=
# Service names (override if your compose uses different names)
APP_SVC ?= mediamanager
FRONTEND_SVC ?= frontend
.PHONY: help up down logs ps restartapp frontend
help:
@echo "Usage:"
@echo " All commands run using the dev docker compose file ($(DEV_FILE))"
@echo ""
@echo " make up # Development environment up, runs with --build flag to rebuild if necessary"
@echo " make down # Development environment down"
@echo " make logs ARGS=\"...\" # (Optional) Set ARGS like \"--follow --tail=100\""
@echo " make ps | restart # Check status or restart containers"
@echo " make app # Shell into $(APP_SVC) container"
@echo " make frontend # Shell into $(FRONTEND_SVC) container"
# Core lifecycle
up:
$(DC) up -d --build
down:
$(DC) down
logs:
$(DC) logs $(ARGS)
ps:
$(DC) ps
restart:
$(DC) restart
# Interactive shells (prefer bash, fallback to sh)
app:
@$(DC) exec -it $(APP_SVC) bash 2>/dev/null || $(DC) exec -it $(APP_SVC) sh
frontend:
@$(DC) exec -it $(FRONTEND_SVC) bash 2>/dev/null || $(DC) exec -it $(FRONTEND_SVC) sh

111
README.md
View File

@@ -1,7 +1,7 @@
<br />
<div align="center">
<a href="https://maxdorninger.github.io/MediaManager">
<img src="https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/Writerside/images/logo.svg" alt="Logo" width="260" height="260">
<a href="https://maxdorninger.github.io/MediaManager/">
<img src="https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/docs/assets/logo-with-text.svg" alt="Logo" width="800">
</a>
<h3 align="center">MediaManager</h3>
@@ -9,73 +9,94 @@
<p align="center">
Modern management system for your media library
<br />
<a href="https://maxdorninger.github.io/MediaManager/introduction.html"><strong>Explore the docs »</strong></a>
<a href="https://maxdorninger.github.io/MediaManager/"><strong>Explore the docs »</strong></a>
<br />
<a href="https://maxdorninger.github.io/MediaManager/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
<a href="https://github.com/maxdorninger/MediaManager/issues/new?labels=bug&template=bug_report.md">Report Bug</a>
&middot;
<a href="https://maxdorninger.github.io/MediaManager/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
<a href="https://github.com/maxdorninger/MediaManager/issues/new?template=feature_request.md">Request Feature</a>
</p>
</div>
MediaManager is 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
other services.
Key features:
- support for OAuth/OIDC
- support for TVDB and TMDB
- made to be deployed with Docker
## Quick Start
```
wget -O docker-compose.yaml https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/docker-compose.yaml
# Edit docker-compose.yaml to set the environment variables!
docker compose up -d
```sh
wget -O docker-compose.yaml https://github.com/maxdorninger/MediaManager/releases/latest/download/docker-compose.yaml
mkdir config
wget -O ./config/config.toml https://github.com/maxdorninger/MediaManager/releases/latest/download/config.example.toml
# you probably need to edit the config.toml file in the ./config directory, for more help see the documentation
docker compose up -d
```
### [View the docs for installation instructions and more](https://maxdorninger.github.io/MediaManager/configuration-overview.html#configuration-overview)
### [View the docs for installation instructions and more](https://maxdorninger.github.io/MediaManager/)
<!-- ROADMAP -->
## Roadmap
## Support MediaManager
- [x] support for more torrent indexers
- [x] fully automatic downloads
- [x] add tests
- [x] add more logs/errors
- [x] make API return proper error codes
- [x] optimize images for web in the backend
- [x] responsive ui
- [x] automatically update metadata of shows
- [x] automatically download new seasons/episodes of shows
- [x] add fallback to just copy files if hardlinks don't work
- [x] add check at startup if hardlinks work
- [x] create separate metadata relay service, so that api keys for TMDB and TVDB are not strictly needed
- [x] support for movies
- [x] expand README with more information and a quickstart guide
- [x] improve reliability of scheduled tasks
- [ ] add notification system
- [ ] add in-depth documentation on the architecture of the codebase
- [ ] make indexer module multithreaded
- [ ] add support for deluge and transmission
- [ ] add delete button for movies/TV shows
- [ ] rework prowlarr module (select which indexers to use, etc.)
- [ ] add sequence diagrams to the documentation
- [ ] _maybe_ rework the logo
- [ ] _maybe_ add support for configuration via toml config file
<a href="https://github.com/sponsors/maxdorninger" target="_blank">
<img src="https://img.shields.io/badge/Sponsor-Maximilian Dorninger-orange" alt="Sponsor @maxdorninger" />
</a>
See the [open issues](hhttps://maxdorninger.github.io/MediaManager/issues) for a full list of proposed features (and known issues).
<a href="https://buymeacoffee.com/maxdorninger" target="_blank">
<img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" >
</a>
## Check out the awesome sponsors of MediaManager ❤️
<a href="https://fosstodon.org/@aljazmerzen"><img src="https://github.com/aljazerzen.png" width="80px" alt="Aljaž Mur Eržen" /></a>&nbsp;&nbsp;
<a href="https://github.com/ldrrp"><img src="https://github.com/ldrrp.png" width="80px" alt="Luis Rodriguez" /></a>&nbsp;&nbsp;
<a href="https://github.com/brandon-dacrib"><img src="https://github.com/brandon-dacrib.png" width="80px" alt="Brandon P." /></a>&nbsp;&nbsp;
<a href="https://github.com/SeimusS"><img src="https://github.com/SeimusS.png" width="80px" alt="SeimusS" /></a>&nbsp;&nbsp;
<a href="https://github.com/HadrienKerlero"><img src="https://github.com/HadrienKerlero.png" width="80px" alt="HadrienKerlero" /></a>&nbsp;&nbsp;
<a href="https://github.com/keyxmakerx"><img src="https://github.com/keyxmakerx.png" width="80px" alt="keyxmakerx" /></a>&nbsp;&nbsp;
<a href="https://github.com/LITUATUI"><img src="https://github.com/LITUATUI.png" width="80px" alt="LITUATUI" /></a>&nbsp;&nbsp;
<a href="https://buymeacoffee.com/maxdorninger"><img src="https://cdn.buymeacoffee.com/uploads/profile_pictures/default/v2/B6CDBD/NI.png" width="80px" alt="Nicolas" /></a>&nbsp;&nbsp;
<a href="https://buymeacoffee.com/maxdorninger"><img src="https://cdn.buymeacoffee.com/uploads/profile_pictures/default/v2/DEBBB9/JO.png" width="80px" alt="Josh" /></a>&nbsp;&nbsp;
<a href="https://buymeacoffee.com/maxdorninger"><img src="https://cdn.buymeacoffee.com/uploads/profile_pictures/2025/11/2VeQ8sTGPhj4tiLy.jpg" width="80px" alt="PuppiestDoggo" /></a>&nbsp;&nbsp;
<a href="https://github.com/seferino-fernandez"><img src="https://avatars.githubusercontent.com/u/5546622" width="80px" alt="Seferino" /></a>&nbsp;&nbsp;
<a href="https://buymeacoffee.com/maxdorninger"><img src="https://cdn.buymeacoffee.com/uploads/profile_pictures/default/v2/EC9689/SY.png" width="80px" alt="syn" /></a>&nbsp;&nbsp;
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=maxdorninger/MediaManager&type=Date)](https://www.star-history.com/#maxdorninger/MediaManager&Date)
## Screenshots
<img width="1902" height="887" alt="Screenshot 2025-12-08 at 00 44 26" src="https://github.com/user-attachments/assets/4c3fbc73-6358-44ac-a948-0eb35ab116fd" />
<img width="1875" height="882" alt="Screenshot 2025-12-08 at 00 46 39" src="https://github.com/user-attachments/assets/75645cb6-236b-4bef-9a21-76bfd6d530f9" />
![Screenshot 2025-07-02 174616](https://github.com/user-attachments/assets/c3af4be8-b873-448c-8a4d-0d5db863aec7)
<img width="1883" height="890" alt="Screenshot 2025-12-08 at 00 48 23" src="https://github.com/user-attachments/assets/c5789559-5aa7-4c26-9442-a2b156e99b1c" />
![Screenshot 2025-06-28 222908](https://github.com/user-attachments/assets/193e1afd-dabb-42a2-ab28-59f2784371c7)
## Developer Quick Start
For the developer guide see the [Developer Guide](https://maxdorninger.github.io/MediaManager/).
<!-- LICENSE -->
## License
Distributed under the GPL 3.0. See `LICENSE.txt` for more information.
Distributed under the AGPL 3.0. See `LICENSE.txt` for more information.
<!-- ACKNOWLEDGMENTS -->
## Acknowledgments
Thanks to DigitalOcean for sponsoring the project!
[![DigitalOcean Referral Badge](https://web-platforms.sfo2.cdn.digitaloceanspaces.com/WWW/Badge%201.svg)](https://www.digitalocean.com/?refcode=4edf05429dca&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge)
* [Thanks to Pawel Czerwinski for the image on the login screen](https://unsplash.com/@pawel_czerwinski)

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE instance-profile
SYSTEM "https://resources.jetbrains.com/writerside/1.0/product-profile.dtd">
<instance-profile id="Writerside_libraries"
name="Writerside_libraries" is-library="true" start-page="notes.topic">
<toc-element topic="notes.topic"/>
</instance-profile>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE categories
SYSTEM "https://resources.jetbrains.com/writerside/1.0/categories.dtd">
<categories>
<category id="wrs" name="Writerside documentation" order="1"/>
</categories>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE buildprofiles SYSTEM "https://resources.jetbrains.com/writerside/1.0/build-profiles.dtd">
<buildprofiles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/build-profiles.xsd">
<variables></variables>
<build-profile instance="mm">
<variables>
<noindex-content>false</noindex-content>
<custom-favicons>favicon.ico</custom-favicons>
<header-logo>logo.svg</header-logo>
<download-title>Buy me a coffee ☕</download-title>
<download-page>https://buymeacoffee.com/maxdorninger</download-page>
<showDownloadButton>true</showDownloadButton>
<product-web-url>https://github.com/maxdorninger/MediaManager</product-web-url>
</variables>
</build-profile>
</buildprofiles>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,158 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg="http://www.w3.org/2000/svg"
version="1.1"
id="svg1"
width="2000"
height="2000"
viewBox="0 0 2000 2000"
sodipodi:docname="logo2.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xmlns="http://www.w3.org/2000/svg">
<defs
id="defs1">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1">
<path
d="M 0,1500 H 1500 V 0 H 0 Z"
id="path1"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path3"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath4">
<path
d="M -17.6886,1032.99 H 1106.27 V 238.53 H -17.6886 Z"
transform="translate(-319.61281,-1032.9941)"
id="path4"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath6">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path6"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath7">
<path
d="M 223.314,1226.85 H 1182.49 V 548.867 H 223.314 Z"
transform="translate(-894.64255,-548.86681)"
id="path7"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath9">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path9"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath10">
<path
d="M 301.561,1098.17 H 1517.73 V 238.53 H 301.561 Z"
transform="translate(-666.53282,-1098.1678)"
id="path10"/>
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath12">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
id="path12"/>
</clipPath>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="0.9075"
inkscape:cx="999.44904"
inkscape:cy="1000"
inkscape:window-width="3840"
inkscape:window-height="2054"
inkscape:window-x="3373"
inkscape:window-y="199"
inkscape:window-maximized="1"
inkscape:current-layer="g1">
<inkscape:page
x="0"
y="0"
inkscape:label="1"
id="page1"
width="2000"
height="2000"
margin="0"
bleed="0"/>
</sodipodi:namedview>
<g
id="g1"
inkscape:groupmode="layer"
inkscape:label="1">
<g
id="g2"
clip-path="url(#clipPath3)">
<path
d="M 0,0 H 1500 V 1500 H 0 Z"
style="fill:#9ed8f7;fill-opacity:0;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,0,2000)"
clip-path="url(#clipPath1)"
id="path2"/>
</g>
<g
opacity="0.720001"
id="g5"
clip-path="url(#clipPath6)">
<path
d="m 0,0 h 669.787 c 68.994,0 116.873,-68.746 92.95,-133.46 L 542.309,-729.728 c -14.382,-38.904 -51.472,-64.736 -92.95,-64.736 h -669.787 c -68.994,0 -116.873,68.746 -92.949,133.46 L -92.949,-64.736 C -78.567,-25.832 -41.478,0 0,0"
style="fill:#2842fc;fill-opacity:1;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,426.1504,622.67453)"
clip-path="url(#clipPath4)"
id="path5"/>
</g>
<g
opacity="0.720001"
id="g8"
clip-path="url(#clipPath9)">
<path
d="m 0,0 h -571.59 c -58.879,0 -99.738,58.667 -79.322,113.893 l 188.111,508.849 c 12.274,33.201 43.925,55.246 79.322,55.246 h 571.59 c 58.879,0 99.739,-58.667 79.322,-113.894 L 79.322,55.245 C 67.049,22.045 35.397,0 0,0"
style="fill:#ff5e00;fill-opacity:1;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,1192.8567,1268.1776)"
clip-path="url(#clipPath7)"
id="path8"/>
</g>
<g
opacity="0.75"
id="g11"
clip-path="url(#clipPath12)">
<path
d="m 0,0 h 724.733 c 74.654,0 126.46,-74.386 100.575,-144.408 L 586.797,-789.591 c -15.562,-42.096 -55.694,-70.047 -100.575,-70.047 h -724.733 c -74.654,0 -126.461,74.386 -100.574,144.409 l 238.511,645.182 C -85.013,-27.952 -44.88,0 0,0"
style="fill:#f20a4c;fill-opacity:1;fill-rule:nonzero;stroke:none"
transform="matrix(1.3333333,0,0,-1.3333333,888.7104,535.77627)"
clip-path="url(#clipPath10)"
id="path11"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE instance-profile
SYSTEM "https://resources.jetbrains.com/writerside/1.0/product-profile.dtd">
<instance-profile id="mm"
name="MediaManager"
start-page="introduction.md">
<toc-element topic="introduction.md"/>
<toc-element topic="configuration-overview.md"/>
<toc-element topic="User-Guide.md"/>
<toc-element topic="Configuration.md">
<toc-element topic="authentication-setup.md"/>
<toc-element topic="configuration-backend.md">
</toc-element>
<toc-element topic="Indexer-Settings.md"/>
<toc-element topic="configuration-frontend.md"/>
</toc-element>
<toc-element topic="troubleshooting.md"/>
<toc-element topic="developer-guide.md"/>
<toc-element topic="api-reference.md"/>
</instance-profile>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rules SYSTEM "https://resources.jetbrains.com/writerside/1.0/redirection-rules.dtd">
<rules>
<!-- format is as follows
<rule id="<unique id>">
<accepts>page.html</accepts>
</rule>
-->
<rule id="63c34f28">
<description>Created after removal of "Installation" from MediaManager</description>
<accepts>installation.html</accepts>
</rule>
<rule id="440cb672">
<description>Created after removal of "About MediaManager" from MediaManager</description>
<accepts>starter-topic.html</accepts>
</rule>
<rule id="666c8c31">
<description>Created after removal of "User Guide" from MediaManager</description>
<accepts>user-guide.html</accepts>
</rule>
<rule id="6822e619">
<description>Created after removal of "Quick Start Guide" from MediaManager</description>
<accepts>Quick-Start-Guide.html</accepts>
</rule>
<rule id="570cb9d1">
<description>Created after removal of "user-guide" from MediaManager</description>
<accepts>user-guide.html</accepts>
</rule>
</rules>

View File

@@ -1,6 +0,0 @@
# Configuration
The configuration of MediaManager is divided into backend and frontend settings, which can be set in your
`docker-compose.yaml` file or in separate `.env` files.
All settings are set as environment variables, because this makes backing up the configuration easier and allows for
easier sharing/transferring of the configuration.

View File

@@ -1,37 +0,0 @@
# Indexer Settings
## Prowlarr
### `PROWLARR_ENABLED`
Set to `True` to enable Prowlarr. Default is `False`. Example: `true`.
### `PROWLARR_API_KEY`
This is your Prowlarr API key. Example: `prowlarr_api_key`.
### `PROWLARR_URL`
Base URL of your Prowlarr instance. Default is `http://localhost:9696`. Example: `http://prowlarr:9696`.
## Jackett
### `JACKETT_ENABLED`
Set to `True` to enable Jackett. Default is `False`. Example: `true`.
### `JACKETT_API_KEY`
This is your Prowlarr API key. Example: `jackett_api_key`.
### `JACKETT_URL`
Base URL of your Prowlarr instance. Default is `http://localhost:9117`. Example: `http://prowlarr:9117`.
### `JACKETT_INDEXERS`
List of all indexers for Jackett to search through. Default is `all`. Example: `["1337x","0magnet"]`.
<note>
<include from="notes.topic" element-id="list-format"/>
</note>

View File

@@ -1,51 +0,0 @@
# Usage
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:__
<tabs>
<tab id="as-a-user" title="as a user">
<procedure title="Downloading/Requesting a show" id="request-show-user">
<step>Add a show on the "Add Show" page</step>
<step>After adding the show you will be redirected to the show's page.</step>
<step>There you can click the "Request Season" button.</step>
<step>Select one or more seasons that you want to download</step>
<step>Then select the "Min Quality", this will be the minimum resolution of the content to download.</step>
<step>Then select the "Wanted Quality", this will be the <strong>maximum</strong> resolution of the content to download.</step>
<step>Finally click Submit request, though this is not the last step!</step>
<step>An administrator first has to approve your request for download, only then will the requested content be downloaded.</step>
<p>Congratulation! You've downloaded a show.</p>
</procedure>
</tab>
<tab id="as-an-admin" title="as an admin">
<procedure title="Requesting a show" id="request-show-admin">
<step>Add a show on the "Add Show" page</step>
<step>After adding the show you will be redirected to the show's page.</step>
<step>There you can click the "Request Season" button.</step>
<step>Select one or more seasons that you want to download</step>
<step>Then select the "Min Quality", this will be the minimum resolution of the content to download.</step>
<step>Then select the "Wanted Quality", this will be the <strong>maximum</strong> resolution of the content to download.</step>
<step>Finally click Submit request, as you are an admin, your request will be automatically approved.</step>
<p>Congratulation! You've downloaded a show.</p>
</procedure>
<procedure title="Downloading a show" id="download-show-admin">
<p>You can only directly download a show if you are an admin!</p>
<step>Go to a show's page.</step>
<step>There you can click the "Download Season" button.</step>
<step>Enter the season's number that you want to download</step>
<step>Then optionally select the "File Path Suffix", <strong>it needs to be unique per season per show!</strong> </step>
<step>Then click "Download" on a torrent that you want to download.</step>
<p>Congratulation! You've downloaded a show.</p>
</procedure>
<procedure title="Managing requests" id="approving-request-admin">
<p>Users need their requests to be approved by an admin, to do this follow these steps:</p>
<step>Go to the "Requests" page.</step>
<step>There you can approve, delete or modify a user's request.</step>
</procedure>
</tab>
</tabs>

View File

@@ -1,8 +0,0 @@
# API Reference
Media Manager's backend is built with FastAPI, which automatically generates interactive API documentation.
* **Swagger UI** (typically available at `http://localhost:8000/docs`).
* **ReDoc** (typically available at `http://localhost:8000/redoc`).

View File

@@ -1,75 +0,0 @@
# Authentication
MediaManager supports multiple authentication methods. Email/password authentication is the default, but you can also
enable OpenID Connect (OAuth 2.0) for integration with external identity providers.
<note>
Note the lack of a trailing slash in some env vars like OPENID_CONFIGURATION_ENDPOINT. This is important.
</note>
## General Authentication Settings
### `AUTH_TOKEN_SECRET`
Strong secret key for signing JWTs (create with `openssl rand -hex 32`). This is a required field. Example:
`AUTH_TOKEN_SECRET=your_super_secret_key`.
### `AUTH_SESSION_LIFETIME`
Lifetime of user sessions in seconds. Default is `86400` (1 day). Example: `AUTH_SESSION_LIFETIME=604800` (1 week).
### `AUTH_ADMIN_EMAIL`
A list of email addresses for administrator accounts. This is a required field. Example:
`AUTH_ADMIN_EMAIL=admin@example.com`.
### `FRONTEND_URL`
The URL the frontend will be accessed from. This is a required field. Example: `https://mediamanager.example/`.
<note>
On login/registration, every user whose email is in <code>AUTH_ADMIN_EMAIL</code> will be granted admin privileges.
Users whose email is not in <code>AUTH_ADMIN_EMAIL</code> will be regular users and will need to be verified by an administrator,
this can be done in the settings page.
</note>
<tip>
<include from="notes.topic" element-id="list-format"/>
</tip>
## OpenID Connect (OAuth 2.0)
### `OPENID_ENABLED`
Enables OpenID authentication. Default is `FALSE`. Example: `TRUE`.
### `OPENID_CLIENT_ID`
Client ID from your OpenID provider.
### `OPENID_CLIENT_SECRET`
Client Secret from your OpenID provider.
### `OPENID_CONFIGURATION_ENDPOINT`
URL of your OpenID provider's discovery document (e.g., `.../.well-known/openid-configuration`). Example:
`https://authentik.example.com/application/o/mediamanager/.well-known/openid-configuration`.
### `OPENID_NAME`
Display name for this OpenID provider. Default is `OpenID`. Example: `Authentik`.
### Configuring OpenID Connect
1. Set `OPENID_ENABLED=TRUE`
2. Configure the following environment variables:
* `OPENID_CLIENT_ID`
* `OPENID_CLIENT_SECRET`
* `OPENID_CONFIGURATION_ENDPOINT`
* `OPENID_NAME` (optional)
* `FRONTEND_URL` (it is important that this is set correctly, as it is used for the redirect URIs)
3. Your OpenID server will likely want a redirect URI. This URL will be like:
`{FRONTEND_URL}/api/v1/auth/cookie/{OPENID_NAME}/callback`. The exact path depends on the `OPENID_NAME`.
4. Example URL: `https://mediamanager.example/api/v1/auth/cookie/Authentik/callback`

View File

@@ -1,153 +0,0 @@
# Backend
These variables configure the core backend application, database connections, authentication, and integrations.
<note>
<include from="notes.topic" element-id="list-format"/>
</note>
## General Settings
### `API_BASE_PATH`
The url base of the backend. Default is `/api/v1`.
### `CORS_URLS`
Enter a list of origins you are going to access the api from. Example: `["https://mm.example"]`.
## Database Settings
### `DB_HOST`
Hostname or IP of the PostgreSQL server. Default is `localhost`.
### `DB_PORT`
Port number of the PostgreSQL server. Default is `5432`.
### `DB_USER`
Username for PostgreSQL connection. Default is `MediaManager`.
### `DB_PASSWORD`
Password for the PostgreSQL user. Default is `MediaManager`.
### `DB_DBNAME`
Name of the PostgreSQL database. Default is `MediaManager`.
## Download Client Settings
Currently, only qBittorrent is supported as a download client. But support for other clients isn't unlikely in the
future.
### `QBITTORRENT_HOST`
Host of the QBittorrent API. Default is `localhost`. Example: `qbit.example.com`.
### `QBITTORRENT_PORT`
Port of the QBittorrent API. Default is `8080`. Example: `443`.
### `QBITTORRENT_USER`
Username for QBittorrent. Default is `admin`.
### `QBITTORRENT_PASSWORD`
Password for QBittorrent. Default is `admin`.
## Metadata Provider Settings
<note>
Note the lack of a trailing slash in some env vars like <code>TMDB_RELAY_URL</code>. This is important.
</note>
These settings configure the integrations with external metadata providers like The Movie Database (TMDB) and The TVDB.
### TMDB (The Movie Database)
TMDB is the primary metadata provider for MediaManager. It provides detailed information about movies and TV shows.
<tip>
Other software like Jellyfin use TMDB as well, so there won't be any metadata discrepancies.
</tip>
#### `TMDB_RELAY_URL`
If you want use your own TMDB relay service, set this to the URL of your own MetadataRelay. Otherwise, don't set it to
use the default relay.
Default: `https://metadata-relay.maxid.me/tmdb`.
### TVDB (The TVDB)
<warning>
The TVDB might provide false metadata, also it doesn't support some features of MediaManager like to show overviews, therfore TMDB is the preferred metadata provider.
</warning>
#### `TVDB_RELAY_URL`
If you want use your own TVDB relay service, set this to the URL of your own MetadataRelay. Otherwise, don't set it to
use the default relay.
Default: `https://metadata-relay.maxid.me/tvdb`.
### MetadataRelay
<note>
To use MediaManager <strong>you don't need to set up your own MetadataRelay</strong>, as the default relay which is hosted by me, the dev of MediaManager, should be sufficient for most purposes.
</note>
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, but not strictly needing your own because only me, the developer, needs to create accounts
for API keys.
You might want to use it if you want to avoid rate limits, to protect your privacy, or other reasons.
If you know Sonarr's Skyhook, this is similar to that.
#### Where to get API keys
Get an API key from [The Movie Database](https://www.themoviedb.org/settings/api). You can create
an account and generate a free API key in your account settings.
Get an API key from [The TVDB](https://thetvdb.com/auth/register). You can create an account and
generate a free API key in your account settings.
<tip>
If you want to use your own MetadataRelay, you can set the <code>TMDB_RELAY_URL</code> and/or <code>TVDB_RELAY_URL</code> to your own relay service.
</tip>
## Directory Settings
<note>
Normally you don't need to change these, as the default mountpoints are usually sufficient. In your <code>docker-compose.yaml</code>, you can just mount <code>/any/directory</code> to <code>/data/torrents</code>.
</note>
### `IMAGE_DIRECTORY`
Media images (posters, backdrops) will be stored here. Default is `/data/images`.
### `TV_DIRECTORY`
Location of TV show files. Default is `/data/tv`.
### `MOVIE_DIRECTORY`
Location of movie files. Default is `/data/movies`.
### `TORRENT_DIRECTORY`
Location of torrent files and downloads. Default is `/data/torrents`.
## Build Arguments (Dockerfile)
### `VERSION`
Labels the Docker image with a version. Passed during build (e.g., by GitHub Actions). Frontend uses this as
`PUBLIC_VERSION`. Example (in build command): `docker build --build-arg VERSION=1.2.3 .`

View File

@@ -1,25 +0,0 @@
# Frontend
## Environment Variables
### `PUBLIC_API_URL`
You (the browser) must reach the backend from this url. Default is `http://localhost:8000/api/v1`. Example:
`https://mediamanager.example.com/api/v1`.
## Build Arguments (web/Dockerfile)
**TODO: expand on this section**
To configure a url base path for the frontend, you need to build the frontend docker container, this is because
unfortunately SvelteKit needs to know the base path at build time.
### `BASE_URL`
Sets the base url path, it must begin with a slash and not end with one. Example (in build command):
`docker build --build-arg BASE_URL=/media -f web/Dockerfile .`
### `VERSION`
Sets the `PUBLIC_VERSION` environment variable at runtime in the frontend container. Passed during build. Example (in
build command): `docker build --build-arg VERSION=1.2.3 -f web/Dockerfile .`

View File

@@ -1,20 +0,0 @@
# Installation Guide
The recommended way to install and run Media Manager is using Docker and Docker Compose.
## Prerequisites
* Ensure Docker and Docker Compose are installed on your system.
* If you plan to use OAuth 2.0 / OpenID Connect for authentication, you will need an account and client credentials
from an OpenID provider (e.g., Authentik, Pocket ID).
## Setup
* Download the docker-compose.yaml from the MediaManager repo with the following command:
```
wget -o docker-compose.yaml https://raw.githubusercontent.com/maxdorninger/MediaManager/refs/heads/master/docker-compose.yaml
```
* Configure the necessary environment variables in your `docker-compose.yaml` file.
* For more information on the available configuration options, see the [Configuration section](Configuration.md) of the
documentation.

View File

@@ -1 +0,0 @@
# Contributing

View File

@@ -1,42 +0,0 @@
# Developer Guide
This section is for those who want to contribute to Media Manager or understand its internals.
### Source Code
- `media_manager/`: Backend FastAPI application (Python)
- `web/`: Frontend SvelteKit application (TypeScript)
### Backend Development
- Uses `uv` for dependency management (see `pyproject.toml` and `uv.lock`)
- Follows standard FastAPI project structure
- Database migrations are handled by Alembic (`alembic.ini`, `alembic/` directory)
### Frontend Development
- Uses `npm` for package management (see `web/package.json`)
- SvelteKit with TypeScript
### Contributing
- Please refer to the project's GitHub repository for contribution guidelines (e.g., forking, branching, pull requests)
- Consider opening an issue to discuss significant changes before starting work
## Tech Stack
### Backend
- Python with FastAPI
- SQLAlchemy
- Pydantic and Pydantic-Settings
### Frontend
- TypeScript with SvelteKit
- Tailwind CSS
- shadcn-svelte
### CI/CD
- GitHub Actions

View File

@@ -1,27 +0,0 @@
# MediaManager
MediaManager is 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.
It also provides an API to interact with the software programmatically, allowing for automation and integration with
other services.
## Screenshots
![screenshot-dashboard.png](screenshot-dashboard.png)
![screenshot-tv-dashboard.png](screenshot-tv-dashboard.png)
![screenshot-download-season.png](screenshot-download-season.png)
![screenshot-request-season.png](screenshot-request-season.png)
![screenshot-tv-torrents.png](screenshot-tv-torrents.png)
![screenshot-settings.png](screenshot-settings.png)
![screenshot-login.png](screenshot-login.png)

View File

@@ -1,8 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/html-entities.dtd">
<topic id="notes"
is-library="true" title="notes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd">
<snippet id="list-format">
Lists have to be formatted like this: <code>["item1", "item2", "item3"]</code>. Note the double quotes.
</snippet>
</topic>

View File

@@ -1,28 +0,0 @@
# Troubleshooting
<note>
Note the lack of a trailing slash in some env vars like FRONTEND_URL. This is important.
</note>
<tip>
Always check the container and browser logs for more specific error messages
</tip>
## Authentication Issues (OIDC)
* Verify `OPENID_CLIENT_ID`, `OPENID_CLIENT_SECRET`, and `OPENID_CONFIGURATION_ENDPOINT` are correct.
* Ensure the `FRONTEND_URL` is accurate and that your OpenID provider has the correct redirect URI whitelisted (
e.g., `http://your-frontend-url/api/v1/auth/cookie/Authentik/callback`).
* Check backend logs for errors from `httpx_oauth` or `fastapi-users`.
## CORS Errors
* Ensure `FRONTEND_URL` is correctly set.
* Ensure your frontend's url is listed in `CORS_URLS`.
## Data Not Appearing / File Issues
* Verify that the volume mounts for `IMAGE_DIRECTORY`, `TV_DIRECTORY`, `MOVIE_DIRECTORY`, and `TORRENT_DIRECTORY` in
your `docker-compose.yaml` are correctly pointing to your media folders on the host machine.
* Check file and directory permissions for the user running the Docker container (or the `node` user inside the
containers).

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE vars SYSTEM "https://resources.jetbrains.com/writerside/1.0/vars.dtd">
<vars>
<var name="product" value="Writerside"/>
</vars>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ihp SYSTEM "https://resources.jetbrains.com/writerside/1.0/ihp.dtd">
<ihp version="2.0">
<topics dir="topics" web-path="topics"/>
<images dir="images" web-path="MediaManager"/>
<instance src="mm.tree"/>
<instance src="Writerside_libraries.tree"/>
</ihp>

View File

@@ -1,14 +1,16 @@
import sys
sys.path = ["", ".."] + sys.path[1:]
sys.path = ["", "..", *sys.path[1:]]
from logging.config import fileConfig # noqa: E402
from sqlalchemy import ( # noqa: E402
engine_from_config,
pool,
)
from alembic import context # noqa: E402
from pydantic_settings import BaseSettings, SettingsConfigDict # noqa: E402
from sqlalchemy import engine_from_config # noqa: E402
from sqlalchemy import pool # noqa: E402
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
@@ -24,28 +26,37 @@ if config.config_file_name is not None:
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
from media_manager.auth.db import User, OAuthAccount # noqa: E402
from media_manager.indexer.models import IndexerQueryResult # noqa: E402
from media_manager.torrent.models import Torrent # noqa: E402
from media_manager.tv.models import Show, Season, Episode, SeasonFile, SeasonRequest # noqa: E402
from media_manager.auth.db import OAuthAccount, User # noqa: E402
from media_manager.config import MediaManagerConfig # noqa: E402
from media_manager.database import Base # noqa: E402
from media_manager.indexer.models import IndexerQueryResult # noqa: E402
from media_manager.movies.models import Movie, MovieFile # noqa: E402
from media_manager.notification.models import Notification # noqa: E402
from media_manager.torrent.models import Torrent # noqa: E402
from media_manager.tv.models import ( # noqa: E402
Episode,
EpisodeFile,
Season,
Show,
)
target_metadata = Base.metadata
# this is to keep pycharm from complaining about/optimizing unused imports
# noinspection PyStatementEffect
(
User,
OAuthAccount,
IndexerQueryResult,
Torrent,
Show,
Season,
Episode,
SeasonFile,
SeasonRequest,
)
__all__ = [
"Episode",
"EpisodeFile",
"IndexerQueryResult",
"Movie",
"MovieFile",
"Notification",
"OAuthAccount",
"Season",
"Show",
"Torrent",
"User",
]
# other values from the config, defined by the needs of env.py,
@@ -54,29 +65,8 @@ target_metadata = Base.metadata
# ... etc.
class DbConfig(BaseSettings):
model_config = SettingsConfigDict(env_prefix="DB_")
HOST: str = "localhost"
PORT: int = 5432
USER: str = "MediaManager"
PASSWORD: str = "MediaManager"
DBNAME: str = "MediaManager"
db_config = DbConfig()
db_url = (
"postgresql+psycopg"
+ "://"
+ db_config.USER
+ ":"
+ db_config.PASSWORD
+ "@"
+ db_config.HOST
+ ":"
+ str(db_config.PORT)
+ "/"
+ db_config.DBNAME
)
db_config = MediaManagerConfig().database
db_url = f"postgresql+psycopg://{db_config.user}:{db_config.password}@{db_config.host}:{db_config.port}/{db_config.dbname}"
config.set_main_option("sqlalchemy.url", db_url)
@@ -112,6 +102,18 @@ def run_migrations_online() -> None:
and associate a connection with the context.
"""
def include_object(
_object: object | None,
name: str | None,
type_: str | None,
_reflected: bool | None,
_compare_to: object | None,
) -> bool:
if type_ == "table" and name == "apscheduler_jobs":
return False
return True
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
@@ -119,7 +121,11 @@ def run_migrations_online() -> None:
)
with connectable.connect() as connection:
context.configure(connection=connection, target_metadata=target_metadata)
context.configure(
connection=connection,
target_metadata=target_metadata,
include_object=include_object,
)
with context.begin_transaction():
context.run_migrations()

View File

@@ -0,0 +1,37 @@
"""add original_language columns to show and movie tables
Revision ID: 16e78af9e5bf
Revises: eb0bd3cc1852
Create Date: 2025-12-13 18:47:02.146038
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "16e78af9e5bf"
down_revision: Union[str, None] = "eb0bd3cc1852"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# Add original_language column to show table
op.add_column("show", sa.Column("original_language", sa.String(10), nullable=True))
# Add original_language column to movie table
op.add_column("movie", sa.Column("original_language", sa.String(10), nullable=True))
def downgrade() -> None:
"""Downgrade schema."""
# Remove original_language column from movie table
op.drop_column("movie", "original_language")
# Remove original_language column from show table
op.drop_column("show", "original_language")

View File

@@ -0,0 +1,41 @@
"""Add library field to Movie and Show tables
Revision ID: 1801d9f5a275
Revises: 333866afcd2c
Create Date: 2025-07-16 01:09:44.045395
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "1801d9f5a275"
down_revision: Union[str, None] = "333866afcd2c"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
op.add_column(
"movie",
sa.Column(
"library", sa.String(), nullable=False, server_default=sa.text("'Default'")
),
)
op.add_column(
"show",
sa.Column(
"library", sa.String(), nullable=False, server_default=sa.text("'Default'")
),
)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_column("show", "library")
op.drop_column("movie", "library")

View File

@@ -8,9 +8,9 @@ Create Date: 2025-06-22 13:46:01.973406
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "1f340754640a"

View File

@@ -0,0 +1,45 @@
"""increase_access_token_length
Revision ID: 21a19f0675f9
Revises: 1f340754640a
Create Date: 2025-07-06 10:49:08.814496
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "21a19f0675f9"
down_revision: Union[str, None] = "1f340754640a"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"oauth_account",
"access_token",
existing_type=sa.VARCHAR(length=1024),
type_=sa.String(length=4096),
existing_nullable=False,
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"oauth_account",
"access_token",
existing_type=sa.String(length=4096),
type_=sa.VARCHAR(length=1024),
existing_nullable=False,
)
# ### end Alembic commands ###

View File

@@ -0,0 +1,35 @@
"""add imdb_id fields
Revision ID: 2c61f662ca9e
Revises: 16e78af9e5bf
Create Date: 2025-12-23 19:42:09.593945
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "2c61f662ca9e"
down_revision: Union[str, None] = "16e78af9e5bf"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("movie", sa.Column("imdb_id", sa.String(), nullable=True))
op.add_column("show", sa.Column("imdb_id", sa.String(), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("show", "imdb_id")
op.drop_column("movie", "imdb_id")
# ### end Alembic commands ###

View File

@@ -0,0 +1,50 @@
"""add-usenet-columns
Revision ID: 333866afcd2c
Revises: aa4689f80796
Create Date: 2025-07-09 20:55:42.338629
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "333866afcd2c"
down_revision: Union[str, None] = "aa4689f80796"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"indexer_query_result",
sa.Column(
"usenet", sa.Boolean(), nullable=False, server_default=sa.text("false")
),
)
op.add_column(
"indexer_query_result",
sa.Column("age", sa.Integer(), nullable=False, server_default=sa.text("0")),
)
op.add_column(
"torrent",
sa.Column(
"usenet", sa.Boolean(), nullable=False, server_default=sa.text("false")
),
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("torrent", "usenet")
op.drop_column("indexer_query_result", "age")
op.drop_column("indexer_query_result", "usenet")
# ### end Alembic commands ###

View File

@@ -0,0 +1,46 @@
"""create episode file table and add episode column to indexerqueryresult
Revision ID: 3a8fbd71e2c2
Revises: 9f3c1b2a4d8e
Create Date: 2026-01-08 13:43:00
"""
from typing import Sequence, Union
from alembic import op
from sqlalchemy.dialects import postgresql
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "3a8fbd71e2c2"
down_revision: Union[str, None] = "9f3c1b2a4d8e"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
quality_enum = postgresql.ENUM("uhd", "fullhd", "hd", "sd", "unknown", name="quality",
create_type=False,
)
# Create episode file table
op.create_table(
"episode_file",
sa.Column("episode_id", sa.UUID(), nullable=False),
sa.Column("torrent_id", sa.UUID(), nullable=True),
sa.Column("file_path_suffix", sa.String(), nullable=False),
sa.Column("quality", quality_enum, nullable=False),
sa.ForeignKeyConstraint(["episode_id"], ["episode.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["torrent_id"], ["torrent.id"], ondelete="SET NULL"),
sa.PrimaryKeyConstraint("episode_id", "file_path_suffix"),
)
# Add episode column to indexerqueryresult
op.add_column(
"indexer_query_result", sa.Column("episode", postgresql.ARRAY(sa.Integer()), nullable=True),
)
def downgrade() -> None:
op.drop_table("episode_file")
op.drop_column("indexer_query_result", "episode")

View File

@@ -0,0 +1,36 @@
"""Add score field to IndexerQueryResult table
Revision ID: 5299dfed220b
Revises: 1801d9f5a275
Create Date: 2025-07-16 23:24:37.931188
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "5299dfed220b"
down_revision: Union[str, None] = "1801d9f5a275"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"indexer_query_result",
sa.Column("score", sa.Integer(), nullable=False, server_default=sa.text("0")),
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("indexer_query_result", "score")
# ### end Alembic commands ###

View File

@@ -8,9 +8,9 @@ Create Date: 2025-06-10 21:25:27.871064
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "7508237d5bc2"

View File

@@ -8,6 +8,10 @@ Create Date: 2025-05-27 21:36:18.532068
from typing import Sequence, Union
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "93fb07842385"
@@ -19,6 +23,230 @@ depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
# Create user table
op.create_table(
"user",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("email", sa.String(length=320), nullable=False),
sa.Column("hashed_password", sa.String(length=1024), nullable=False),
sa.Column("is_active", sa.Boolean(), nullable=False),
sa.Column("is_superuser", sa.Boolean(), nullable=False),
sa.Column("is_verified", sa.Boolean(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_index(op.f("ix_user_email"), "user", ["email"], unique=True)
# Create oauth account table
op.create_table(
"oauth_account",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("oauth_name", sa.String(length=100), nullable=False),
sa.Column("access_token", sa.String(length=1024), nullable=False),
sa.Column("expires_at", sa.Integer(), nullable=True),
sa.Column("refresh_token", sa.String(length=1024), nullable=True),
sa.Column("account_id", sa.String(length=320), nullable=False),
sa.Column("account_email", sa.String(length=320), nullable=False),
sa.Column("user_id", sa.UUID(), nullable=False),
sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="cascade"),
sa.PrimaryKeyConstraint("id"),
)
op.create_index(
op.f("ix_oauth_account_account_id"),
"oauth_account",
["account_id"],
unique=False,
)
op.create_index(
op.f("ix_oauth_account_oauth_name"),
"oauth_account",
["oauth_name"],
unique=False,
)
# Create torrent table
op.create_table(
"torrent",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column(
"status",
sa.Enum(
"finished", "downloading", "error", "unknown", name="torrentstatus"
),
nullable=False,
),
sa.Column("title", sa.String(), nullable=False),
sa.Column(
"quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.Column("imported", sa.Boolean(), nullable=False),
sa.Column("hash", sa.String(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
# Create indexer query result table
op.create_table(
"indexer_query_result",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("title", sa.String(), nullable=False),
sa.Column("download_url", sa.String(), nullable=False),
sa.Column("seeders", sa.Integer(), nullable=False),
sa.Column("flags", postgresql.ARRAY(sa.String()), nullable=True),
sa.Column(
"quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.Column("season", postgresql.ARRAY(sa.Integer()), nullable=True),
sa.Column("size", sa.BigInteger(), nullable=True),
sa.PrimaryKeyConstraint("id"),
)
# Create notification table
op.create_table(
"notification",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("message", sa.String(), nullable=False),
sa.Column("read", sa.Boolean(), nullable=False),
sa.Column("timestamp", sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
# Create show table
op.create_table(
"show",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("external_id", sa.Integer(), nullable=False),
sa.Column("metadata_provider", sa.String(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("overview", sa.String(), nullable=False),
sa.Column("year", sa.Integer(), nullable=True),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("external_id", "metadata_provider"),
)
# Create movie table
op.create_table(
"movie",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("external_id", sa.Integer(), nullable=False),
sa.Column("metadata_provider", sa.String(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("overview", sa.String(), nullable=False),
sa.Column("year", sa.Integer(), nullable=True),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("external_id", "metadata_provider"),
)
# Create season table
op.create_table(
"season",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("show_id", sa.UUID(), nullable=False),
sa.Column("number", sa.Integer(), nullable=False),
sa.Column("external_id", sa.Integer(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("overview", sa.String(), nullable=False),
sa.ForeignKeyConstraint(["show_id"], ["show.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("show_id", "number"),
)
# Create movie file table
op.create_table(
"movie_file",
sa.Column("movie_id", sa.UUID(), nullable=False),
sa.Column("file_path_suffix", sa.String(), nullable=False),
sa.Column(
"quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.Column("torrent_id", sa.UUID(), nullable=True),
sa.ForeignKeyConstraint(["movie_id"], ["movie.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["torrent_id"], ["torrent.id"], ondelete="SET NULL"),
sa.PrimaryKeyConstraint("movie_id", "file_path_suffix"),
)
# Create movie request table
op.create_table(
"movie_request",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("movie_id", sa.UUID(), nullable=False),
sa.Column(
"wanted_quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.Column(
"min_quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.Column("authorized", sa.Boolean(), nullable=False),
sa.Column("requested_by_id", sa.UUID(), nullable=True),
sa.Column("authorized_by_id", sa.UUID(), nullable=True),
sa.ForeignKeyConstraint(["authorized_by_id"], ["user.id"], ondelete="SET NULL"),
sa.ForeignKeyConstraint(["movie_id"], ["movie.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["requested_by_id"], ["user.id"], ondelete="SET NULL"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("movie_id", "wanted_quality"),
)
# Create episode table
op.create_table(
"episode",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("season_id", sa.UUID(), nullable=False),
sa.Column("number", sa.Integer(), nullable=False),
sa.Column("external_id", sa.Integer(), nullable=False),
sa.Column("title", sa.String(), nullable=False),
sa.ForeignKeyConstraint(["season_id"], ["season.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("season_id", "number"),
)
# Create season file table
op.create_table(
"season_file",
sa.Column("season_id", sa.UUID(), nullable=False),
sa.Column("torrent_id", sa.UUID(), nullable=True),
sa.Column("file_path_suffix", sa.String(), nullable=False),
sa.Column(
"quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.ForeignKeyConstraint(["season_id"], ["season.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["torrent_id"], ["torrent.id"], ondelete="SET NULL"),
sa.PrimaryKeyConstraint("season_id", "file_path_suffix"),
)
# Create season request table
op.create_table(
"season_request",
sa.Column("id", sa.UUID(), nullable=False),
sa.Column("season_id", sa.UUID(), nullable=False),
sa.Column(
"wanted_quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.Column(
"min_quality",
sa.Enum("uhd", "fullhd", "hd", "sd", "unknown", name="quality"),
nullable=False,
),
sa.Column("requested_by_id", sa.UUID(), nullable=True),
sa.Column("authorized", sa.Boolean(), nullable=False),
sa.Column("authorized_by_id", sa.UUID(), nullable=True),
sa.ForeignKeyConstraint(["authorized_by_id"], ["user.id"], ondelete="SET NULL"),
sa.ForeignKeyConstraint(["requested_by_id"], ["user.id"], ondelete="SET NULL"),
sa.ForeignKeyConstraint(["season_id"], ["season.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("season_id", "wanted_quality"),
)
# ### end Alembic commands ###
@@ -26,5 +254,20 @@ def upgrade() -> None:
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("season_request")
op.drop_table("season_file")
op.drop_table("episode")
op.drop_table("movie_request")
op.drop_table("movie_file")
op.drop_table("season")
op.drop_table("movie")
op.drop_table("show")
op.drop_table("notification")
op.drop_table("indexer_query_result")
op.drop_table("torrent")
op.drop_index(op.f("ix_oauth_account_oauth_name"), table_name="oauth_account")
op.drop_index(op.f("ix_oauth_account_account_id"), table_name="oauth_account")
op.drop_table("oauth_account")
op.drop_index(op.f("ix_user_email"), table_name="user")
op.drop_table("user")
# ### end Alembic commands ###

View File

@@ -0,0 +1,31 @@
"""add overview column to episode table
Revision ID: 9f3c1b2a4d8e
Revises: 2c61f662ca9e
Create Date: 2025-12-29 21:45:00
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "9f3c1b2a4d8e"
down_revision: Union[str, None] = "2c61f662ca9e"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# Add overview to episode table
op.add_column(
"episode",
sa.Column("overview", sa.Text(), nullable=True),
)
def downgrade() -> None:
op.drop_column("episode", "overview")

View File

@@ -0,0 +1,71 @@
"""migrate season files to episode files and drop the legacy table
Revision ID: a6f714d3c8b9
Revises: 16e78af9e5bf
Create Date: 2026-02-22 16:30:00
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = "a6f714d3c8b9"
down_revision: Union[str, None] = "3a8fbd71e2c2"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Copy season_file records into episode_file and remove the legacy table."""
op.execute(
"""
INSERT INTO episode_file (episode_id, torrent_id, file_path_suffix, quality)
SELECT episode.id, season_file.torrent_id, season_file.file_path_suffix, season_file.quality
FROM season_file
JOIN season ON season.id = season_file.season_id
JOIN episode ON episode.season_id = season.id
LEFT JOIN episode_file ON
episode_file.episode_id = episode.id
AND episode_file.file_path_suffix = season_file.file_path_suffix
WHERE episode_file.episode_id IS NULL
"""
)
op.drop_table("season_file")
def downgrade() -> None:
"""Recreate season_file, repopulate it from episode_file, and keep both tables."""
quality_enum = postgresql.ENUM(
"uhd", "fullhd", "hd", "sd", "unknown", name="quality", create_type=False
)
op.create_table(
"season_file",
sa.Column("season_id", sa.UUID(), nullable=False),
sa.Column("torrent_id", sa.UUID(), nullable=True),
sa.Column("file_path_suffix", sa.String(), nullable=False),
sa.Column("quality", quality_enum, nullable=False),
sa.ForeignKeyConstraint(["season_id"], ["season.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["torrent_id"], ["torrent.id"], ondelete="SET NULL"),
sa.PrimaryKeyConstraint("season_id", "file_path_suffix"),
)
op.execute(
"""
INSERT INTO season_file (season_id, torrent_id, file_path_suffix, quality)
SELECT DISTINCT ON (episode.season_id, episode_file.file_path_suffix)
episode.season_id,
episode_file.torrent_id,
episode_file.file_path_suffix,
episode_file.quality
FROM episode_file
JOIN episode ON episode.id = episode_file.episode_id
ORDER BY episode.season_id, episode_file.file_path_suffix, episode_file.torrent_id, episode_file.quality
"""
)

View File

@@ -0,0 +1,45 @@
"""increase_refresh_token_length
Revision ID: aa4689f80796
Revises: 21a19f0675f9
Create Date: 2025-07-06 10:54:19.714809
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "aa4689f80796"
down_revision: Union[str, None] = "21a19f0675f9"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"oauth_account",
"refresh_token",
existing_type=sa.VARCHAR(length=1024),
type_=sa.String(length=4096),
existing_nullable=True,
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"oauth_account",
"refresh_token",
existing_type=sa.String(length=4096),
type_=sa.VARCHAR(length=1024),
existing_nullable=True,
)
# ### end Alembic commands ###

View File

@@ -0,0 +1,65 @@
"""remove requests
Revision ID: e60ae827ed98
Revises: a6f714d3c8b9
Create Date: 2026-02-22 18:07:12.866130
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = 'e60ae827ed98'
down_revision: Union[str, None] = 'a6f714d3c8b9'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('movie_request')
op.drop_table('season_request')
op.alter_column('episode', 'overview',
existing_type=sa.TEXT(),
type_=sa.String(),
existing_nullable=True)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('season_request',
sa.Column('id', sa.UUID(), autoincrement=False, nullable=False),
sa.Column('season_id', sa.UUID(), autoincrement=False, nullable=False),
sa.Column('wanted_quality', postgresql.ENUM('uhd', 'fullhd', 'hd', 'sd', 'unknown', name='quality'), autoincrement=False, nullable=False),
sa.Column('min_quality', postgresql.ENUM('uhd', 'fullhd', 'hd', 'sd', 'unknown', name='quality'), autoincrement=False, nullable=False),
sa.Column('requested_by_id', sa.UUID(), autoincrement=False, nullable=True),
sa.Column('authorized', sa.BOOLEAN(), autoincrement=False, nullable=False),
sa.Column('authorized_by_id', sa.UUID(), autoincrement=False, nullable=True),
sa.ForeignKeyConstraint(['authorized_by_id'], ['user.id'], name=op.f('season_request_authorized_by_id_fkey'), ondelete='SET NULL'),
sa.ForeignKeyConstraint(['requested_by_id'], ['user.id'], name=op.f('season_request_requested_by_id_fkey'), ondelete='SET NULL'),
sa.ForeignKeyConstraint(['season_id'], ['season.id'], name=op.f('season_request_season_id_fkey'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id', name=op.f('season_request_pkey')),
sa.UniqueConstraint('season_id', 'wanted_quality', name=op.f('season_request_season_id_wanted_quality_key'), postgresql_include=[], postgresql_nulls_not_distinct=False)
)
op.create_table('movie_request',
sa.Column('id', sa.UUID(), autoincrement=False, nullable=False),
sa.Column('movie_id', sa.UUID(), autoincrement=False, nullable=False),
sa.Column('wanted_quality', postgresql.ENUM('uhd', 'fullhd', 'hd', 'sd', 'unknown', name='quality'), autoincrement=False, nullable=False),
sa.Column('min_quality', postgresql.ENUM('uhd', 'fullhd', 'hd', 'sd', 'unknown', name='quality'), autoincrement=False, nullable=False),
sa.Column('authorized', sa.BOOLEAN(), autoincrement=False, nullable=False),
sa.Column('requested_by_id', sa.UUID(), autoincrement=False, nullable=True),
sa.Column('authorized_by_id', sa.UUID(), autoincrement=False, nullable=True),
sa.ForeignKeyConstraint(['authorized_by_id'], ['user.id'], name=op.f('movie_request_authorized_by_id_fkey'), ondelete='SET NULL'),
sa.ForeignKeyConstraint(['movie_id'], ['movie.id'], name=op.f('movie_request_movie_id_fkey'), ondelete='CASCADE'),
sa.ForeignKeyConstraint(['requested_by_id'], ['user.id'], name=op.f('movie_request_requested_by_id_fkey'), ondelete='SET NULL'),
sa.PrimaryKeyConstraint('id', name=op.f('movie_request_pkey')),
sa.UniqueConstraint('movie_id', 'wanted_quality', name=op.f('movie_request_movie_id_wanted_quality_key'), postgresql_include=[], postgresql_nulls_not_distinct=False)
)
# ### end Alembic commands ###

View File

@@ -0,0 +1,35 @@
"""add_indexer_column_to_indexerqueryresult
Revision ID: eb0bd3cc1852
Revises: 5299dfed220b
Create Date: 2025-10-28 21:39:24.480466
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "eb0bd3cc1852"
down_revision: Union[str, None] = "5299dfed220b"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"indexer_query_result", sa.Column("indexer", sa.String(), nullable=True)
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("indexer_query_result", "indexer")
# ### end Alembic commands ###

175
config.dev.toml Normal file
View File

@@ -0,0 +1,175 @@
# MediaManager Dev Configuration File
# This file contains all available configuration options for MediaManager
# Documentation: https://maxdorninger.github.io/MediaManager/
#
# This is an example configuration file that gets copied to your config folder
# on first boot. You should modify the values below to match your setup.
[misc]
# it's very likely that you need to change this for MediaManager to work
frontend_url = "http://localhost:5173" # note the lack of a trailing slash
cors_urls = ["http://localhost:8000", "http://localhost:5173", "http://mediamanager:8000"] # note the lack of a trailing slash
image_directory = "/data/images"
tv_directory = "/data/tv"
movie_directory = "/data/movies"
torrent_directory = "/data/torrents" # this is where MediaManager will search for the downloaded torrents and usenet files
# you probaly don't need to change this
development = true
# Custom Media Libraries
# These paths should match your volume mounts in docker-compose.yaml
# Example: if you mount "./movies:/media/movies" then use path = "/media/movies/subdirectory"
[[misc.tv_libraries]]
name = "Live Action"
path = "/data/tv/live-action" # Change this to match your actual TV shows location
[[misc.movie_libraries]]
name = "Documentary"
path = "/data/movies/documentary" # Change this to match your actual movies location
[database]
host = "db"
port = 5432
user = "MediaManager"
password = "MediaManager"
dbname = "MediaManager"
[auth]
email_password_resets = false # if true, you also need to set up SMTP (notifications.smtp_config)
token_secret = "CHANGE_ME_GENERATE_RANDOM_STRING" # generate a random string with "openssl rand -hex 32", e.g. here https://www.cryptool.org/en/cto/openssl/
session_lifetime = 86400 # this is how long you will be logged in after loggin in, in seconds
# Admin users: Users who register with these email addresses will automatically become administrators
# If no users exist in the database, a default admin user will be created with the first email in this list
admin_emails = ["admin@example.com", "admin2@example.com"]
# OpenID Connect settings
[auth.openid_connect]
enabled = false
client_id = ""
client_secret = ""
configuration_endpoint = "https://openid.example.com/.well-known/openid-configuration"
name = "OpenID"
[notifications]
# SMTP settings for email notifications and email password resets
[notifications.smtp_config]
smtp_host = "smtp.example.com"
smtp_port = 587
smtp_user = "admin"
smtp_password = "admin"
from_email = "mediamanager@example.com"
use_tls = true
# Email notification settings
[notifications.email_notifications]
enabled = false
emails = ["admin@example.com", "admin2@example.com"] # List of email addresses to send notifications to
# Gotify notification settings
[notifications.gotify]
enabled = false
api_key = ""
url = "https://gotify.example.com"
# Ntfy notification settings
[notifications.ntfy]
enabled = false
url = "https://ntfy.sh/your-topic"
# Pushover notification settings
[notifications.pushover]
enabled = false
api_key = ""
user = ""
[torrents]
# qBittorrent settings
[torrents.qbittorrent]
enabled = false
host = "http://localhost"
port = 8080
username = "admin"
password = "admin"
# Transmission settings
[torrents.transmission]
enabled = false
username = "admin"
password = "admin"
https_enabled = true
host = "localhost"
port = 9091
path = "/transmission/rpc" # RPC request path target, usually "/transmission/rpc"
# SABnzbd settings
[torrents.sabnzbd]
enabled = false
host = "http://localhost"
port = 8080
api_key = ""
base_path = "/api"
[indexers]
# Prowlarr settings
[indexers.prowlarr]
enabled = false
url = "http://localhost:9696"
api_key = ""
timeout_seconds = 60
# Jackett settings
[indexers.jackett]
enabled = false
url = "http://localhost:9117"
api_key = ""
indexers = ["1337x", "torrentleech"] # List of indexer names to use
timeout_seconds = 60
# Title-based scoring rules
[[indexers.title_scoring_rules]]
name = "prefer_h265"
keywords = ["h265", "hevc", "x265", "h.265", "x.265"]
score_modifier = 100
negate = false
[[indexers.title_scoring_rules]]
name = "avoid_cam"
keywords = ["cam", "camrip", "bdscr", "ddc", "dvdscreener","dvdscr", "hdcam", "hdtc", "hdts", "scr", "screener","telesync", "ts", "webscreener", "tc", "telecine", "tvrip"]
score_modifier = -10000
negate = false
# Indexer flag-based scoring rules
[[indexers.indexer_flag_scoring_rules]]
name = "reject_non_freeleech"
flags = ["freeleech", "freeleech75"]
score_modifier = -10000
negate = true
[[indexers.indexer_flag_scoring_rules]]
name = "reject_nuked"
flags = ["nuked"]
score_modifier = -10000
negate = false
# Scoring rulesets
[[indexers.scoring_rule_sets]]
name = "default"
libraries = ["ALL_TV", "ALL_MOVIES"]
rule_names = ["prefer_h265", "avoid_cam", "reject_nuked"]
[[indexers.scoring_rule_sets]]
name = "strict_quality"
libraries = ["ALL_MOVIES"]
rule_names = ["prefer_h265", "avoid_cam", "reject_non_freeleech"]
# its very unlikely that you need to change this
[metadata]
[metadata.tmdb]
tmdb_relay_url = "https://metadata-relay.dorninger.co/tmdb"
[metadata.tvdb]
tvdb_relay_url = "https://metadata-relay.dorninger.co/tvdb"

172
config.example.toml Normal file
View File

@@ -0,0 +1,172 @@
# MediaManager Example Configuration File
# This file contains all available configuration options for MediaManager
# Documentation: https://maxdorninger.github.io/MediaManager/
#
# This is an example configuration file that gets copied to your config folder
# on first boot. You should modify the values below to match your setup.
[misc]
# it's very likely that you need to change this for MediaManager to work
frontend_url = "http://localhost:8000" # note the lack of a trailing slash
cors_urls = ["http://localhost:8000"] # note the lack of a trailing slash
image_directory = "/data/images"
tv_directory = "/data/tv"
movie_directory = "/data/movies"
torrent_directory = "/data/torrents" # this is where MediaManager will search for the downloaded torrents and usenet files
# you probaly don't need to change this
development = false
# Custom Media Libraries
# These paths should match your volume mounts in docker-compose.yaml
# Example: if you mount "./movies:/media/movies" then use path = "/media/movies/subdirectory"
[[misc.tv_libraries]]
name = "Live Action"
path = "/data/tv/live-action" # Change this to match your actual TV shows location
[[misc.movie_libraries]]
name = "Documentary"
path = "/data/movies/documentary" # Change this to match your actual movies location
[database]
host = "db"
port = 5432
user = "MediaManager"
password = "MediaManager"
dbname = "MediaManager"
[auth]
email_password_resets = false # if true, you also need to set up SMTP (notifications.smtp_config)
token_secret = "CHANGE_ME_GENERATE_RANDOM_STRING" # generate a random string with "openssl rand -hex 32", e.g. here https://www.cryptool.org/en/cto/openssl/
session_lifetime = 86400 # this is how long you will be logged in after loggin in, in seconds
# Admin users: Users who register with these email addresses will automatically become administrators
# If no users exist in the database, a default admin user will be created with the first email in this list
admin_emails = ["admin@example.com", "admin2@example.com"]
# OpenID Connect settings
[auth.openid_connect]
enabled = false
client_id = ""
client_secret = ""
configuration_endpoint = "https://openid.example.com/.well-known/openid-configuration"
name = "OpenID"
[notifications]
# SMTP settings for email notifications and email password resets
[notifications.smtp_config]
smtp_host = "smtp.example.com"
smtp_port = 587
smtp_user = "admin"
smtp_password = "admin"
from_email = "mediamanager@example.com"
use_tls = true
# Email notification settings
[notifications.email_notifications]
enabled = false
emails = ["admin@example.com", "admin2@example.com"] # List of email addresses to send notifications to
# Gotify notification settings
[notifications.gotify]
enabled = false
api_key = ""
url = "https://gotify.example.com"
# Ntfy notification settings
[notifications.ntfy]
enabled = false
url = "https://ntfy.sh/your-topic"
# Pushover notification settings
[notifications.pushover]
enabled = false
api_key = ""
user = ""
[torrents]
# qBittorrent settings
[torrents.qbittorrent]
enabled = false
host = "http://localhost"
port = 8080
username = "admin"
password = "admin"
# Transmission settings
[torrents.transmission]
enabled = false
username = "admin"
password = "admin"
https_enabled = true
host = "localhost"
port = 9091
path = "/transmission/rpc" # RPC request path target, usually "/transmission/rpc"
# SABnzbd settings
[torrents.sabnzbd]
enabled = false
host = "http://localhost"
port = 8080
api_key = ""
base_path = "/api"
[indexers]
# Prowlarr settings
[indexers.prowlarr]
enabled = false
url = "http://localhost:9696"
api_key = ""
timeout_seconds = 60
# Jackett settings
[indexers.jackett]
enabled = false
url = "http://localhost:9117"
api_key = ""
indexers = ["1337x", "torrentleech"] # List of indexer names to use
timeout_seconds = 60
# Title-based scoring rules
[[indexers.title_scoring_rules]]
name = "prefer_h265"
keywords = ["h265", "hevc", "x265", "h.265", "x.265"]
score_modifier = 100
negate = false
[[indexers.title_scoring_rules]]
name = "avoid_cam"
keywords = ["cam", "camrip", "bdscr", "ddc", "dvdscreener","dvdscr", "hdcam", "hdtc", "hdts", "scr", "screener","telesync", "ts", "webscreener", "tc", "telecine", "tvrip"]
score_modifier = -10000
negate = false
# Indexer flag-based scoring rules
[[indexers.indexer_flag_scoring_rules]]
name = "prefer_freeleech"
flags = ["freeleech", "freeleech75"]
score_modifier = 100
negate = false
[[indexers.indexer_flag_scoring_rules]]
name = "reject_nuked"
flags = ["nuked"]
score_modifier = -10000
negate = false
# Scoring rulesets
[[indexers.scoring_rule_sets]]
name = "default"
libraries = ["ALL_TV", "ALL_MOVIES"]
rule_names = ["prefer_h265", "avoid_cam", "reject_nuked", "prefer_freeleech"]
# its very unlikely that you need to change this
[metadata]
[metadata.tmdb]
tmdb_relay_url = "https://metadata-relay.dorninger.co/tmdb"
primary_languages = [""]
default_language = "en"
[metadata.tvdb]
tvdb_relay_url = "https://metadata-relay.dorninger.co/tvdb"

155
docker-compose.dev.yaml Normal file
View File

@@ -0,0 +1,155 @@
services:
db:
image: postgres:17
restart: unless-stopped
container_name: postgres
volumes:
- ./res/postgres:/var/lib/postgresql/data
environment:
POSTGRES_USER: MediaManager
POSTGRES_DB: MediaManager
POSTGRES_PASSWORD: MediaManager
ports:
- "5432:5432"
healthcheck:
test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
interval: 10s
timeout: 5s
retries: 5
mediamanager:
build:
context: .
dockerfile: Dockerfile
target: app
args:
- VERSION=locally-built
- BASE_PATH=
container_name: mediamanager
restart: unless-stopped
ports:
- "8000:8000"
environment:
- CONFIG_DIR=/app/config
- MEDIAMANAGER_MISC__DEVELOPMENT=TRUE
- MEDIAMANAGER_MISC__CORS_URLS=["http://localhost:5173"]
- DISABLE_FRONTEND_MOUNT=TRUE
- LOG_FILE=/dev/null
- MEDIAMANAGER_LOG_LEVEL=DEBUG
volumes:
#- ./web/build:/app/web/build # this is only needed to test built frontend when developing frontend
- ./res/images/:/data/images/
- ./res/:/data/
- ./res/config/:/app/config/
- ./media_manager:/app/media_manager
depends_on:
db:
condition: service_healthy
frontend:
image: node:24-alpine
container_name: mediamanager-frontend-dev
working_dir: /app
command: sh -c "npm install && npm run dev -- --host 0.0.0.0"
ports:
- "5173:5173"
- "24678:24678"
volumes:
- ./web:/app
depends_on:
- mediamanager
docs:
image: squidfunk/mkdocs-material:9
container_name: mediamanager-docs
volumes:
- .:/docs
ports:
- "9000:9000"
command: serve -w /docs -a 0.0.0.0:9000
# ----------------------------
# Additional services can be uncommented and configured as needed
# ----------------------------
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
container_name: prowlarr
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
volumes:
- ./res/prowlarr:/config
restart: unless-stopped
ports:
- "9696:9696"
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
environment:
- TZ=Etc/UTC
- WEBUI_PORT=8080
- TORRENTING_PORT=6881
ports:
- 8080:8080
- 6881:6881
- 6881:6881/udp
restart: unless-stopped
volumes:
- ./res/torrents:/download
- ./res/qbittorrent:/config
# transmission:
# image: lscr.io/linuxserver/transmission:latest
# container_name: transmission
# environment:
# - PUID=1000
# - PGID=1000
# - TZ=Etc/UTC
# - USER=admin
# - PASS=admin
# volumes:
# - ./res/transmission:/config
# - ./res/torrents:/data/torrents
# ports:
# - 9091:9091
# restart: unless-stopped
# pocket-id:
# image: ghcr.io/pocket-id/pocket-id
# restart: unless-stopped
# env_file: .env
# ports:
# - 1411:1411
# volumes:
# - ./res/pocket-id:/app/data
# healthcheck:
# test: "curl -f http://localhost:1411/healthz"
# interval: 1m30s
# timeout: 5s
# retries: 2
# start_period: 10s
# sabnzbd:
# image: lscr.io/linuxserver/sabnzbd:latest
# container_name: sabnzbd
# environment:
# - PUID=1000
# - PGID=1000
# - TZ=Etc/UTC
# volumes:
# - ./res/sabnzbd:/config
# - ./res/torrents:/downloads
# ports:
# - 8081:8080
# restart: unless-stopped
jackett:
image: lscr.io/linuxserver/jackett:latest
container_name: jackett
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- AUTO_UPDATE=true
volumes:
- ./res/jackett/data:/config
- ./res/jackett/torrents:/downloads
ports:
- 9117:9117
restart: unless-stopped

View File

@@ -1,68 +1,33 @@
services:
backend:
image: ghcr.io/maxdorninger/mediamanager/backend:latest
container_name: backend
mediamanager:
container_name: mediamanager_server
image: quay.io/maxdorninger/mediamanager:latest
ports:
- "8000:8000"
# In your reverse proxy you will probably need to set rule that only requests with a path prefix
# of /api/v1 will be forwarded to this container
# if you are using traefik the rule is going to look something like this:
# "traefik.http.routers.mm-api.rule=Host(`media.example`)&&PathPrefix(`/api/v1`)"
environment:
- QBITTORRENT_PASSWORD=
- QBITTORRENT_HOST=
- QBITTORRENT_USERNAME=
- QBITTORRENT_PORT=
- CORS_URLS=
- DB_HOST=db
#- DB_NAME=
#- DB_PORT=
#- DB_PASSWORD=
#- DB_DBNAME=
# generate a random string with "openssl rand -hex 32"
- AUTH_TOKEN_SECRET=
# this should be you email address
- AUTH_ADMIN_EMAIL=
# this is the URL of your frontend, e.g. https://mediamanager.example.com
- FRONTEND_URL=
#- OPENID_ENABLED=FALSE
#- OPENID_CLIENT_ID=
#- OPENID_CLIENT_SECRET=
#- OPENID_CONFIGURATION_ENDPOINT=
#- OPENID_NAME=
#- AUTH_SESSION_LIFETIME=
#- API_BASE_PATH=/api/v1
#- DEVELOPMENT=
- CONFIG_DIR=/app/config
volumes:
- ./data/:/data/
frontend:
image: ghcr.io/maxdorninger/mediamanager/frontend:latest
container_name: frontend
ports:
- "3000:3000"
volumes:
- ./cache:/app/cache
environment:
- PUBLIC_API_URL=http://localhost:8000/api/v1
# Mount your actual media directories here - these paths should match your config.toml
- ./data/:/data/ # Example: change ./data/ to your actual media root
# Config folder for application configuration
- ./config/:/app/config/
# Image folder
- ./images/:/data/images/
depends_on:
db:
condition: service_healthy
db:
image: postgres:latest
container_name: mediamanager_postgres
image: postgres:17
restart: unless-stopped
container_name: postgres
volumes:
- ./postgres:/var/lib/postgresql/data
healthcheck:
test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
interval: 10s
timeout: 5s
retries: 5
environment:
POSTGRES_USER: MediaManager
POSTGRES_DB: MediaManager
POSTGRES_PASSWORD: MediaManager
ports:
- "5432:5432"

View File

@@ -0,0 +1,4 @@
# Custom port
* `PORT`\
Port that MediaManager listens on. Default is `8000`. This only works if you are using the Docker image. Configured as environment variable.

View File

@@ -0,0 +1,4 @@
# Disable Startup Ascii Art
* `MEDIAMANAGER_NO_STARTUP_ART`: Set this environment variable (to any value) \
to disable the colorized startup splash screen. Unset to reenable.

View File

@@ -0,0 +1,12 @@
# Follow symlinks in frontend files
MediaManager can be configured to follow symlinks when serving frontend files. This is useful if you have a setup where your frontend files are stored in a different location, and you want to symlink them into the MediaManager frontend directory.
* `FRONTEND_FOLLOW_SYMLINKS`\
Set this environment variable to `true` to follow symlinks when serving frontend files. Default is `false`.
```bash title=".env"
FRONTEND_FOLLOW_SYMLINKS=true
```

View File

@@ -0,0 +1,65 @@
# Metadata Provider Configuration
## Metadata Provider Configuration
Metadata provider settings are configured in the `[metadata]` section of your `config.toml` file. These settings control how MediaManager retrieves information about movies and TV shows.
### TMDB Settings (`[metadata.tmdb]`)
TMDB (The Movie Database) is the primary metadata provider for MediaManager. It provides detailed information about movies and TV shows.
!!! 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`.
* `primary_languages`\
If the original language of a show/movie is in this list, metadata is fetched in that language. Otherwise, `default_language` is used. Default is `[]`. Example: `["no", "de", "es"]`. Format: ISO 639-1 (2 letters). Full list: https://en.wikipedia.org/wiki/List\_of\_ISO\_639\_language\_codes
* `default_language`\
TMDB language parameter used when searching and adding. Default is `en`. Format: ISO 639-1 (2 letters).
!!! 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]`)
!!! 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
!!! 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.
You might want to use your own relay if you want to avoid rate limits, protect your privacy, or for other reasons. If you know Sonarr's Skyhook, this is similar to that.
#### Where to get API keys
* 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)
!!! 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`:
```toml title="config.toml"
[metadata]
# TMDB configuration
[metadata.tmdb]
tmdb_relay_url = "https://metadata-relay.dorninger.co/tmdb"
# TVDB configuration
[metadata.tvdb]
tvdb_relay_url = "https://metadata-relay.dorninger.co/tvdb"
```
!!! info
In most cases, you can simply use the default values and don't need to specify these settings in your config file at all.

View File

@@ -0,0 +1,16 @@
# qBittorrent Category
qBittorrent supports saving Torrents to subdirectories based on the category of the Torrent. The default category name that MediaManager uses is `MediaManager`.
Use the following variables to customize behavior:
* `torrents.qbittorrent.category_name`\
Category name MediaManager uses when adding torrents to qBittorrent. Default is `MediaManager`.
* `torrents.qbittorrent.category_save_path`\
Save path for the category in qBittorrent. By default, no subdirectory is used. Example: `/data/torrents/MediaManager`.
!!! 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.
!!! warning
For MediaManager to successfully import torrents, you must add the subdirectory to the `misc.torrent_directory` variable.

View File

@@ -0,0 +1,36 @@
# URL Prefix
MediaManager, by default, expects to run at the base of a domain, e.g. `maxdorninger.github.io`.
In order to run it on a prefixed path, like `maxdorninger.github.io/media`, the docker image must be built with a special build argument. That's because SvelteKit needs to know the base URL at build time.
In short, clone the repository, then run:
```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 .
```
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.
```yaml title="docker-compose.yaml (excerpt)"
services:
mediamanager:
image: MediaManager:my-custom-version
ports:
- "8000:8000"
environment:
BASE_PATH: /media
...
```
!!! 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/`.

7
docs/api-reference.md Normal file
View File

@@ -0,0 +1,7 @@
# API Reference
!!! info
Media Manager's backend is built with FastAPI, which automatically generates interactive API documentation.
* Swagger UI (typically available at `http://localhost:8000/docs`)
* ReDoc (typically available at `http://localhost:8000/redoc`)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

BIN
docs/assets/assets/5546622 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
docs/assets/assets/JO.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
docs/assets/assets/NI.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 8.9 MiB

After

Width:  |  Height:  |  Size: 8.9 MiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 MiB

After

Width:  |  Height:  |  Size: 5.5 MiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 MiB

After

Width:  |  Height:  |  Size: 7.6 MiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

BIN
docs/assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 108 KiB

1
docs/assets/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 110 KiB

View File

@@ -0,0 +1,69 @@
# Configuration
MediaManager uses a TOML configuration file (`config.toml`) for all backend settings. This centralized configuration approach makes it easier to manage, backup, and share your MediaManager setup.
Frontend settings are configured through environment variables in your `docker-compose.yaml` file.
## Configuration File Location
!!! warning
Note that MediaManager may need to be restarted for changes in the config file to take effect.
Your `config.toml` file should be in the directory that's mounted to `/app/config/config.toml` inside the container:
```yaml
volumes:
- ./config:/app/config
```
You can change the configuration directory with the following environment variable:
* `CONFIG_DIR`\
Directory that contains `config.toml`. Default is `/app/config`. Example: `/etc/mediamanager/`.
## Configuration Sections
The configuration is organized into the following sections:
* `[misc]` - General settings
* `[database]` - Database settings
* `[auth]` - Authentication settings
* `[notifications]` - Notification settings (Email, Gotify, Ntfy, Pushover)
* `[torrents]` - Download client settings (qBittorrent, Transmission, SABnzbd)
* `[indexers]` - Indexer settings (Prowlarr and Jackett )
* `[metadata]` - TMDB and TVDB settings
## Configuring Secrets
For sensitive information like API keys, passwords, and secrets, you should use environment variables. You can actually set every configuration value through environment variables. For example, to set the `token_secret` value for authentication, with a .toml file you would use:
```toml
[auth]
token_secret = "your_super_secret_key_here"
```
But you can also set it through an environment variable:
```none
MEDIAMANAGER_AUTH__TOKEN_SECRET = "your_super_secret_key_here"
```
or another example with the OIDC client secret:
```toml
[auth]
...
[auth.openid_connect]
client_secret = "your_client_secret_from_provider"
```
env variable:
```none
MEDIAMANAGER_AUTH__OPENID_CONNECT__CLIENT_SECRET = "your_client_secret_from_provider"
```
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.
!!! 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.

View File

@@ -0,0 +1,81 @@
---
description: >-
MediaManager supports multiple authentication methods. Email/password
authentication is the default, but you can also enable OpenID Connect (OAuth
2.0) for integration with external identity providers
---
# Authentication
All authentication settings are configured in the `[auth]` section of your `config.toml` file.
## General Authentication Settings (`[auth]`)
* `token_secret`\
Strong secret key for signing JWTs (create with `openssl rand -hex 32`). This is required.
* `session_lifetime`\
Lifetime of user sessions in seconds. Default is `86400` (1 day).
* `admin_emails`\
A list of email addresses for administrator accounts. This is required.
* `email_password_resets`\
Enables password resets via email. Default is `false`.
!!! info
To use email password resets, you must also configure SMTP settings in the `[notifications.smtp_config]` section.
!!! 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.
## OpenID Connect Settings (`[auth.openid_connect]`)
OpenID Connect allows you to integrate with external identity providers like Google, Microsoft Azure AD, Keycloak, or any other OIDC-compliant provider.
* `enabled`\
Set to `true` to enable OpenID Connect authentication. Default is `false`.
* `client_id`\
Client ID provided by your OpenID Connect provider.
* `client_secret`\
Client secret provided by your OpenID Connect provider.
* `configuration_endpoint`\
OpenID Connect configuration endpoint URL. Do not include a trailing slash. Usually ends with `/.well-known/openid-configuration`.
* `name`\
Display name for the OpenID Connect provider shown on the login page.
### Configuration for your OpenID Connect Provider
#### Redirect URI
The OpenID server will likely require a redirect URI. This URL will usually look something like this:
```none
{MEDIAMANAGER_URL}/api/v1/auth/oauth/callback
```
!!! warning
It is very important that you set the correct callback URI, otherwise it won't work!
#### Authentik Example
Here is an example configuration for the OpenID Connect provider for Authentik.
![authentik-redirect-url-example](<../assets/assets/authentik redirect url example.png>)
## Example Configuration
Here's a complete example of the authentication section in your `config.toml`:
```toml title="config.toml"
[auth]
token_secret = "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6"
session_lifetime = 604800 # 1 week
admin_emails = ["admin@example.com", "manager@example.com"]
email_password_resets = true
[auth.openid_connect]
enabled = true
client_id = "mediamanager-client"
client_secret = "your-secret-key-here"
configuration_endpoint = "https://auth.example.com/.well-known/openid-configuration"
name = "Authentik"
```

View File

@@ -0,0 +1,42 @@
---
description: >-
These settings configure the core backend application through the config.toml
file. All backend configuration is now centralized in this TOML file instead
of environment variables.
---
# Backend
## General Settings (`[misc]`)
* `frontend_url`\
The URL the frontend will be accessed from. This is required. Do not include a trailing slash. Default is `http://localhost:8000`.
Example: if you are accessing MediaManager at `http://example.com/media`, set this to `http://example.com/media`.
If you are accessing MediaManager at the root of a domain, e.g. `https://mediamanager.example.com`, set this to `https://mediamanager.example.com`.
`frontend_url` does not affect where the server binds. It also does not configure a base path prefix. For prefixes, see [URL Prefix](../advanced-features/url-prefix.md).
* `cors_urls`\
A list of origins you are going to access the API from. Do not include trailing slashes.
* `development`\
Set to `true` to enable development mode. Default is `false`.
## Example Configuration
Here's a complete example of the general settings section in your `config.toml`:
```toml title="config.toml"
[misc]
# REQUIRED: Change this to match your actual frontend domain.
frontend_url = "http://mediamanager.dev"
cors_urls = ["http://localhost:8000"]
# Optional: Development mode (set to true for debugging)
development = false
```
!!! info
The `frontend_url` is the most important setting to configure correctly. Make sure it matches your actual deployment URLs.

View File

@@ -0,0 +1,52 @@
# Custom Libraries
MediaManager supports custom libraries, allowing you to add multiple folders for your movies and TV series. This feature is useful if you organize your media into different directories. For example, you might have separate folders for "Action" movies and "Comedy" movies, or "Live Action" TV shows and "Animated" TV shows.
## Configuration
Custom libraries are configured in the `misc` section in the `config.toml` file. You can add as many libraries as you need.
!!! info
You are not limited to `/data/tv` or `/data/movies`, you can choose the entire path freely!
### Movie Libraries
To add custom movie libraries, add a `[[misc.movie_libraries]]` section for each library. Each library requires a `name` and a `path`.
Example — configuring two movie libraries:
```toml
[misc]
# ... other misc settings
[[misc.movie_libraries]]
name = "Action"
path = "/data/movies/action"
[[misc.movie_libraries]]
name = "Comedy"
path = "/data/movies/comedy"
```
In this example, MediaManager will scan both `/data/movies/action` and `/data/movies/comedy` for movies.
### TV Show Libraries
Similarly, to add custom TV show libraries, add a `[[misc.tv_libraries]]` section for each library. Each library requires a `name` and a `path`.
Example — configuring two TV show libraries:
```toml
[misc]
# ... other misc settings
[[misc.tv_libraries]]
name = "Live Action"
path = "/data/tv/live-action"
[[misc.tv_libraries]]
name = "Animation"
path = "/data/tv/animation"
```

View File

@@ -0,0 +1,32 @@
# Database
Database settings are configured in the `[database]` section of your `config.toml` file. MediaManager uses PostgreSQL as its database backend.
## Database Settings (`[database]`)
* `host`\
Hostname or IP of the PostgreSQL server. Default is `localhost`.
* `port`\
Port number of the PostgreSQL server. Default is `5432`.
* `user`\
Username for the PostgreSQL connection. Default is `MediaManager`.
* `password`\
Password for the PostgreSQL user. Default is `MediaManager`.
* `dbname`\
Name of the PostgreSQL database. Default is `MediaManager`.
## Example Configuration
Here's a complete example of the database section in your `config.toml`:
```toml title="config.toml"
[database]
host = "db"
port = 5432
user = "MediaManager"
password = "your_secure_password"
dbname = "MediaManager"
```
!!! info
In docker-compose deployments the container name is simultaneously its hostname, so you can use "db" or "postgres" as host.

View File

@@ -0,0 +1,125 @@
# Download Clients
Download client settings are configured in the `[torrents]` section of your `config.toml` file. MediaManager supports both qBittorrent and SABnzbd as download clients.
## qBittorrent Settings (`[torrents.qbittorrent]`)
qBittorrent is a popular BitTorrent client that MediaManager can integrate with for downloading torrents.
* `enabled`\
Set to `true` to enable qBittorrent integration. Default is `false`.
* `host`\
Hostname or IP of the qBittorrent server. Include the protocol (http/https).
* `port`\
Port of the qBittorrent Web UI/API. Default is `8080`.
* `username`\
Username for qBittorrent Web UI authentication. Default is `admin`.
* `password`\
Password for qBittorrent Web UI authentication. Default is `admin`.
## Transmission Settings (`[torrents.transmission]`)
!!! info
The downloads path in Transmission and MediaManager must be the same, i.e. the path `/data/torrents` must link to the same volume for both containers.
Transmission is a BitTorrent client that MediaManager can integrate with for downloading torrents.
* `enabled`\
Set to `true` to enable Transmission integration. Default is `false`.
* `username`\
Username for Transmission RPC authentication.
* `password`\
Password for Transmission RPC authentication.
* `https_enabled`\
Set to `true` if your Transmission RPC endpoint uses HTTPS. Default is `true`.
* `host`\
Hostname or IP of the Transmission server (without protocol).
* `port`\
Port of the Transmission RPC endpoint. Default is `9091`.
* `path`\
RPC request path target. Usually `/transmission/rpc`.
## SABnzbd Settings (`[torrents.sabnzbd]`)
SABnzbd is a Usenet newsreader that MediaManager can integrate with for downloading NZB files.
* `enabled`\
Set to `true` to enable SABnzbd integration. Default is `false`.
* `host`\
Hostname or IP of the SABnzbd server, it needs to include `http(s)://`.
* `port`\
Port of the SABnzbd API. Default is `8080`.
* `api_key`\
API key for SABnzbd. You can find this in SABnzbd's configuration under "General" → "API Key".
* `base_path`\
API base path for SABnzbd. It usually ends with `/api`, the default is `/api`.
## Example Configuration
Here's a complete example of the download clients section in your `config.toml`:
```toml title="config.toml"
[torrents]
# qBittorrent configuration
[torrents.qbittorrent]
enabled = true
host = "http://qbittorrent"
port = 8080
username = "admin"
password = "your_secure_password"
# Transmission configuration
[torrents.transmission]
enabled = false
username = "admin"
password = "your_secure_password"
https_enabled = true
host = "transmission"
port = 9091
path = "/transmission/rpc"
# SABnzbd configuration
[torrents.sabnzbd]
enabled = false
host = "http://sabnzbd"
port = 8080
api_key = "your_sabnzbd_api_key"
```
## Docker Compose Integration
When using Docker Compose, make sure your download clients are accessible from the MediaManager backend:
```yaml title="docker-compose.yml"
services:
# MediaManager backend
backend:
image: ghcr.io/maxdorninger/mediamanager/backend:latest
# ... other configuration ...
# qBittorrent service
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
ports:
- "8080:8080"
environment:
- WEBUI_PORT=8080
volumes:
- ./data/torrents:/downloads
# ... other configuration ...
# SABnzbd service
sabnzbd:
image: lscr.io/linuxserver/sabnzbd:latest
ports:
- "8081:8080"
volumes:
- ./data/usenet:/downloads
# ... other configuration ...
```
!!! warning
You should enable only one BitTorrent and only one Usenet Download Client at any time.
!!! info
Make sure the download directories in your download clients are accessible to MediaManager for proper file management and organization.

Some files were not shown because too many files have changed in this diff Show More