Skip to content

Extras

Extras module for additional functionality related to RTN processing.

Functions:

Name Description
- `title_match`

Compare two titles using the Levenshtein ratio to determine similarity.

- `sort_torrents`

Sort a set of Torrent objects by their resolution and rank in descending order.

- `extract_seasons`

Extract season numbers from the title.

- `extract_episodes`

Extract episode numbers from the title.

- `episodes_from_season`

Extract episode numbers for a specific season from the title.

For more details, please refer to the documentation.

episodes_from_season(raw_title, season_num)

Only return episode numbers if the season number is found in the title and the season number matches the input season number.

Parameters:

Name Type Description Default
`raw_title` str

The original title of the torrent to analyze.

required
`season_num` int

The season number to extract episodes for.

required

Returns:

Type Description
List[int]

List[int]: A list of extracted episode numbers for the specified season.

Source code in RTN/extras.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def episodes_from_season(raw_title: str, season_num: int) -> List[int]:
    """
    Only return episode numbers if the season number is found in the title
    and the season number matches the input season number.

    Args:
        `raw_title` (str): The original title of the torrent to analyze.
        `season_num` (int): The season number to extract episodes for.

    Returns:
        `List[int]`: A list of extracted episode numbers for the specified season.
    """
    if not season_num:
        raise ValueError("The season number must be provided.")
    if not isinstance(season_num, int) or season_num <= 0:
        raise TypeError("The season number must be a positive integer.")
    if not raw_title or not isinstance(raw_title, str):
        raise ValueError("The input title must be a non-empty string.")

    data: dict[str, Any] = parse_title(raw_title)

    season_from_title = data.get("seasons", [])
    episodes_from_title = data.get("episodes", [])

    if isinstance(episodes_from_title, list) and season_num in season_from_title:
        return episodes_from_title
    return []

extract_episodes(raw_title)

Extract episode numbers from the title or filename.

Parameters:

Name Type Description Default
`raw_title` str

The original title of the torrent to analyze.

required

Returns:

Type Description
List[int]

List[int]: A list of extracted episode numbers from the title.

Source code in RTN/extras.py
150
151
152
153
154
155
156
157
158
159
160
161
162
def extract_episodes(raw_title: str) -> List[int]:
    """
    Extract episode numbers from the title or filename.

    Args:
        `raw_title` (str): The original title of the torrent to analyze.

    Returns:
        `List[int]`: A list of extracted episode numbers from the title.
    """
    if not raw_title or not isinstance(raw_title, str):
        raise TypeError("The input title must be a non-empty string.")
    return parse_title(raw_title)["episodes"]

extract_seasons(raw_title)

Extract season numbers from the title or filename.

Parameters:

Name Type Description Default
`raw_title` str

The original title of the torrent to analyze.

required

Returns:

Type Description
List[int]

List[int]: A list of extracted season numbers from the title.

Source code in RTN/extras.py
135
136
137
138
139
140
141
142
143
144
145
146
147
def extract_seasons(raw_title: str) -> List[int]:
    """
    Extract season numbers from the title or filename.

    Args:
        `raw_title` (str): The original title of the torrent to analyze.

    Returns:
        `List[int]`: A list of extracted season numbers from the title.
    """
    if not raw_title or not isinstance(raw_title, str):
        raise TypeError("The input title must be a non-empty string.")
    return parse_title(raw_title)["seasons"]

get_lev_ratio(correct_title, parsed_title, threshold=0.85, aliases={})

Compares two titles using the Levenshtein ratio to determine similarity.

Parameters:

Name Type Description Default
`correct_title` str

The reference title to compare against.

required
`parsed_title` str

The title to compare with the reference title.

required
`threshold` float

The similarity threshold to consider the titles as matching.

required
`aliases` dict

A dictionary of aliases for the correct title.

required

Returns:

Type Description
float

float: The highest Levenshtein ratio between the parsed title and any of the correct titles (including aliases if provided).

Source code in RTN/extras.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def get_lev_ratio(correct_title: str, parsed_title: str, threshold: float = 0.85, aliases: dict = {}) -> float:
    """
    Compares two titles using the Levenshtein ratio to determine similarity.

    Args:
        `correct_title` (str): The reference title to compare against.
        `parsed_title` (str): The title to compare with the reference title.
        `threshold` (float): The similarity threshold to consider the titles as matching.
        `aliases` (dict, optional): A dictionary of aliases for the correct title.

    Returns:
        `float`: The highest Levenshtein ratio between the parsed title and any of the correct titles (including aliases if provided).
    """
    if not (correct_title and parsed_title):
        raise ValueError("Both titles must be provided.")
    if not isinstance(threshold, (int, float)) or not 0 <= threshold <= 1:
        raise ValueError("The threshold must be a number between 0 and 1.")

    ratio_set = {
        ratio(normalize_title(title), normalize_title(parsed_title), score_cutoff=threshold)
        for title in [normalize_title(correct_title)] + [normalize_title(alias) for alias_list in aliases.values() for alias in alias_list]
    }

    return max(ratio_set)

