From 32cffc3079ddad77b4e8ccb578cb8d8b44f76f3b Mon Sep 17 00:00:00 2001 From: Lukas Pupka-Lipinski Date: Sun, 18 May 2025 11:50:02 +0200 Subject: [PATCH] chore: better logging --- Loader.py | 21 ++++++--------------- main.py | 56 +++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/Loader.py b/Loader.py index 109e80c..c028f78 100644 --- a/Loader.py +++ b/Loader.py @@ -7,16 +7,14 @@ from aniworld.models import Anime from aniworld.config import PROVIDER_HEADERS, INVALID_PATH_CHARS from aniworld.parser import arguments -# Configure logging -logging.basicConfig( - filename="download.log", - level=logging.INFO, - format="%(asctime)s - %(levelname)s - %(message)s" -) - # Read timeout from environment variable, default to 600 seconds (10 minutes) timeout = int(os.getenv("DOWNLOAD_TIMEOUT", 600)) +download_error_logger = logging.getLogger("DownloadErrors") +download_error_handler = logging.FileHandler("download_errors.log") +download_error_handler.setLevel(logging.ERROR) +download_error_logger.addHandler(download_error_handler) + def download(anime: Anime): # pylint: disable=too-many-branches for episode in anime: sanitized_anime_title = ''.join( @@ -38,9 +36,6 @@ def download(anime: Anime): # pylint: disable=too-many-branches output_path = os.path.join(anime.output_directory, output_file) os.makedirs(os.path.dirname(output_path), exist_ok=True) - - logging.info(f"Preparing to download: {output_path}") - command = [ "yt-dlp", episode.get_direct_link(anime.provider, anime.language), @@ -48,8 +43,7 @@ def download(anime: Anime): # pylint: disable=too-many-branches "--concurrent-fragments", "4", "-o", output_path, "--quiet", - "--no-warnings", - "--progress" + "--no-warnings" ] if anime.provider in PROVIDER_HEADERS: @@ -64,10 +58,7 @@ def download(anime: Anime): # pylint: disable=too-many-branches continue try: - - logging.info(f"Starting download to {output_path}...") subprocess.run(command, check=True, timeout=timeout) - logging.info(f"Download completed: {output_path}") except subprocess.TimeoutExpired: logging.error(f"Download timed out after {timeout} seconds: {' '.join(str(item) for item in command)}") except subprocess.CalledProcessError: diff --git a/main.py b/main.py index 2516af7..28d2746 100644 --- a/main.py +++ b/main.py @@ -10,26 +10,41 @@ from aniworld.common import get_season_episode_count, get_movie_episode_count from aniworld.search import search_anime from Loader import download -# Configure basic logging to the console -logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +error_logger = logging.getLogger("ErrorLog") +error_handler = logging.FileHandler("errors.log") +error_handler.setLevel(logging.ERROR) +error_logger.addHandler(error_handler) + +noKeyFound_logger = logging.getLogger("NoKeyFound") +noKeyFound_handler = logging.FileHandler("NoKeyFound.log") +noKeyFound_handler.setLevel(logging.ERROR) +noKeyFound_logger.addHandler(noKeyFound_handler) + +class NoKeyFoundException(Exception): + """Exception raised when an anime key cannot be found.""" + pass class MatchNotFoundError(Exception): - """Custom exception raised when the pattern match is not found.""" + """Exception raised when an anime key cannot be found.""" pass class Loader: def __init__(self, basePath: str): self.directory = basePath - logging.warning(f"Initialized Loader with base path: {self.directory}") + logging.info(f"Initialized Loader with base path: {self.directory}") def __find_mp4_files(self): - logging.warning("Scanning for .mp4 files") + logging.info("Scanning for .mp4 files") for root_folder_name in os.listdir(self.directory): folder_data = defaultdict(list) # Dictionary to store MP4 files per folder folder = os.path.join(self.directory, root_folder_name) + logging.info(f"Processing folder: {root_folder_name}") + # First pass: Scan all folders and collect MP4 file data for root, dirs, files in os.walk(folder): mp4_files = [file for file in files if file.endswith('.mp4')] @@ -38,7 +53,7 @@ class Loader: yield root_folder_name, folder_data[root_folder_name] for dir in self.__find_empty_folders(): - logging.debug(f"Found no .mp4 files in {dir}") + logging.info(f"Found no .mp4 files in {dir}") yield dir, [] def __find_empty_folders(self): @@ -64,17 +79,21 @@ class Loader: if os.path.exists(key_file): with open(key_file, 'r') as file: key = file.read().strip() - logging.debug(f"Key found for folder '{folder_name}': {key}") + logging.info(f"Key found for folder '{folder_name}': {key}") return key else: - key = search_anime(self.__remove_year(folder_name), True) - if (len(key) >= 1): - key = key[0]['link'] - with open(key_file, 'w') as file: - file.write(key) - logging.warning(f"Generated new key for folder '{folder_name}': {key}") - return key - raise Exception() + try: + key = search_anime(folder_name, True) + if key: + key = key[0]['link'] + with open(key_file, 'w') as file: + file.write(key) + logging.info(f"Generated new key for folder '{folder_name}': {key}") + return key + else: + raise NoKeyFoundException(f"No key found for folder '{folder_name}'") + except Exception as e: + raise NoKeyFoundException(f"Failed to retrieve key for folder '{folder_name}'") from e def __GetEpisodeAndSeason(self, filename: str): pattern = r'S(\d+)E(\d+)' @@ -136,13 +155,14 @@ class Loader: try: key = self.__check_and_generate_key(folder) missings = self.__GetMissingEpisodesAndSeason(key, mp4_files) - + logging.info("Missing episodes for {key} \n" + "\n".join(f"Season {str(k)}: {', '.join(str(v))}" for k, v in missings)) for season, missing_episodes in missings: for episode in missing_episodes: executor.submit(download_episode, folder, season, episode, key) + except NoKeyFoundException as nkfe: + noKeyFound_logger.error(f"Error processing folder '{folder}': {nkfe}") except Exception as e: - logging.error(f"Error processing folder '{folder}': {e}") - traceback.print_exc() + error_logger.error(f"Unexpected error processing folder '{folder}': {e} \n {traceback.format_exc()}") continue # Read the base directory from an environment variable