update 5 files

This commit is contained in:
LimeDrive 2024-09-14 18:45:21 +02:00
parent c9fe3f0fff
commit d0673dae07
5 changed files with 95 additions and 18 deletions

View file

@ -12,19 +12,14 @@ class ResultsPerQualityFilter(BaseFilter):
resolution_count = {}
for item in data:
resolutions = getattr(item.parsed_data, 'resolution', [])
if not resolutions:
resolutions = ["?.BZH.?"]
resolution = getattr(item.parsed_data, 'resolution', "?.BZH.?")
for resolution in resolutions:
if resolution not in resolution_count:
resolution_count[resolution] = 1
filtered_items.append(item)
break
elif resolution_count[resolution] < self.max_results_per_quality:
resolution_count[resolution] += 1
filtered_items.append(item)
break
if resolution not in resolution_count:
resolution_count[resolution] = 1
filtered_items.append(item)
elif resolution_count[resolution] < self.max_results_per_quality:
resolution_count[resolution] += 1
filtered_items.append(item)
logger.info(f"ResultsPerQualityFilter: input {len(data)}, output {len(filtered_items)}")
return filtered_items

View file

@ -28,7 +28,7 @@ class TorrentItem:
self.torrent_download = None # The torrent jackett download url if its None, it means that there is only a magnet link provided by Jackett. It also means, that we cant do series file filtering before debrid.
self.trackers = [] # Trackers of the torrent
self.file_index = None # Index of the file inside of the torrent - it may be updated durring __process_torrent() and update_availability(). If the index is None and torrent is not None, it means that the series episode is not inside of the torrent.
self.full_index = None # Case where we cannot call RD to get the full index. Else None
self.availability = False # If it's instantly available on the debrid service
self.parsed_data: ParsedData = parsed_data # Ranked result

View file

@ -1,4 +1,5 @@
import hashlib
import os
import queue
import threading
import time
@ -161,7 +162,7 @@ class TorrentService:
result.files = metadata["info"]["files"]
if result.type == "series":
file_details = self.__find_episode_file(result.files, result.parsed_data.seasons, result.parsed_data.episodes)
file_details = self.__find_single_episode_file(result.files, result.parsed_data.seasons, result.parsed_data.episodes)
if file_details is not None:
self.logger.debug("File details")
@ -169,7 +170,10 @@ class TorrentService:
result.file_index = file_details["file_index"]
result.file_name = file_details["title"]
result.size = file_details["size"]
else:
else:
result.full_index = self.__find_full_index(result.files)
if result.type == "movie":
result.file_index = self.__find_movie_file(result.files)
return result
@ -231,7 +235,7 @@ class TorrentService:
return trackers
def __find_episode_file(self, file_structure, season, episode):
def __find_single_episode_file(self, file_structure, season, episode):
if len(season) == 0 or len(episode) == 0:
return None
@ -255,6 +259,46 @@ class TorrentService:
file_index += 1
return max(episode_files, key=lambda file: file["size"])
def __find_full_index(self, file_structure):
self.logger.info("Starting to build full index of video files")
video_formats = {".mkv", ".mp4", ".avi", ".mov", ".flv", ".wmv", ".webm", ".mpg", ".mpeg", ".m4v", ".3gp", ".3g2",
".ogv", ".ogg", ".drc", ".gif", ".gifv", ".mng", ".avi", ".mov", ".qt", ".wmv", ".yuv", ".rm",
".rmvb", ".asf", ".amv", ".m4p", ".m4v", ".mpg", ".mp2", ".mpeg", ".mpe", ".mpv", ".mpg",
".mpeg", ".m2v", ".m4v", ".svi", ".3gp", ".3g2", ".mxf", ".roq", ".nsv", ".flv", ".f4v",
".f4p", ".f4a", ".f4b"}
full_index = []
file_index = 1
for file_entry in file_structure:
file_path = file_entry.get("path", [])
if isinstance(file_path, list):
file_name = file_path[-1] if file_path else ""
else:
file_name = file_path
_, file_extension = os.path.splitext(file_name.lower())
if file_extension in video_formats:
parsed_file = parse(file_name)
if len(parsed_file.seasons) == 0 or len(parsed_file.episodes) == 0:
self.logger.debug(f"Skipping file without season or episode parsed: {file_name}")
continue
full_index.append({
"file_index": file_index,
"file_name": file_name,
"full_path": os.path.join(*file_path) if isinstance(file_path, list) else file_path,
"size": file_entry.get("length", 0),
"seasons": parsed_file.seasons,
"episodes": parsed_file.episodes
})
self.logger.debug(f"Added file to index: {file_name}")
file_index += 1
self.logger.info(f"Full index built with {len(full_index)} video files")
return full_index
def __find_movie_file(self, file_structure):
max_size = 0

View file

@ -48,12 +48,50 @@ class TorrentSmartContainer:
if torrent_item.file_index is not None:
best_matching.append(torrent_item)
self.logger.debug("Item added to best matching (has file index)")
else:
matching_file = self.__find_matching_file(torrent_item.full_index, self.__media.season, self.__media.episode)
if matching_file:
torrent_item.file_index = matching_file['file_index']
torrent_item.file_name = matching_file['file_name']
torrent_item.size = matching_file['size']
best_matching.append(torrent_item)
self.logger.debug(f"Item added to best matching (found matching file: {matching_file['file_name']})")
else:
self.logger.debug("No matching file found, item not added to best matching")
else:
best_matching.append(torrent_item)
self.logger.debug("Item added to best matching (magnet link)")
self.logger.info(f"Found {len(best_matching)} best matching items")
return best_matching
def __find_matching_file(self, full_index, season, episode):
self.logger.info(f"Searching for matching file: Season {season}, Episode {episode}")
if not full_index:
self.logger.warning("Full index is empty, cannot find matching file")
return None
# Convert season and episode to integers for comparison
try:
target_season = int(season.replace('S', ''))
target_episode = int(episode.replace('E', ''))
except ValueError:
self.logger.error(f"Invalid season or episode format: {season}, {episode}")
return None
best_match = None
for file_entry in full_index:
if target_season in file_entry['seasons'] and target_episode in file_entry['episodes']:
if best_match is None or file_entry['size'] > best_match['size']:
best_match = file_entry
self.logger.debug(f"Found potential match: {file_entry['file_name']}")
if best_match:
self.logger.info(f"Best matching file found: {best_match['file_name']}")
return best_match
else:
self.logger.warning(f"No matching file found for Season {season}, Episode {episode}")
return None
def cache_container_items(self):
self.logger.info("Starting cache process for container items")
threading.Thread(target=self.__save_to_cache).start()
@ -189,7 +227,7 @@ class TorrentSmartContainer:
file_index = self.__explore_folders(file["e"], files, file_index, type, season, episode)
continue
parsed_file = parse(file["n"])
if season in parsed_file.season and episode in parsed_file.episode:
if season in parsed_file.seasons and episode in parsed_file.episodes:
self.logger.debug(f"Matching series file found: {file['n']}")
files.append({
"file_index": file_index,

View file

@ -89,7 +89,7 @@ def parse_to_debrid_stream(
title = f"{torrent_item.raw_title}\n"
if torrent_item.file_name is not None:
if media.type == "series" and torrent_item.file_name is not None:
title += f"{torrent_item.file_name}\n"
if torrent_item.languages: