From 06e7bb15d87b286703bfb5df39a0cfd5a4b18412 Mon Sep 17 00:00:00 2001 From: Brett Williams Date: Tue, 20 Aug 2024 23:48:42 -0500 Subject: [PATCH] Add docstrings to base_downloader.py --- src/engines/core/base_downloader.py | 134 ++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 5 deletions(-) diff --git a/src/engines/core/base_downloader.py b/src/engines/core/base_downloader.py index 356edea..f1d370f 100644 --- a/src/engines/core/base_downloader.py +++ b/src/engines/core/base_downloader.py @@ -1,9 +1,7 @@ import logging import os import shutil -import tarfile import tempfile -import zipfile import requests from tqdm import tqdm @@ -12,26 +10,150 @@ logger = logging.getLogger() class EngineDownloader: + """A class responsible for downloading and extracting rendering engines from publicly available URLs. + + Attributes: + supported_formats (list[str]): A list of file formats supported by the downloader. + """ supported_formats = ['.zip', '.tar.xz', '.dmg'] def __init__(self): pass + # -------------------------------------------- + # Required Overrides for Subclasses: + # -------------------------------------------- + @classmethod def find_most_recent_version(cls, system_os=None, cpu=None, lts_only=False): - raise NotImplementedError # implement this method in your engine subclass + """ + Finds the most recent version of the rendering engine available for download. + + This method should be overridden in a subclass to implement the logic for determining + the most recent version of the rendering engine, optionally filtering by long-term + support (LTS) versions, the operating system, and CPU architecture. + + Args: + system_os (str, optional): Desired OS ('linux', 'macos', 'windows'). Defaults to system os. + cpu (str, optional): The CPU architecture for which to download the engine. Default is system cpu. + lts_only (bool, optional): Limit the search to LTS (long-term support) versions only. Default is False. + + Returns: + dict: A dict with the following keys: + - 'cpu' (str): The CPU architecture. + - 'system_os' (str): The operating system. + - 'file' (str): The filename of the version's download file. + - 'url' (str): The remote URL for downloading the version. + - 'version' (str): The version number. + + Raises: + NotImplementedError: If the method is not overridden in a subclass. + """ + raise NotImplementedError(f"find_most_recent_version not implemented for {cls.__class__.__name__}") @classmethod def version_is_available_to_download(cls, version, system_os=None, cpu=None): - raise NotImplementedError # implement this method in your engine subclass + """Checks if a requested version of the rendering engine is available for download. + + This method should be overridden in a subclass to implement the logic for determining + whether a given version of the rendering engine is available for download, based on the + operating system and CPU architecture. + + Args: + version (str): The requested renderer version to download. + system_os (str, optional): Desired OS ('linux', 'macos', 'windows'). Defaults to system os. + cpu (str, optional): The CPU architecture for which to download the engine. Default is system cpu. + + Returns: + bool: True if the version is available for download, False otherwise. + + Raises: + NotImplementedError: If the method is not overridden in a subclass. + """ + raise NotImplementedError(f"version_is_available_to_download not implemented for {cls.__class__.__name__}") @classmethod def download_engine(cls, version, download_location, system_os=None, cpu=None, timeout=120): - raise NotImplementedError # implement this method in your engine subclass + """Downloads the requested version of the rendering engine to the given download location. + + This method should be overridden in a subclass to implement the logic for downloading + a specific version of the rendering engine. The method is intended to handle the + downloading process based on the version, operating system, CPU architecture, and + timeout parameters. + + Args: + version (str): The requested renderer version to download. + download_location (str): The directory where the engine should be downloaded. + system_os (str, optional): Desired OS ('linux', 'macos', 'windows'). Defaults to system os. + cpu (str, optional): The CPU architecture for which to download the engine. Default is system cpu. + timeout (int, optional): The maximum time in seconds to wait for the download. Default is 120 seconds. + + Raises: + NotImplementedError: If the method is not overridden in a subclass. + """ + raise NotImplementedError(f"download_engine not implemented for {cls.__class__.__name__}") + + # -------------------------------------------- + # Optional Overrides for Subclasses: + # -------------------------------------------- + + @classmethod + def all_versions(cls, system_os=None, cpu=None): + """Retrieves a list of available versions of the software for a specific operating system and CPU architecture. + + This method fetches all available versions for the given operating system and CPU type, constructing + a list of dictionaries containing details such as the version, CPU architecture, system OS, and the + remote URL for downloading each version. + + Args: + system_os (str, optional): Desired OS ('linux', 'macos', 'windows'). Defaults to system os. + cpu (str, optional): The CPU architecture for which to download the engine. Default is system cpu. + + Returns: + list[dict]: A list of dictionaries, each containing: + - 'cpu' (str): The CPU architecture. + - 'file' (str): The filename of the version's download file. + - 'system_os' (str): The operating system. + - 'url' (str): The remote URL for downloading the version. + - 'version' (str): The version number. + """ + return [] + + # -------------------------------------------- + # Do Not Override These Methods: + # -------------------------------------------- @classmethod def download_and_extract_app(cls, remote_url, download_location, timeout=120): + """Downloads an application from the given remote URL and extracts it to the specified location. + + This method handles the downloading of the application, supports multiple archive formats, + and extracts the contents to the specified `download_location`. It also manages temporary + files and logs progress throughout the process. + + Args: + remote_url (str): The URL of the application to download. + download_location (str): The directory where the application should be extracted. + timeout (int, optional): The maximum time in seconds to wait for the download. Default is 120 seconds. + + Returns: + str: The path to the directory where the application was extracted. + + Raises: + Exception: Catches and logs any exceptions that occur during the download or extraction process. + + Supported Formats: + - `.tar.xz`: Extracted using the `tarfile` module. + - `.zip`: Extracted using the `zipfile` module. + - `.dmg`: macOS disk image files, handled using the `dmglib` library. + - Other formats will result in an error being logged. + + Notes: + - If the application already exists in the `download_location`, the method will log an error + and return without downloading or extracting. + - Temporary files created during the download process are cleaned up after completion. + """ # Create a temp download directory temp_download_dir = tempfile.mkdtemp() @@ -80,6 +202,7 @@ class EngineDownloader: # Extract the downloaded file # Process .tar.xz files if temp_downloaded_file_path.lower().endswith('.tar.xz'): + import tarfile try: with tarfile.open(temp_downloaded_file_path, 'r:xz') as tar: tar.extractall(path=download_location) @@ -93,6 +216,7 @@ class EngineDownloader: # Process .zip files elif temp_downloaded_file_path.lower().endswith('.zip'): + import zipfile try: with zipfile.ZipFile(temp_downloaded_file_path, 'r') as zip_ref: zip_ref.extractall(download_location)