Skip to content

[REQUEST] Support for Single Episode Torrents #322

@natarelli22

Description

@natarelli22

Is your feature request related to a problem? Please describe.
Currently, MediaManager only matches torrents that represent full seasons or season packs.
However, some indexers, as EZTV, mainly provides individual episode torrents (S01E01, S1E2, etc.), which are filtered and not considered valid results, even when indexers return them correctly.
A proposed code is presented below, but a few changes are needed to fully implement this feature.

Describe the solution you'd like
This feature request proposes extending season parsing to support single-episode releases, enabling:

  • Proper filtering/scoring of episode torrents

  • (Optionally) Imported status for individual episodes

Current behavior (Pluribus (2025) as example):
In /media_manager/indexer/schemas.py:

    def season(self) -> list[int]:
        pattern = r"\b[sS](\d+)\b"
        matches = re.findall(pattern, self.title, re.IGNORECASE)
        if matches.__len__() == 2:
            result = []
            for i in range(int(matches[0]), int(matches[1]) + 1):
                result.append(i)
        elif matches.__len__() == 1:
            result = [int(matches[0])]
        else:
            result = []
        return result

Log results:

2025-12-29 00:57:55,066 - INFO - media_manager.indexer.indexers.prowlarr - _newznab_search(): Indexer EZTV returned 56 results for search: {'cat': '5000', 'q': 'Pluribus S01', 't': 'tvsearch', 'season': 1, 'limit': 10000}
2025-12-29 00:57:55,340 - INFO - media_manager.indexer.utils - evaluate_indexer_query_results(): 0 passed the scoring rulesets

Screenshots:
Image

Proposed behavior (Pluribus (2025) as example):
In /media_manager/indexer/schemas.py:

    def season(self) -> list[int]:
        title = self.title.lower()

        # 1) S01E01 / S1E2
        m = re.search(r"s(\d{1,2})e\d{1,3}", title)
        if m:
            return [int(m.group(1))]

        # 2) Range S01-S03 / S1-S3
        m = re.search(r"s(\d{1,2})\s*[-–]\s*s?(\d{1,2})", title)
        if m:
            start, end = int(m.group(1)), int(m.group(2))
            return list(range(start, end + 1)) if start <= end else []

        # 3) Pack S01 / S1
        m = re.search(r"\bs(\d{1,2})\b", title)
        if m:
            return [int(m.group(1))]

        # 4) Season 01 / Season 1
        m = re.search(r"\bseason\s*(\d{1,2})\b", title)
        if m:
            return [int(m.group(1))]

        return []

Log results:

2025-12-29 01:00:29,327 - INFO - media_manager.indexer.indexers.prowlarr - _newznab_search(): Indexer EZTV returned 56 results for search: {'cat': '5000', 'q': 'Pluribus S01', 't': 'tvsearch', 'season': 1, 'limit': 10000}
2025-12-29 01:00:29,758 - INFO - media_manager.indexer.utils - evaluate_indexer_query_results(): 56 passed the scoring rulesets

Screenshots:
Image

Additional context / current limitation
After applying the proposed parsing change, the individual episodes are correctly discovered.
A first episode can be downloaded and imported. However, when attempting to download a second individual episode from the same season, an integrity error occurs:

Logs:

2025-12-29 01:46:23,130 - ERROR - media_manager.tv - add_season_file(): Integrity error while adding season file: (psycopg.errors.UniqueViolation) duplicate key value violates unique constraint "season_file_pkey"
DETAIL:  Key (season_id, file_path_suffix)=(740aa5bd-2143-402c-ba1d-09a5eaa1ecb6, 1080P) already exists.
[SQL: INSERT INTO season_file (season_id, torrent_id, file_path_suffix, quality) VALUES (%(season_id)s::UUID, %(torrent_id)s::UUID, %(file_path_suffix)s::VARCHAR, %(quality)s)]
[parameters: {'season_id': UUID('740aa5bd-2143-402c-ba1d-09a5eaa1ecb6'), 'torrent_id': UUID('35d5b689-5798-4dec-be34-d8e8bc2b8169'), 'file_path_suffix': '1080P', 'quality': 'fullhd'}]
(Background on this error at: https://sqlalche.me/e/20/gkpj)
2025-12-29 01:46:23,130 - ERROR - media_manager.tv - download_torrent(): Season file for season 740aa5bd-2143-402c-ba1d-09a5eaa1ecb6 and quality Quality.fullhd already exists, skipping.

Screenshots:
Image

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions