feat(KIAUH): show commit in UpdateMenu

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
This commit is contained in:
dw-0
2023-12-28 13:38:24 +01:00
parent f3b0e45e39
commit dfbce3b489
6 changed files with 182 additions and 73 deletions

View File

@@ -21,7 +21,14 @@ from kiauh.core.menus.update_menu import UpdateMenu
from kiauh.modules.klipper.klipper_utils import get_klipper_status from kiauh.modules.klipper.klipper_utils import get_klipper_status
from kiauh.modules.mainsail.mainsail_utils import get_mainsail_status from kiauh.modules.mainsail.mainsail_utils import get_mainsail_status
from kiauh.modules.moonraker.moonraker_utils import get_moonraker_status from kiauh.modules.moonraker.moonraker_utils import get_moonraker_status
from kiauh.utils.constants import COLOR_MAGENTA, COLOR_CYAN, RESET_FORMAT, COLOR_RED from kiauh.utils.constants import (
COLOR_MAGENTA,
COLOR_CYAN,
RESET_FORMAT,
COLOR_RED,
COLOR_GREEN,
COLOR_YELLOW,
)
class MainMenu(BaseMenu): class MainMenu(BaseMenu):
@@ -39,18 +46,18 @@ class MainMenu(BaseMenu):
}, },
footer_type=QUIT_FOOTER, footer_type=QUIT_FOOTER,
) )
self.kl_status = None self.kl_status = ""
self.kl_repo = None self.kl_repo = ""
self.mr_status = None self.mr_status = ""
self.mr_repo = None self.mr_repo = ""
self.ms_status = None self.ms_status = ""
self.fl_status = None self.fl_status = ""
self.ks_status = None self.ks_status = ""
self.mb_status = None self.mb_status = ""
self.cn_status = None self.cn_status = ""
self.tg_status = None self.tg_status = ""
self.ob_status = None self.ob_status = ""
self.oe_status = None self.oe_status = ""
self.init_status() self.init_status()
def init_status(self) -> None: def init_status(self) -> None:
@@ -60,14 +67,30 @@ class MainMenu(BaseMenu):
def fetch_status(self) -> None: def fetch_status(self) -> None:
# klipper # klipper
self.kl_status = get_klipper_status().get("status") klipper_status = get_klipper_status()
self.kl_repo = get_klipper_status().get("repo") kl_status = klipper_status.get("status")
kl_code = klipper_status.get("status_code")
kl_instances = f" {klipper_status.get('instances')}" if kl_code == 1 else ""
self.kl_status = self.format_status_by_code(kl_code, kl_status, kl_instances)
self.kl_repo = f"{COLOR_CYAN}{klipper_status.get('repo')}{RESET_FORMAT}"
# moonraker # moonraker
self.mr_status = get_moonraker_status().get("status") moonraker_status = get_moonraker_status()
self.mr_repo = get_moonraker_status().get("repo") mr_status = moonraker_status.get("status")
mr_code = moonraker_status.get("status_code")
mr_instances = f" {moonraker_status.get('instances')}" if mr_code == 1 else ""
self.mr_status = self.format_status_by_code(mr_code, mr_status, mr_instances)
self.mr_repo = f"{COLOR_CYAN}{moonraker_status.get('repo')}{RESET_FORMAT}"
# mainsail # mainsail
self.ms_status = get_mainsail_status() self.ms_status = get_mainsail_status()
def format_status_by_code(self, code: int, status: str, count: str) -> str:
if code == 1:
return f"{COLOR_GREEN}{status}{count}{RESET_FORMAT}"
elif code == 2:
return f"{COLOR_RED}{status}{count}{RESET_FORMAT}"
return f"{COLOR_YELLOW}{status}{count}{RESET_FORMAT}"
def print_menu(self): def print_menu(self):
self.fetch_status() self.fetch_status()

View File