sort_torrents(torrents, bucket_limit=None)

Sorts a set of Torrent objects by their resolution bucket and then by their rank in descending order. Returns a dictionary with infohash as keys and Torrent objects as values.

Parameters:

Name Type Description Default
`torrents` Set[Torrent]

A set of Torrent objects.

required
`bucket_limit` int

The maximum number of torrents to return from each bucket.

required

Raises:

Type Description
`TypeError`

If the input is not a set of Torrent objects.

Returns:

Type Description
Dict[str, Torrent]

Dict[str, Torrent]: A dictionary of Torrent objects sorted by resolution and rank in descending order,

Dict[str, Torrent]

with the torrent's infohash as the key.

Source code in RTN/extras.py
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def sort_torrents(torrents: Set[Torrent], bucket_limit: int = None) -> Dict[str, Torrent]:
    """
    Sorts a set of Torrent objects by their resolution bucket and then by their rank in descending order.
    Returns a dictionary with infohash as keys and Torrent objects as values.

    Args:
        `torrents` (Set[Torrent]): A set of Torrent objects.
        `bucket_limit` (int, optional): The maximum number of torrents to return from each bucket.

    Raises:
        `TypeError`: If the input is not a set of Torrent objects.

    Returns:
        `Dict[str, Torrent]`: A dictionary of Torrent objects sorted by resolution and rank in descending order,
        with the torrent's infohash as the key.
    """

    if not isinstance(torrents, set) or not all(isinstance(t, Torrent) for t in torrents):
        raise TypeError("The input must be a set of Torrent objects.")

    buckets = {
        Resolution.UHD: 4,
        Resolution.UHD_2160P: 4,
        Resolution.UHD_1440P: 4,
        Resolution.FHD: 3,
        Resolution.HD: 2,
        Resolution.SD_576P: 1,
        Resolution.SD_480P: 1,
        Resolution.SD_360P: 1,
        Resolution.UNKNOWN: 0,
    }

    def get_bucket(torrent: Torrent) -> int:
        resolution_map = {
            "4k": Resolution.UHD,
            "2160p": Resolution.UHD_2160P,
            "1440p": Resolution.UHD_1440P,
            "1080p": Resolution.FHD,
            "720p": Resolution.HD,
            "576p": Resolution.SD_576P,
            "480p": Resolution.SD_480P,
            "360p": Resolution.SD_360P,
            "unknown": Resolution.UNKNOWN,
        }
        resolution = resolution_map.get(torrent.data.resolution, Resolution.UNKNOWN)
        return buckets[resolution]

    sorted_torrents: List[Torrent] = sorted(
        torrents,
        key=lambda torrent: (get_bucket(torrent), torrent.rank if torrent.rank is not None else float("-inf")),
        reverse=True
    )

    if bucket_limit and bucket_limit > 0:
        bucket_groups: Dict[int, List[Torrent]] = {}
        for torrent in sorted_torrents:
            bucket = get_bucket(torrent)
            if bucket not in bucket_groups:
                bucket_groups[bucket] = []
            bucket_groups[bucket].append(torrent)

        result = {}
        for bucket_torrents in bucket_groups.values():
            for torrent in bucket_torrents[:bucket_limit]:
                result[torrent.infohash] = torrent
        return result

    return {torrent.infohash: torrent for torrent in sorted_torrents}

title_match(correct_title, parsed_title, threshold=0.85, aliases={})

Compares two titles using the Levenshtein ratio to determine similarity.

Parameters:

Name Type Description Default
`correct_title` str

The reference title to compare against.

required
`parsed_title` str

The title to compare with the reference title.

required
`threshold` float

The similarity threshold to consider the titles as matching.

required
`aliases` dict

A dictionary of aliases for the correct title.

required

Returns: bool: True if the titles match, False otherwise.

Source code in RTN/extras.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def title_match(correct_title: str, parsed_title: str, threshold: float = 0.85, aliases: dict = {}) -> bool:
    """
    Compares two titles using the Levenshtein ratio to determine similarity.

    Args:
        `correct_title` (str): The reference title to compare against.
        `parsed_title` (str): The title to compare with the reference title.
        `threshold` (float): The similarity threshold to consider the titles as matching.
        `aliases` (dict, optional): A dictionary of aliases for the correct title.
    Returns:
        `bool`: True if the titles match, False otherwise.
    """
    check = get_lev_ratio(correct_title, parsed_title, threshold, aliases)
    return check >= threshold