From ac0478b062a07df758a9aae13aab93f094cf6dff Mon Sep 17 00:00:00 2001 From: dw-0 Date: Sun, 19 May 2024 18:41:29 +0200 Subject: [PATCH] refactor: more robust type hinting Signed-off-by: Dominik Willner --- kiauh/components/crowsnest/crowsnest.py | 27 ++--- kiauh/components/klipper/klipper_utils.py | 23 +--- .../components/klipperscreen/klipperscreen.py | 44 +++---- kiauh/components/mobileraker/mobileraker.py | 27 +---- kiauh/components/moonraker/moonraker_utils.py | 27 ++--- kiauh/components/webui_client/client_utils.py | 52 ++++----- kiauh/core/menus/main_menu.py | 52 +++++---- kiauh/core/menus/update_menu.py | 13 ++- kiauh/utils/common.py | 107 +++++++----------- kiauh/utils/types.py | 30 +++++ 10 files changed, 167 insertions(+), 235 deletions(-) create mode 100644 kiauh/utils/types.py diff --git a/kiauh/components/crowsnest/crowsnest.py b/kiauh/components/crowsnest/crowsnest.py index f6a0e09..7d4b789 100644 --- a/kiauh/components/crowsnest/crowsnest.py +++ b/kiauh/components/crowsnest/crowsnest.py @@ -12,19 +12,19 @@ import shutil import time from pathlib import Path from subprocess import CalledProcessError, run -from typing import Dict, List, Literal, Union +from typing import List from components.crowsnest import CROWSNEST_BACKUP_DIR, CROWSNEST_DIR, CROWSNEST_REPO from components.klipper.klipper import Klipper from core.backup_manager.backup_manager import BackupManager from core.instance_manager.instance_manager import InstanceManager from core.settings.kiauh_settings import KiauhSettings -from utils.common import check_install_dependencies, get_install_status +from utils.common import ( + check_install_dependencies, + get_install_status, +) from utils.constants import CURRENT_USER from utils.git_utils import ( - get_local_commit, - get_remote_commit, - get_repo_name, git_clone_wrapper, git_pull_wrapper, ) @@ -34,6 +34,7 @@ from utils.sys_utils import ( cmd_sysctl_service, parse_packages_from_file, ) +from utils.types import ComponentStatus def install_crowsnest() -> None: @@ -142,25 +143,13 @@ def update_crowsnest() -> None: return -def get_crowsnest_status() -> ( - Dict[ - Literal["status", "status_code", "repo", "local", "remote"], - Union[str, int], - ] -): +def get_crowsnest_status() -> ComponentStatus: files = [ Path("/usr/local/bin/crowsnest"), Path("/etc/logrotate.d/crowsnest"), Path("/etc/systemd/system/crowsnest.service"), ] - status = get_install_status(CROWSNEST_DIR, files) - return { - "status": status.get("status"), - "status_code": status.get("status_code"), - "repo": get_repo_name(CROWSNEST_DIR), - "local": get_local_commit(CROWSNEST_DIR), - "remote": get_remote_commit(CROWSNEST_DIR), - } + return get_install_status(CROWSNEST_DIR, files=files) def remove_crowsnest() -> None: diff --git a/kiauh/components/klipper/klipper_utils.py b/kiauh/components/klipper/klipper_utils.py index 691c790..2689951 100644 --- a/kiauh/components/klipper/klipper_utils.py +++ b/kiauh/components/klipper/klipper_utils.py @@ -12,7 +12,7 @@ import os import re import shutil from subprocess import CalledProcessError, run -from typing import Dict, List, Literal, Optional, Union +from typing import Dict, List, Optional, Union from components.klipper import ( KLIPPER_BACKUP_DIR, @@ -39,29 +39,16 @@ from core.instance_manager.base_instance import BaseInstance from core.instance_manager.instance_manager import InstanceManager from core.instance_manager.name_scheme import NameScheme from utils import PRINTER_CFG_BACKUP_DIR -from utils.common import get_install_status_common +from utils.common import get_install_status from utils.constants import CURRENT_USER -from utils.git_utils import get_local_commit, get_remote_commit, get_repo_name from utils.input_utils import get_confirm, get_number_input, get_string_input from utils.logger import DialogType, Logger from utils.sys_utils import cmd_sysctl_service +from utils.types import ComponentStatus -def get_klipper_status() -> ( - Dict[ - Literal["status", "status_code", "instances", "repo", "local", "remote"], - Union[str, int], - ] -): - status = get_install_status_common(Klipper, KLIPPER_DIR, KLIPPER_ENV_DIR) - return { - "status": status.get("status"), - "status_code": status.get("status_code"), - "instances": status.get("instances"), - "repo": get_repo_name(KLIPPER_DIR), - "local": get_local_commit(KLIPPER_DIR), - "remote": get_remote_commit(KLIPPER_DIR), - } +def get_klipper_status() -> ComponentStatus: + return get_install_status(KLIPPER_DIR, KLIPPER_ENV_DIR, Klipper) def check_is_multi_install( diff --git a/kiauh/components/klipperscreen/klipperscreen.py b/kiauh/components/klipperscreen/klipperscreen.py index 87dcc03..1b2ce89 100644 --- a/kiauh/components/klipperscreen/klipperscreen.py +++ b/kiauh/components/klipperscreen/klipperscreen.py @@ -8,39 +8,40 @@ # ======================================================================= # import shutil from pathlib import Path -from subprocess import run, CalledProcessError -from typing import List, Dict, Literal, Union +from subprocess import CalledProcessError, run +from typing import List from components.klipper.klipper import Klipper from components.klipperscreen import ( - KLIPPERSCREEN_DIR, - KLIPPERSCREEN_REPO, - KLIPPERSCREEN_ENV, KLIPPERSCREEN_BACKUP_DIR, + KLIPPERSCREEN_DIR, + KLIPPERSCREEN_ENV, + KLIPPERSCREEN_REPO, ) from components.moonraker.moonraker import Moonraker from core.backup_manager.backup_manager import BackupManager from core.instance_manager.instance_manager import InstanceManager from core.settings.kiauh_settings import KiauhSettings -from utils.common import get_install_status, check_install_dependencies +from utils.common import ( + check_install_dependencies, + get_install_status, +) from utils.config_utils import add_config_section, remove_config_section from utils.constants import SYSTEMD from utils.fs_utils import remove_with_sudo from utils.git_utils import ( git_clone_wrapper, git_pull_wrapper, - get_repo_name, - get_local_commit, - get_remote_commit, ) from utils.input_utils import get_confirm -from utils.logger import Logger, DialogType +from utils.logger import DialogType, Logger from utils.sys_utils import ( check_python_version, + cmd_sysctl_manage, cmd_sysctl_service, install_python_requirements, - cmd_sysctl_manage, ) +from utils.types import ComponentStatus def install_klipperscreen() -> None: @@ -141,25 +142,12 @@ def update_klipperscreen() -> None: return -def get_klipperscreen_status() -> ( - Dict[ - Literal["status", "status_code", "repo", "local", "remote"], - Union[str, int], - ] -): - files = [ +def get_klipperscreen_status() -> ComponentStatus: + return get_install_status( KLIPPERSCREEN_DIR, KLIPPERSCREEN_ENV, - SYSTEMD.joinpath("KlipperScreen.service"), - ] - status = get_install_status(KLIPPERSCREEN_DIR, files) - return { - "status": status.get("status"), - "status_code": status.get("status_code"), - "repo": get_repo_name(KLIPPERSCREEN_DIR), - "local": get_local_commit(KLIPPERSCREEN_DIR), - "remote": get_remote_commit(KLIPPERSCREEN_DIR), - } + files=[SYSTEMD.joinpath("KlipperScreen.service")], + ) def remove_klipperscreen() -> None: diff --git a/kiauh/components/mobileraker/mobileraker.py b/kiauh/components/mobileraker/mobileraker.py index f08ad05..5f911de 100644 --- a/kiauh/components/mobileraker/mobileraker.py +++ b/kiauh/components/mobileraker/mobileraker.py @@ -9,7 +9,7 @@ import shutil from pathlib import Path from subprocess import CalledProcessError, run -from typing import Dict, List, Literal, Union +from typing import List from components.klipper.klipper import Klipper from components.mobileraker import ( @@ -27,9 +27,6 @@ from utils.config_utils import add_config_section, remove_config_section from utils.constants import SYSTEMD from utils.fs_utils import remove_with_sudo from utils.git_utils import ( - get_local_commit, - get_remote_commit, - get_repo_name, git_clone_wrapper, git_pull_wrapper, ) @@ -41,6 +38,7 @@ from utils.sys_utils import ( cmd_sysctl_service, install_python_requirements, ) +from utils.types import ComponentStatus def install_mobileraker() -> None: @@ -138,25 +136,12 @@ def update_mobileraker() -> None: return -def get_mobileraker_status() -> ( - Dict[ - Literal["status", "status_code", "repo", "local", "remote"], - Union[str, int], - ] -): - files = [ +def get_mobileraker_status() -> ComponentStatus: + return get_install_status( MOBILERAKER_DIR, MOBILERAKER_ENV, - SYSTEMD.joinpath("mobileraker.service"), - ] - status = get_install_status(MOBILERAKER_DIR, files) - return { - "status": status.get("status"), - "status_code": status.get("status_code"), - "repo": get_repo_name(MOBILERAKER_DIR), - "local": get_local_commit(MOBILERAKER_DIR), - "remote": get_remote_commit(MOBILERAKER_DIR), - } + files=[SYSTEMD.joinpath("mobileraker.service")], + ) def remove_mobileraker() -> None: diff --git a/kiauh/components/moonraker/moonraker_utils.py b/kiauh/components/moonraker/moonraker_utils.py index 966d58a..7312bbd 100644 --- a/kiauh/components/moonraker/moonraker_utils.py +++ b/kiauh/components/moonraker/moonraker_utils.py @@ -8,15 +8,15 @@ # ======================================================================= # import shutil -from typing import Dict, Literal, List, Union, Optional +from typing import Dict, List, Optional from components.moonraker import ( DEFAULT_MOONRAKER_PORT, MODULE_PATH, - MOONRAKER_DIR, - MOONRAKER_ENV_DIR, MOONRAKER_BACKUP_DIR, MOONRAKER_DB_BACKUP_DIR, + MOONRAKER_DIR, + MOONRAKER_ENV_DIR, ) from components.moonraker.moonraker import Moonraker from components.webui_client.base_data import BaseWebClient @@ -25,29 +25,16 @@ from components.webui_client.mainsail_data import MainsailData from core.backup_manager.backup_manager import BackupManager from core.config_manager.config_manager import ConfigManager from core.instance_manager.instance_manager import InstanceManager -from utils.common import get_install_status_common -from utils.git_utils import get_repo_name, get_local_commit, get_remote_commit +from utils.common import get_install_status from utils.logger import Logger from utils.sys_utils import ( get_ipv4_addr, ) +from utils.types import ComponentStatus -def get_moonraker_status() -> ( - Dict[ - Literal["status", "status_code", "instances", "repo", "local", "remote"], - Union[str, int], - ] -): - status = get_install_status_common(Moonraker, MOONRAKER_DIR, MOONRAKER_ENV_DIR) - return { - "status": status.get("status"), - "status_code": status.get("status_code"), - "instances": status.get("instances"), - "repo": get_repo_name(MOONRAKER_DIR), - "local": get_local_commit(MOONRAKER_DIR), - "remote": get_remote_commit(MOONRAKER_DIR), - } +def get_moonraker_status() -> ComponentStatus: + return get_install_status(MOONRAKER_DIR, MOONRAKER_ENV_DIR, Moonraker) def create_example_moonraker_conf( diff --git a/kiauh/components/webui_client/client_utils.py b/kiauh/components/webui_client/client_utils.py index f6c2746..7b42ae2 100644 --- a/kiauh/components/webui_client/client_utils.py +++ b/kiauh/components/webui_client/client_utils.py @@ -7,61 +7,53 @@ # This file may be distributed under the terms of the GNU GPLv3 license # # ======================================================================= # -import json +import json # noqa: I001 import shutil from pathlib import Path -from typing import List, Dict, Literal, Union, get_args - +from typing import List, get_args from components.klipper.klipper import Klipper from components.webui_client.base_data import ( - WebClientType, BaseWebClient, BaseWebClientConfig, + WebClientType, ) from components.webui_client.mainsail_data import MainsailData from core.backup_manager.backup_manager import BackupManager from core.settings.kiauh_settings import KiauhSettings -from utils import NGINX_SITES_AVAILABLE, NGINX_CONFD -from utils.common import get_install_status_webui -from utils.constants import COLOR_CYAN, RESET_FORMAT, COLOR_YELLOW +from utils import NGINX_CONFD, NGINX_SITES_AVAILABLE +from utils.common import get_install_status +from utils.constants import COLOR_CYAN, COLOR_YELLOW, RESET_FORMAT from utils.git_utils import ( get_latest_tag, get_latest_unstable_tag, - get_repo_name, - get_local_commit, - get_remote_commit, ) from utils.logger import Logger +from utils.types import ComponentStatus, InstallStatus def get_client_status( client: BaseWebClient, fetch_remote: bool = False -) -> Dict[Literal["status", "local", "remote"], str]: - status = get_install_status_webui( - client.client_dir, +) -> ComponentStatus: + files = [ NGINX_SITES_AVAILABLE.joinpath(client.name), NGINX_CONFD.joinpath("upstreams.conf"), NGINX_CONFD.joinpath("common_vars.conf"), - ) - local = get_local_client_version(client) - remote = get_remote_client_version(client) if fetch_remote else None - return {"status": status, "local": local, "remote": remote} + ] + status = get_install_status(client.client_dir, files=files) + + # if the client dir does not exist, set the status to not + # installed even if the other files are present + if not client.client_dir.exists(): + status["status"] = InstallStatus.NOT_INSTALLED + + status["local"] = get_local_client_version(client) + status["remote"] = get_remote_client_version(client) if fetch_remote else None + return status -def get_client_config_status( - client: BaseWebClient, -) -> Dict[ - Literal["repo", "local", "remote"], - Union[str, int], -]: - client_config = client.client_config.config_dir - - return { - "repo": get_repo_name(client_config), - "local": get_local_commit(client_config), - "remote": get_remote_commit(client_config), - } +def get_client_config_status(client: BaseWebClient) -> ComponentStatus: + return get_install_status(client.client_config.config_dir) def get_current_client_config(clients: List[BaseWebClient]) -> str: diff --git a/kiauh/core/menus/main_menu.py b/kiauh/core/menus/main_menu.py index 98bb916..9fef36a 100644 --- a/kiauh/core/menus/main_menu.py +++ b/kiauh/core/menus/main_menu.py @@ -8,7 +8,7 @@ # ======================================================================= # import textwrap -from typing import Type, Optional +from typing import Optional, Type from components.crowsnest.crowsnest import get_crowsnest_status from components.klipper.klipper_utils import get_klipper_status @@ -26,19 +26,20 @@ from core.menus import FooterType from core.menus.advanced_menu import AdvancedMenu from core.menus.backup_menu import BackupMenu from core.menus.base_menu import BaseMenu, Option -from extensions.extensions_menu import ExtensionsMenu from core.menus.install_menu import InstallMenu from core.menus.remove_menu import RemoveMenu from core.menus.settings_menu import SettingsMenu from core.menus.update_menu import UpdateMenu +from extensions.extensions_menu import ExtensionsMenu from utils.constants import ( - COLOR_MAGENTA, COLOR_CYAN, - RESET_FORMAT, - COLOR_RED, COLOR_GREEN, + COLOR_MAGENTA, + COLOR_RED, COLOR_YELLOW, + RESET_FORMAT, ) +from utils.types import ComponentStatus # noinspection PyUnusedLocal @@ -91,18 +92,17 @@ class MainMenu(BaseMenu): self._get_component_status("cn", get_crowsnest_status) def _get_component_status(self, name: str, status_fn: callable, *args) -> None: - status_data = status_fn(*args) - status = status_data.get("status") - code = status_data.get("status_code") - repo = status_data.get("repo") + status_data: ComponentStatus = status_fn(*args) + code: int = status_data.get("status").value.code + status: str = status_data.get("status").value.txt + repo: str = status_data.get("repo") + instance_count: int = status_data.get("instances") - instance_count = status_data.get("instances") + count_txt: str = "" + if instance_count > 0 and code == 1: + count_txt = f": {instance_count}" - count: str = "" - if instance_count and code == 1: - count = f" {instance_count}" - - setattr(self, f"{name}_status", self._format_by_code(code, status, count)) + setattr(self, f"{name}_status", self._format_by_code(code, status, count_txt)) setattr(self, f"{name}_repo", f"{COLOR_CYAN}{repo}{RESET_FORMAT}") def _format_by_code(self, code: int, status: str, count: str) -> str: @@ -121,24 +121,26 @@ class MainMenu(BaseMenu): footer2 = f"Changelog: {COLOR_MAGENTA}https://git.io/JnmlX{RESET_FORMAT}" color = COLOR_CYAN count = 62 - len(color) - len(RESET_FORMAT) + pad1 = 32 + pad2 = 26 menu = textwrap.dedent( f""" /=======================================================\\ | {color}{header:~^{count}}{RESET_FORMAT} | |-------------------------------------------------------| - | 0) [Log-Upload] | Klipper: {self.kl_status:<32} | - | | Repo: {self.kl_repo:<32} | + | 0) [Log-Upload] | Klipper: {self.kl_status:<{pad1}} | + | | Repo: {self.kl_repo:<{pad1}} | | 1) [Install] |------------------------------------| - | 2) [Update] | Moonraker: {self.mr_status:<32} | - | 3) [Remove] | Repo: {self.mr_repo:<32} | + | 2) [Update] | Moonraker: {self.mr_status:<{pad1}} | + | 3) [Remove] | Repo: {self.mr_repo:<{pad1}} | | 4) [Advanced] |------------------------------------| - | 5) [Backup] | Mainsail: {self.ms_status:<35} | - | | Fluidd: {self.fl_status:<35} | - | S) [Settings] | Client-Config: {self.cc_status:<26} | + | 5) [Backup] | Mainsail: {self.ms_status:<{pad2}} | + | | Fluidd: {self.fl_status:<{pad2}} | + | S) [Settings] | Client-Config: {self.cc_status:<{pad2}} | | | | - | Community: | KlipperScreen: {self.ks_status:<26} | - | E) [Extensions] | Mobileraker: {self.mb_status:<26} | - | | Crowsnest: {self.cn_status:<26} | + | Community: | KlipperScreen: {self.ks_status:<{pad2}} | + | E) [Extensions] | Mobileraker: {self.mb_status:<{pad2}} | + | | Crowsnest: {self.cn_status:<{pad2}} | |-------------------------------------------------------| | {COLOR_CYAN}{footer1:^16}{RESET_FORMAT} | {footer2:^43} | """ diff --git a/kiauh/core/menus/update_menu.py b/kiauh/core/menus/update_menu.py index 7632cf3..2efe153 100644 --- a/kiauh/core/menus/update_menu.py +++ b/kiauh/core/menus/update_menu.py @@ -8,7 +8,7 @@ # ======================================================================= # import textwrap -from typing import Type, Optional +from typing import Optional, Type from components.crowsnest.crowsnest import get_crowsnest_status, update_crowsnest from components.klipper.klipper_setup import update_klipper @@ -16,12 +16,12 @@ from components.klipper.klipper_utils import ( get_klipper_status, ) from components.klipperscreen.klipperscreen import ( - update_klipperscreen, get_klipperscreen_status, + update_klipperscreen, ) from components.mobileraker.mobileraker import ( - update_mobileraker, get_mobileraker_status, + update_mobileraker, ) from components.moonraker.moonraker_setup import update_moonraker from components.moonraker.moonraker_utils import get_moonraker_status @@ -39,10 +39,11 @@ from core.menus import Option from core.menus.base_menu import BaseMenu from utils.constants import ( COLOR_GREEN, - RESET_FORMAT, - COLOR_YELLOW, COLOR_RED, + COLOR_YELLOW, + RESET_FORMAT, ) +from utils.types import ComponentStatus # noinspection PyUnusedLocal @@ -177,7 +178,7 @@ class UpdateMenu(BaseMenu): return f"{COLOR_YELLOW}{local_version}{RESET_FORMAT}" def _get_update_status(self, name: str, status_fn: callable, *args) -> None: - status_data = status_fn(*args) + status_data: ComponentStatus = status_fn(*args) local_ver = status_data.get("local") remote_ver = status_data.get("remote") color = COLOR_GREEN if remote_ver != "ERROR" else COLOR_RED diff --git a/kiauh/utils/common.py b/kiauh/utils/common.py index 1d567a3..8ca8051 100644 --- a/kiauh/utils/common.py +++ b/kiauh/utils/common.py @@ -9,7 +9,7 @@ import re from datetime import datetime from pathlib import Path -from typing import Dict, Literal, List, Type, Union +from typing import Dict, List, Literal, Optional, Type from components.klipper.klipper import Klipper from core.instance_manager.base_instance import BaseInstance @@ -18,16 +18,15 @@ from utils import PRINTER_CFG_BACKUP_DIR from utils.constants import ( COLOR_CYAN, RESET_FORMAT, - COLOR_YELLOW, - COLOR_GREEN, - COLOR_RED, ) +from utils.git_utils import get_local_commit, get_remote_commit, get_repo_name from utils.logger import Logger from utils.sys_utils import ( check_package_install, install_system_packages, update_system_package_lists, ) +from utils.types import ComponentStatus, InstallStatus def convert_camelcase_to_kebabcase(name: str) -> str: @@ -64,78 +63,50 @@ def check_install_dependencies(deps: List[str]) -> None: def get_install_status( - repo_dir: Path, opt_files: List[Path] -) -> Dict[Literal["status", "status_code", "instances"], Union[str, int]]: - status = [repo_dir.exists()] - - for f in opt_files: - status.append(f.exists()) - - if all(status): - return {"status": "Installed!", "status_code": 1} - elif not any(status): - return {"status": "Not installed!", "status_code": 2} - else: - return {"status": "Incomplete!", "status_code": 3} - - -def get_install_status_common( - instance_type: Type[BaseInstance], repo_dir: Path, env_dir: Path -) -> Dict[Literal["status", "status_code", "instances"], Union[str, int]]: + repo_dir: Path, + env_dir: Optional[Path] = None, + instance_type: Optional[Type[BaseInstance]] = None, + files: Optional[List[Path]] = None, +) -> ComponentStatus: """ - Helper method to get the installation status of software components, - which only consist of 3 major parts and if those parts exist, the - component can be considered as "installed". Typically, Klipper or - Moonraker match that criteria. - :param instance_type: The component type + Helper method to get the installation status of software components :param repo_dir: the repository directory :param env_dir: the python environment directory + :param instance_type: The component type + :param files: List of optional files to check for existence :return: Dictionary with status string, statuscode and instance count """ + checks = [repo_dir.exists()] + + if env_dir is not None: + checks.append(env_dir.exists()) + im = InstanceManager(instance_type) - instances_exist = len(im.instances) > 0 - status = [repo_dir.exists(), env_dir.exists(), instances_exist] - if all(status): - return { - "status": "Installed:", - "status_code": 1, - "instances": len(im.instances), - } - elif not any(status): - return { - "status": "Not installed!", - "status_code": 2, - "instances": len(im.instances), - } + instances = 0 + if instance_type is not None: + instances = len(im.instances) + checks.append(instances > 0) + + if files is not None: + for f in files: + checks.append(f.exists()) + + if all(checks): + status = InstallStatus.INSTALLED + + elif not any(checks): + status = InstallStatus.NOT_INSTALLED + else: - return { - "status": "Incomplete!", - "status_code": 3, - "instances": len(im.instances), - } + status = InstallStatus.INCOMPLETE - -def get_install_status_webui( - install_dir: Path, nginx_cfg: Path, upstreams_cfg: Path, common_cfg: Path -) -> str: - """ - Helper method to get the installation status of webuis - like Mainsail or Fluidd | - :param install_dir: folder of the static webui files - :param nginx_cfg: the webuis NGINX config - :param upstreams_cfg: the required upstreams.conf - :param common_cfg: the required common_vars.conf - :return: formatted string, containing the status - """ - status = [install_dir.exists(), nginx_cfg.exists()] - general_nginx_status = [upstreams_cfg.exists(), common_cfg.exists()] - - if all(status) and all(general_nginx_status): - return f"{COLOR_GREEN}Installed!{RESET_FORMAT}" - elif not all(status): - return f"{COLOR_RED}Not installed!{RESET_FORMAT}" - else: - return f"{COLOR_YELLOW}Incomplete!{RESET_FORMAT}" + return ComponentStatus( + status=status, + instances=instances, + repo=get_repo_name(repo_dir), + local=get_local_commit(repo_dir), + remote=get_remote_commit(repo_dir), + ) def backup_printer_config_dir(): diff --git a/kiauh/utils/types.py b/kiauh/utils/types.py new file mode 100644 index 0000000..c49a1c9 --- /dev/null +++ b/kiauh/utils/types.py @@ -0,0 +1,30 @@ +# ======================================================================= # +# Copyright (C) 2020 - 2024 Dominik Willner # +# # +# This file is part of KIAUH - Klipper Installation And Update Helper # +# https://github.com/dw-0/kiauh # +# # +# This file may be distributed under the terms of the GNU GPLv3 license # +# ======================================================================= # +from enum import Enum +from typing import Optional, TypedDict + + +class StatusInfo: + def __init__(self, txt: str, code: int): + self.txt: str = txt + self.code: int = code + + +class InstallStatus(Enum): + INSTALLED = StatusInfo("Installed", 1) + NOT_INSTALLED = StatusInfo("Not installed", 2) + INCOMPLETE = StatusInfo("Incomplete", 3) + + +class ComponentStatus(TypedDict): + status: InstallStatus + repo: Optional[str] + local: Optional[str] + remote: Optional[str] + instances: Optional[int]