@@ -14,7 +14,11 @@ import textwrap
from kiauh.core.menus import BACK_FOOTER from kiauh.core.menus import BACK_FOOTER
from kiauh.core.menus.base_menu import BaseMenu from kiauh.core.menus.base_menu import BaseMenu
from kiauh.modules.klipper.klipper_setup import update_klipper from kiauh.modules.klipper.klipper_setup import update_klipper
from kiauh.utils.constants import COLOR_GREEN, RESET_FORMAT from kiauh.modules.klipper.klipper_utils import (
get_klipper_status,
)
from kiauh.modules.moonraker.moonraker_utils import get_moonraker_status
from kiauh.utils.constants import COLOR_GREEN, RESET_FORMAT, COLOR_YELLOW, COLOR_WHITE
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
@@ -39,8 +43,14 @@ class UpdateMenu(BaseMenu):
}, },
footer_type=BACK_FOOTER, footer_type=BACK_FOOTER,
) )
self.kl_local = f"{COLOR_WHITE}{RESET_FORMAT}"
self.kl_remote = f"{COLOR_WHITE}{RESET_FORMAT}"
self.mr_local = f"{COLOR_WHITE}{RESET_FORMAT}"
self.mr_remote = f"{COLOR_WHITE}{RESET_FORMAT}"
def print_menu(self): def print_menu(self):
self.fetch_update_status()
header = " [ Update Menu ] " header = " [ Update Menu ] "
color = COLOR_GREEN color = COLOR_GREEN
count = 62 - len(color) - len(RESET_FORMAT) count = 62 - len(color) - len(RESET_FORMAT)
@@ -49,28 +59,28 @@ class UpdateMenu(BaseMenu):
/=======================================================\\ /=======================================================\\
| {color}{header:~^{count}}{RESET_FORMAT} | | {color}{header:~^{count}}{RESET_FORMAT} |
|-------------------------------------------------------| |-------------------------------------------------------|
| 0) [Update all] | | | | 0) Update all | | |
| | Current: | Latest: | | | Current: | Latest: |
| Klipper & API: |--------------|--------------| | Klipper & API: |---------------|---------------|
| 1) [Klipper] | | | | 1) Klipper | {self.kl_local:<22} | {self.kl_remote:<22} |
| 2) [Moonraker] | | | | 2) Moonraker | {self.mr_local:<22} | {self.mr_remote:<22} |
| | | | | | | |
| Klipper Webinterface: |--------------|--------------| | Klipper Webinterface: |---------------|---------------|
| 3) [Mainsail] | | | | 3) Mainsail | | |
| 4) [Fluidd] | | | | 4) Fluidd | | |
| | | | | | | |
| Touchscreen GUI: |--------------|--------------| | Touchscreen GUI: |---------------|---------------|
| 5) [KlipperScreen] | | | | 5) KlipperScreen | | |
| | | | | | | |
| Other: |--------------|--------------| | Other: |---------------|---------------|
| 6) [PrettyGCode] | | | | 6) PrettyGCode | | |
| 7) [Telegram Bot] | | | | 7) Telegram Bot | | |
| 8) [Obico for Klipper] | | | | 8) Obico for Klipper | | |
| 9) [OctoEverywhere] | | | | 9) OctoEverywhere | | |
| 10) [Mobileraker] | | | | 10) Mobileraker | | |
| 11) [Crowsnest] | | | | 11) Crowsnest | | |
| |-----------------------------| | |-------------------------------|
| 12) [System] | | | | 12) System | |
""" """
)[1:] )[1:]
print(menu, end="") print(menu, end="")
@@ -113,3 +123,23 @@ class UpdateMenu(BaseMenu):
def upgrade_system_packages(self): def upgrade_system_packages(self):
print("upgrade_system_packages") print("upgrade_system_packages")
def fetch_update_status(self):
# klipper
kl_status = get_klipper_status()
self.kl_local = kl_status.get("local")
self.kl_remote = kl_status.get("remote")
if self.kl_local == self.kl_remote:
self.kl_local = f"{COLOR_GREEN}{self.kl_local}{RESET_FORMAT}"
else:
self.kl_local = f"{COLOR_YELLOW}{self.kl_local}{RESET_FORMAT}"
self.kl_remote = f"{COLOR_GREEN}{self.kl_remote}{RESET_FORMAT}"
# moonraker
mr_status = get_moonraker_status()
self.mr_local = mr_status.get("local")
self.mr_remote = mr_status.get("remote")
if self.mr_local == self.mr_remote:
self.mr_local = f"{COLOR_GREEN}{self.mr_local}{RESET_FORMAT}"
else:
self.mr_local = f"{COLOR_YELLOW}{self.mr_local}{RESET_FORMAT}"
self.mr_remote = f"{COLOR_GREEN}{self.mr_remote}{RESET_FORMAT}"

View File

