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 -->
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 -->
## What
Two-line fix to the quality detection regex in
`media_manager/indexer/schemas.py`.
**UHD pattern**: `\b(4k)\b` → `\b(4k|2160p|uhd)\b`
**FullHD pattern**: `\b(1080p)\b` → `\b(1080p|fullhd|full\s*hd)\b`
## Why
The UHD regex only matched the literal keyword `4k`. Torrent titles
containing `2160p` or `UHD` (but not `4k`) were classified as
`Quality.unknown` (value 5) instead of `Quality.uhd` (value 1). Since
sorting uses quality as the primary key, these 4K releases ended up at
the bottom of search results.
### Example
| Title | Before | After |
|---|---|---|
| `Movie.2013.4K.HDR.2160p.x265` | ✅ `Quality.uhd` | ✅ `Quality.uhd` |
| `Movie.2013.UHD.BluRay.2160p.HDR10.x265` | ❌ `Quality.unknown` | ✅
`Quality.uhd` |
| `Movie.2013.2160p.WEBRip.DDP5.1.x264` | ❌ `Quality.unknown` | ✅
`Quality.uhd` |
All patterns already use `re.IGNORECASE`, so case variants are handled.
Fixes#449
---------
Co-authored-by: GokuPlay609 <GokuPlay609@users.noreply.github.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: maxid <97409287+maxdorninger@users.noreply.github.com>
**Description**
As explained on #322, MediaManager currently only matches torrents that
represent full seasons or season packs.
As a result, valid episode-based releases — commonly returned by
indexers such as EZTV — are filtered out during scoring and never
considered for download.
Initial changes to the season parsing logic allow these torrents to be
discovered.
However, additional changes are required beyond season parsing to
properly support single-episode imports.
This PR is intended as a work-in-progress / RFC to discuss the required
changes and align on the correct approach before completing the
implementation.
**Things planned to do**
[X] Update Web UI to better display episode-level details
[ ] Update TV show import logic to handle single episode files, instead
of assuming full season files (to avoid integrity errors when episodes
are missing)
[ ] Create episode file tables to store episode-level data, similar to
season files
[ ] Implement fetching and downloading logic for single-episode torrents
**Notes / current limitations**
At the moment, the database and import logic assume one file per season
per quality, which works for season packs but not for episode-based
releases.
These changes are intentionally not completed yet and are part of the
discussion this PR aims to start.
**Request for feedback**
This represents a significant change in how TV content is handled in
MediaManager.
Before proceeding further, feedback from @maxdorninger on the overall
direction and next steps would be greatly appreciated.
Once aligned, the remaining tasks can be implemented incrementally.
---------
Co-authored-by: Maximilian Dorninger <97409287+maxdorninger@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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
this mostly either removes unused parameters, prefixes them with an
underscore or uses the @override decorator to tell the linter, that that
method comes from a superclass and can't be changed
this mostly adds a timeout=60 to all requests
this does mainly wants a timeout to all requests functions, since when
left out they hang infinitly.
I added a timeout of 60s, which is probably way too high, but since
before this there was none, I guess it's an improvement?