@@ -62,6 +62,46 @@ class RepoManager:
def target_dir(self, value) -> None: def target_dir(self, value) -> None:
self._target_dir = value self._target_dir = value
@staticmethod
def get_repo_name(repo: Path) -> str:
"""
Helper method to extract the organisation and name of a repository |
:param repo: repository to extract the values from
:return: String in form of "<orga>/<name>"
"""
try:
cmd = ["git", "-C", repo, "config", "--get", "remote.origin.url"]
result = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
return "/".join(result.decode().strip().split("/")[-2:])
except subprocess.CalledProcessError:
return "-"
@staticmethod
def get_local_commit(repo: Path) -> str:
if not repo.exists() and repo.joinpath(".git").exists():
return "-"
try:
cmd = f"cd {repo} && git describe HEAD --always --tags | cut -d '-' -f 1,2"
return subprocess.check_output(cmd, shell=True, text=True).strip()
except subprocess.CalledProcessError:
return "-"
@staticmethod
def get_remote_commit(repo: Path) -> str:
if not repo.exists() and repo.joinpath(".git").exists():
return "-"
try:
# get locally checked out branch
branch_cmd = f"cd {repo} && git branch | grep -E '\*'"
branch = subprocess.check_output(branch_cmd, shell=True, text=True)
branch = branch.split("*")[-1].strip()
cmd = f"cd {repo} && git describe 'origin/{branch}' --always --tags | cut -d '-' -f 1,2"
return subprocess.check_output(cmd, shell=True, text=True).strip()
except subprocess.CalledProcessError:
return "-"
def clone_repo(self): def clone_repo(self):
log = f"Cloning repository from '{self.repo}' with method '{self.method}'" log = f"Cloning repository from '{self.repo}' with method '{self.method}'"
Logger.print_status(log) Logger.print_status(log)

View File

@@ -23,6 +23,7 @@ from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.base_instance import BaseInstance from kiauh.core.instance_manager.base_instance import BaseInstance
from kiauh.core.instance_manager.instance_manager import InstanceManager from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.core.instance_manager.name_scheme import NameScheme from kiauh.core.instance_manager.name_scheme import NameScheme
from kiauh.core.repo_manager.repo_manager import RepoManager
from kiauh.modules.klipper import MODULE_PATH, KLIPPER_DIR, KLIPPER_ENV_DIR from kiauh.modules.klipper import MODULE_PATH, KLIPPER_DIR, KLIPPER_ENV_DIR
from kiauh.modules.klipper.klipper import Klipper from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.klipper.klipper_dialogs import ( from kiauh.modules.klipper.klipper_dialogs import (
@@ -33,17 +34,27 @@ from kiauh.modules.klipper.klipper_dialogs import (
) )
from kiauh.modules.moonraker.moonraker import Moonraker from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.modules.moonraker.moonraker_utils import moonraker_to_multi_conversion from kiauh.modules.moonraker.moonraker_utils import moonraker_to_multi_conversion
from kiauh.utils.common import get_install_status_common, get_repo_name from kiauh.utils.common import get_install_status_common
from kiauh.utils.constants import CURRENT_USER from kiauh.utils.constants import CURRENT_USER
from kiauh.utils.input_utils import get_confirm, get_string_input, get_number_input from kiauh.utils.input_utils import get_confirm, get_string_input, get_number_input
from kiauh.utils.logger import Logger from kiauh.utils.logger import Logger
from kiauh.utils.system_utils import mask_system_service from kiauh.utils.system_utils import mask_system_service
def get_klipper_status() -> Dict[Literal["status", "repo"], str]: 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 { return {
"status": get_install_status_common(Klipper, KLIPPER_DIR, KLIPPER_ENV_DIR), "status": status.get("status"),
"repo": get_repo_name(KLIPPER_DIR), "status_code": status.get("status_code"),
"instances": status.get("instances"),
"repo": RepoManager.get_repo_name(KLIPPER_DIR),
"local": RepoManager.get_local_commit(KLIPPER_DIR),
"remote": RepoManager.get_remote_commit(KLIPPER_DIR),
} }

View File

@@ -10,10 +10,11 @@
# ======================================================================= # # ======================================================================= #
import shutil import shutil
from typing import Dict, Literal, List from typing import Dict, Literal, List, Union
from kiauh.core.config_manager.config_manager import ConfigManager from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.instance_manager import InstanceManager from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.core.repo_manager.repo_manager import RepoManager
from kiauh.modules.mainsail import MAINSAIL_DIR from kiauh.modules.mainsail import MAINSAIL_DIR
from kiauh.modules.mainsail.mainsail_utils import enable_mainsail_remotemode from kiauh.modules.mainsail.mainsail_utils import enable_mainsail_remotemode
from kiauh.modules.moonraker import ( from kiauh.modules.moonraker import (
@@ -23,19 +24,27 @@ from kiauh.modules.moonraker import (
MOONRAKER_ENV_DIR, MOONRAKER_ENV_DIR,
) )
from kiauh.modules.moonraker.moonraker import Moonraker from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.utils.common import get_install_status_common, get_repo_name from kiauh.utils.common import get_install_status_common
from kiauh.utils.logger import Logger from kiauh.utils.logger import Logger
from kiauh.utils.system_utils import ( from kiauh.utils.system_utils import (
get_ipv4_addr, get_ipv4_addr,
) )
def get_moonraker_status() -> Dict[Literal["status", "repo"], str]: 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 { return {
"status": get_install_status_common( "status": status.get("status"),
Moonraker, MOONRAKER_DIR, MOONRAKER_ENV_DIR "status_code": status.get("status_code"),
), "instances": status.get("instances"),
"repo": get_repo_name(MOONRAKER_DIR), "repo": RepoManager.get_repo_name(MOONRAKER_DIR),
"local": RepoManager.get_local_commit(MOONRAKER_DIR),
"remote": RepoManager.get_remote_commit(MOONRAKER_DIR),
} }

View File

@@ -9,10 +9,9 @@
# This file may be distributed under the terms of the GNU GPLv3 license # # This file may be distributed under the terms of the GNU GPLv3 license #
# ======================================================================= # # ======================================================================= #
import subprocess
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import Dict, Literal, List, Type from typing import Dict, Literal, List, Type, Union
from kiauh.core.instance_manager.base_instance import BaseInstance from kiauh.core.instance_manager.base_instance import BaseInstance
from kiauh.core.instance_manager.instance_manager import InstanceManager from kiauh.core.instance_manager.instance_manager import InstanceManager
@@ -56,24 +55,9 @@ def check_install_dependencies(deps: List[str]) -> None:
install_system_packages(requirements) install_system_packages(requirements)
def get_repo_name(repo_dir: Path) -> str:
"""
Helper method to extract the organisation and name of a repository |
:param repo_dir: repository to extract the values from
:return: String in form of "<orga>/<name>"
"""
try:
cmd = ["git", "-C", repo_dir, "config", "--get", "remote.origin.url"]
result = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
result = "/".join(result.decode().strip().split("/")[-2:])
return f"{COLOR_CYAN}{result}{RESET_FORMAT}"
except subprocess.CalledProcessError:
return f"{COLOR_RED}-{RESET_FORMAT}"
def get_install_status_common( def get_install_status_common(
instance_type: Type[BaseInstance], repo_dir: Path, env_dir: Path instance_type: Type[BaseInstance], repo_dir: Path, env_dir: Path
) -> str: ) -> Dict[Literal["status", "status_code", "instances"], Union[str, int]]:
""" """
Helper method to get the installation status of software components, Helper method to get the installation status of software components,
which only consist of 3 major parts and if those parts exist, the which only consist of 3 major parts and if those parts exist, the
@@ -82,17 +66,29 @@ def get_install_status_common(
:param instance_type: The component type :param instance_type: The component type
:param repo_dir: the repository directory :param repo_dir: the repository directory
:param env_dir: the python environment directory :param env_dir: the python environment directory
:return: formatted string, containing the status :return: Dictionary with status string, statuscode and instance count
""" """
im = InstanceManager(instance_type) im = InstanceManager(instance_type)
instances_exist = len(im.instances) > 0 instances_exist = len(im.instances) > 0
status = [repo_dir.exists(), env_dir.exists(), instances_exist] status = [repo_dir.exists(), env_dir.exists(), instances_exist]
if all(status): if all(status):
return f"{COLOR_GREEN}Installed: {len(im.instances)}{RESET_FORMAT}" return {
"status": "Installed:",
"status_code": 1,
"instances": len(im.instances),
}
elif not any(status): elif not any(status):
return f"{COLOR_RED}Not installed!{RESET_FORMAT}" return {
"status": "Not installed!",
"status_code": 2,
"instances": len(im.instances),
}
else: else:
return f"{COLOR_YELLOW}Incomplete!{RESET_FORMAT}" return {
"status": "Incomplete!",
"status_code": 3,
"instances": len(im.instances),
}
def get_install_status_webui( def get_install_status_webui(