refactor: menu refactoring

Signed-off-by: Dominik Willner <th33xitus@gmail.com>
This commit is contained in:
dw-0
2024-03-31 00:30:44 +01:00
parent dc87d30770
commit 39f0bd8b0a
17 changed files with 271 additions and 292 deletions

View File

@@ -10,7 +10,7 @@
import textwrap import textwrap
from components.klipper import klipper_remove from components.klipper import klipper_remove
from core.menus import BACK_HELP_FOOTER from core.menus import FooterType
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
@@ -18,18 +18,18 @@ from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
class KlipperRemoveMenu(BaseMenu): class KlipperRemoveMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=False, self.header = False
options={ self.options = {
"0": self.toggle_all, "0": self.toggle_all,
"1": self.toggle_remove_klipper_service, "1": self.toggle_remove_klipper_service,
"2": self.toggle_remove_klipper_dir, "2": self.toggle_remove_klipper_dir,
"3": self.toggle_remove_klipper_env, "3": self.toggle_remove_klipper_env,
"4": self.toggle_delete_klipper_logs, "4": self.toggle_delete_klipper_logs,
"c": self.run_removal_process, "c": self.run_removal_process,
}, }
footer_type=BACK_HELP_FOOTER, self.footer_type = FooterType.BACK_HELP
)
self.remove_klipper_service = False self.remove_klipper_service = False
self.remove_klipper_dir = False self.remove_klipper_dir = False
self.remove_klipper_env = False self.remove_klipper_env = False

View File

@@ -21,7 +21,7 @@ from components.klipper_firmware.flash_utils import (
find_usb_dfu_device, find_usb_dfu_device,
flash_device, flash_device,
) )
from core.menus import BACK_HELP_FOOTER, BACK_FOOTER from core.menus import FooterType
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import COLOR_CYAN, RESET_FORMAT, COLOR_YELLOW, COLOR_RED from utils.constants import COLOR_CYAN, RESET_FORMAT, COLOR_YELLOW, COLOR_RED
@@ -33,17 +33,17 @@ from utils.logger import Logger
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class KlipperFlashMethodMenu(BaseMenu): class KlipperFlashMethodMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__()
self.header = False
self.options = {
"1": self.select_regular,
"2": self.select_sdcard,
"h": KlipperFlashMethodHelpMenu,
}
self.input_label_txt = "Select flash method"
self.footer_type = FooterType.BACK_HELP
self.flash_options = FlashOptions() self.flash_options = FlashOptions()
super().__init__(
header=False,
options={
"1": self.select_regular,
"2": self.select_sdcard,
"h": KlipperFlashMethodHelpMenu,
},
input_label_txt="Select flash method",
footer_type=BACK_HELP_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = " [ Flash MCU ] " header = " [ Flash MCU ] "
@@ -76,26 +76,26 @@ class KlipperFlashMethodMenu(BaseMenu):
def goto_next_menu(self, **kwargs): def goto_next_menu(self, **kwargs):
next_menu = KlipperFlashCommandMenu(previous_menu=self) next_menu = KlipperFlashCommandMenu(previous_menu=self)
next_menu.start() next_menu.run()
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class KlipperFlashCommandMenu(BaseMenu): class KlipperFlashCommandMenu(BaseMenu):
def __init__(self, previous_menu: BaseMenu): def __init__(self, previous_menu: BaseMenu):
super().__init__()
self.header = False
self.options = {
"1": self.select_flash,
"2": self.select_serialflash,
"h": KlipperFlashCommandHelpMenu,
}
self.default_option = self.select_flash
self.input_label_txt = "Select flash command"
self.previous_menu = previous_menu
self.footer_type = FooterType.BACK_HELP
self.flash_options = FlashOptions() self.flash_options = FlashOptions()
super().__init__(
header=False,
options={
"1": self.select_flash,
"2": self.select_serialflash,
"h": KlipperFlashCommandHelpMenu,
},
default_option="1",
input_label_txt="Select flash command",
previous_menu=previous_menu,
footer_type=BACK_HELP_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
menu = textwrap.dedent( menu = textwrap.dedent(
@@ -120,26 +120,26 @@ class KlipperFlashCommandMenu(BaseMenu):
def goto_next_menu(self, **kwargs): def goto_next_menu(self, **kwargs):
next_menu = KlipperSelectMcuConnectionMenu(previous_menu=self) next_menu = KlipperSelectMcuConnectionMenu(previous_menu=self)
next_menu.start() next_menu.run()
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class KlipperSelectMcuConnectionMenu(BaseMenu): class KlipperSelectMcuConnectionMenu(BaseMenu):
def __init__(self, previous_menu: BaseMenu): def __init__(self, previous_menu: BaseMenu):
super().__init__()
self.header = False
self.options = {
"1": self.select_usb,
"2": self.select_dfu,
"3": self.select_usb_dfu,
"h": KlipperMcuConnectionHelpMenu,
}
self.input_label_txt = "Select connection type"
self.previous_menu = previous_menu
self.footer_type = FooterType.BACK_HELP
self.flash_options = FlashOptions() self.flash_options = FlashOptions()
super().__init__(
header=False,
options={
"1": self.select_usb,
"2": self.select_dfu,
"3": self.select_usb_dfu,
"h": KlipperMcuConnectionHelpMenu,
},
input_label_txt="Select connection type",
previous_menu=previous_menu,
footer_type=BACK_HELP_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = "Make sure that the controller board is connected now!" header = "Make sure that the controller board is connected now!"
@@ -193,23 +193,22 @@ class KlipperSelectMcuConnectionMenu(BaseMenu):
def goto_next_menu(self, **kwargs): def goto_next_menu(self, **kwargs):
next_menu = KlipperSelectMcuIdMenu(previous_menu=self) next_menu = KlipperSelectMcuIdMenu(previous_menu=self)
next_menu.start() next_menu.run()
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class KlipperSelectMcuIdMenu(BaseMenu): class KlipperSelectMcuIdMenu(BaseMenu):
def __init__(self, previous_menu: BaseMenu): def __init__(self, previous_menu: BaseMenu):
super().__init__()
self.header = False
self.flash_options = FlashOptions() self.flash_options = FlashOptions()
self.mcu_list = self.flash_options.mcu_list self.mcu_list = self.flash_options.mcu_list
options = {f"{index}": self.flash_mcu for index in range(len(self.mcu_list))} options = {f"{index}": self.flash_mcu for index in range(len(self.mcu_list))}
super().__init__( self.options = options
header=False, self.input_label_txt = "Select MCU to flash"
options=options, self.previous_menu = previous_menu
input_label_txt="Select MCU to flash", self.footer_type = FooterType.BACK_HELP
previous_menu=previous_menu,
footer_type=BACK_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = "!!! ATTENTION !!!" header = "!!! ATTENTION !!!"
@@ -262,11 +261,8 @@ class KlipperSelectMcuIdMenu(BaseMenu):
class KlipperFlashMethodHelpMenu(BaseMenu): class KlipperFlashMethodHelpMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=False, self.header = False
options={},
footer_type=BACK_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = " < ? > Help: Flash MCU < ? > " header = " < ? > Help: Flash MCU < ? > "
@@ -309,11 +305,8 @@ class KlipperFlashMethodHelpMenu(BaseMenu):
class KlipperFlashCommandHelpMenu(BaseMenu): class KlipperFlashCommandHelpMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=False, self.header = False
options={},
footer_type=BACK_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = " < ? > Help: Flash MCU < ? > " header = " < ? > Help: Flash MCU < ? > "
@@ -343,11 +336,8 @@ class KlipperFlashCommandHelpMenu(BaseMenu):
class KlipperMcuConnectionHelpMenu(BaseMenu): class KlipperMcuConnectionHelpMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=False, self.header = False
options={},
footer_type=BACK_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = " < ? > Help: Flash MCU < ? > " header = " < ? > Help: Flash MCU < ? > "

View File

@@ -11,7 +11,6 @@ import textwrap
from components.log_uploads.log_upload_utils import get_logfile_list from components.log_uploads.log_upload_utils import get_logfile_list
from components.log_uploads.log_upload_utils import upload_logfile from components.log_uploads.log_upload_utils import upload_logfile
from core.menus import BACK_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import RESET_FORMAT, COLOR_YELLOW from utils.constants import RESET_FORMAT, COLOR_YELLOW
@@ -19,13 +18,11 @@ from utils.constants import RESET_FORMAT, COLOR_YELLOW
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class LogUploadMenu(BaseMenu): class LogUploadMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__()
self.header = True
self.logfile_list = get_logfile_list() self.logfile_list = get_logfile_list()
options = {f"{index}": self.upload for index in range(len(self.logfile_list))} options = {f"{index}": self.upload for index in range(len(self.logfile_list))}
super().__init__( self.options = options
header=True,
options=options,
footer_type=BACK_FOOTER,
)
def print_menu(self): def print_menu(self):
header = " [ Log Upload ] " header = " [ Log Upload ] "

View File

@@ -10,7 +10,6 @@
import textwrap import textwrap
from components.moonraker import moonraker_remove from components.moonraker import moonraker_remove
from core.menus import BACK_HELP_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
@@ -18,19 +17,18 @@ from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
class MoonrakerRemoveMenu(BaseMenu): class MoonrakerRemoveMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=False, self.header = False
options={ self.options = {
"0": self.toggle_all, "0": self.toggle_all,
"1": self.toggle_remove_moonraker_service, "1": self.toggle_remove_moonraker_service,
"2": self.toggle_remove_moonraker_dir, "2": self.toggle_remove_moonraker_dir,
"3": self.toggle_remove_moonraker_env, "3": self.toggle_remove_moonraker_env,
"4": self.toggle_remove_moonraker_polkit, "4": self.toggle_remove_moonraker_polkit,
"5": self.toggle_delete_moonraker_logs, "5": self.toggle_delete_moonraker_logs,
"c": self.run_removal_process, "c": self.run_removal_process,
}, }
footer_type=BACK_HELP_FOOTER,
)
self.remove_moonraker_service = False self.remove_moonraker_service = False
self.remove_moonraker_dir = False self.remove_moonraker_dir = False
self.remove_moonraker_env = False self.remove_moonraker_env = False

View File

@@ -11,7 +11,6 @@ import textwrap
from typing import Callable, Dict from typing import Callable, Dict
from components.webui_client import client_remove, ClientData from components.webui_client import client_remove, ClientData
from core.menus import BACK_HELP_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
@@ -19,25 +18,23 @@ from utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
class ClientRemoveMenu(BaseMenu): class ClientRemoveMenu(BaseMenu):
def __init__(self, client: ClientData): def __init__(self, client: ClientData):
super().__init__()
self.header = False
self.options = self.get_options(client)
self.client = client self.client = client
self.rm_client = False self.rm_client = False
self.rm_client_config = False self.rm_client_config = False
self.backup_mainsail_config_json = False self.backup_mainsail_config_json = False
super().__init__( def get_options(self, client: ClientData) -> Dict[str, Callable]:
header=False,
options=self.get_options(),
footer_type=BACK_HELP_FOOTER,
)
def get_options(self) -> Dict[str, Callable]:
options = { options = {
"0": self.toggle_all, "0": self.toggle_all,
"1": self.toggle_rm_client, "1": self.toggle_rm_client,
"2": self.toggle_rm_client_config, "2": self.toggle_rm_client_config,
"c": self.run_removal_process, "c": self.run_removal_process,
} }
if self.client.get("name") == "mainsail": if client.get("name") == "mainsail":
options["3"] = self.toggle_backup_mainsail_config_json options["3"] = self.toggle_backup_mainsail_config_json
return options return options

View File

@@ -7,6 +7,17 @@
# 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 #
# ======================================================================= # # ======================================================================= #
QUIT_FOOTER = "quit" from enum import Enum
BACK_FOOTER = "back"
BACK_HELP_FOOTER = "back_help"
class FooterType(Enum):
QUIT = "QUIT"
BACK = "BACK"
BACK_HELP = "BACK_HELP"
NAVI_OPTIONS = {
FooterType.QUIT: ["q"],
FooterType.BACK: ["b"],
FooterType.BACK_HELP: ["b", "h"],
}

View File

@@ -9,26 +9,25 @@
import textwrap import textwrap
from components.klipper_firmware.menus.klipper_flash_menu import KlipperFlashMethodMenu from components.klipper_firmware.menus.klipper_flash_menu import (
from core.menus import BACK_FOOTER KlipperFlashMethodMenu,
KlipperSelectMcuConnectionMenu,
)
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import COLOR_YELLOW, RESET_FORMAT from utils.constants import COLOR_YELLOW, RESET_FORMAT
class AdvancedMenu(BaseMenu): class AdvancedMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=True, self.options = {
options={ "1": None,
"1": None, "2": None,
"2": None, "3": None,
"3": None, "4": KlipperFlashMethodMenu,
"4": KlipperFlashMethodMenu, "5": None,
"5": None, "6": KlipperSelectMcuConnectionMenu,
"6": None, }
},
footer_type=BACK_FOOTER,
)
def print_menu(self): def print_menu(self):
header = " [ Advanced Menu ] " header = " [ Advanced Menu ] "

View File

@@ -19,7 +19,6 @@ from components.webui_client.client_utils import (
load_client_data, load_client_data,
backup_client_config_data, backup_client_config_data,
) )
from core.menus import BACK_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.common import backup_printer_config_dir from utils.common import backup_printer_config_dir
from utils.constants import COLOR_CYAN, RESET_FORMAT, COLOR_YELLOW from utils.constants import COLOR_CYAN, RESET_FORMAT, COLOR_YELLOW
@@ -29,21 +28,18 @@ from utils.constants import COLOR_CYAN, RESET_FORMAT, COLOR_YELLOW
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class BackupMenu(BaseMenu): class BackupMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=True, self.options = {
options={ "1": self.backup_klipper,
"1": self.backup_klipper, "2": self.backup_moonraker,
"2": self.backup_moonraker, "3": self.backup_printer_config,
"3": self.backup_printer_config, "4": self.backup_moonraker_db,
"4": self.backup_moonraker_db, "5": self.backup_mainsail,
"5": self.backup_mainsail, "6": self.backup_fluidd,
"6": self.backup_fluidd, "7": self.backup_mainsail_config,
"7": self.backup_mainsail_config, "8": self.backup_fluidd_config,
"8": self.backup_fluidd_config, "9": self.backup_klipperscreen,
"9": self.backup_klipperscreen, }
},
footer_type=BACK_FOOTER,
)
def print_menu(self): def print_menu(self):
header = " [ Backup Menu ] " header = " [ Backup Menu ] "

View File

@@ -13,9 +13,9 @@ import subprocess
import sys import sys
import textwrap import textwrap
from abc import abstractmethod, ABC from abc import abstractmethod, ABC
from typing import Dict, Any, Literal, Union, Callable from typing import Dict, Union, Callable, Type
from core.menus import QUIT_FOOTER, BACK_FOOTER, BACK_HELP_FOOTER from core.menus import FooterType, NAVI_OPTIONS
from utils.constants import ( from utils.constants import (
COLOR_GREEN, COLOR_GREEN,
COLOR_YELLOW, COLOR_YELLOW,
@@ -92,74 +92,86 @@ def print_back_help_footer():
print(footer, end="") print(footer, end="")
class BaseMenu(ABC): Option = Union[Callable, Type["BaseMenu"], "BaseMenu"]
NAVI_OPTIONS = {"quit": ["q"], "back": ["b"], "back_help": ["b", "h"]} Options = Dict[str, Option]
def __init__(
self, class BaseMenu(ABC):
options: Dict[str, Union[Callable, Any]], options: Options = None
options_offset: int = 0, options_offset: int = 0
default_option: Union[str, None] = None, default_option: Union[Option, None] = None
input_label_txt: Union[str, None] = None, input_label_txt: str = "Perform action"
header: bool = True, header: bool = True
previous_menu: BaseMenu = None, previous_menu: Union[Type[BaseMenu], BaseMenu] = None
footer_type: Literal[ footer_type: FooterType = FooterType.BACK
"QUIT_FOOTER", "BACK_FOOTER", "BACK_HELP_FOOTER"
] = QUIT_FOOTER, def __init__(self):
): if type(self) is BaseMenu:
self.previous_menu = previous_menu raise NotImplementedError("BaseMenu cannot be instantiated directly.")
self.options = options
self.default_option = default_option
self.options_offset = options_offset
self.input_label_txt = input_label_txt
self.header = header
self.footer_type = footer_type
@abstractmethod @abstractmethod
def print_menu(self) -> None: def print_menu(self) -> None:
raise NotImplementedError("Subclasses must implement the print_menu method") raise NotImplementedError("Subclasses must implement the print_menu method")
def print_footer(self) -> None: def print_footer(self) -> None:
footer_type_map = { if self.footer_type is FooterType.QUIT:
QUIT_FOOTER: print_quit_footer, print_quit_footer()
BACK_FOOTER: print_back_footer, elif self.footer_type is FooterType.BACK:
BACK_HELP_FOOTER: print_back_help_footer, print_back_footer()
} elif self.footer_type is FooterType.BACK_HELP:
footer_function = footer_type_map.get(self.footer_type, print_quit_footer) print_back_help_footer()
footer_function() else:
raise NotImplementedError("Method for printing footer not implemented.")
def display(self) -> None: def display_menu(self) -> None:
# clear() # clear()
if self.header: if self.header:
print_header() print_header()
self.print_menu() self.print_menu()
self.print_footer() self.print_footer()
def handle_user_input(self) -> str: def validate_user_input(self, usr_input: str) -> Union[Option, str, None]:
"""
Validate the user input and either return an Option, a string or None
:param usr_input: The user input in form of a string
:return: Option, str or None
"""
usr_input = usr_input.lower()
option = self.options.get(usr_input, None)
# check if usr_input contains a character used for basic navigation, e.g. b, h or q
# and if the current menu has the appropriate footer to allow for that action
is_valid_navigation = self.footer_type in NAVI_OPTIONS
user_navigated = usr_input in NAVI_OPTIONS[self.footer_type]
if is_valid_navigation and user_navigated:
return usr_input
# if usr_input is None or an empty string, we execute the menues default option if specified
if option is None or option == "" and self.default_option is not None:
return self.default_option
# user selected a regular option
if option is not None:
return option
return None
def handle_user_input(self) -> Union[Option, str]:
"""Handle the user input, return the validated input or print an error."""
while True: while True:
label_text = ( print(f"{COLOR_CYAN}###### {self.input_label_txt}: {RESET_FORMAT}", end="")
"Perform action" usr_input = input().lower()
if self.input_label_txt is None or self.input_label_txt == "" validated_input = self.validate_user_input(usr_input)
else self.input_label_txt
)
choice = input(f"{COLOR_CYAN}###### {label_text}: {RESET_FORMAT}").lower()
option = self.options.get(choice, None)
has_navi_option = self.footer_type in self.NAVI_OPTIONS if validated_input is not None:
user_navigated = choice in self.NAVI_OPTIONS[self.footer_type] return validated_input
if has_navi_option and user_navigated:
return choice
if option is not None:
return choice
elif option is None and self.default_option is not None:
return self.default_option
else: else:
Logger.print_error("Invalid input!", False) Logger.print_error("Invalid input!", False)
def start(self) -> None: def run(self) -> None:
"""Start the menu lifecycle. When this function returns, the lifecycle of the menu ends."""
while True: while True:
self.display() self.display_menu()
choice = self.handle_user_input() choice = self.handle_user_input()
if choice == "q": if choice == "q":
@@ -170,21 +182,16 @@ class BaseMenu(ABC):
else: else:
self.execute_option(choice) self.execute_option(choice)
def execute_option(self, choice: str) -> None: def execute_option(self, option: Option) -> None:
option = self.options.get(choice, None) if option is None:
raise NotImplementedError(f"No implementation for {option}")
if isinstance(option, type) and issubclass(option, BaseMenu): if isinstance(option, type) and issubclass(option, BaseMenu):
self.navigate_to_menu(option, True) self.navigate_to_menu(option, True)
elif isinstance(option, BaseMenu): elif isinstance(option, BaseMenu):
self.navigate_to_menu(option, False) self.navigate_to_menu(option, False)
elif callable(option): elif callable(option):
option(opt_index=choice) option()
elif option is None:
raise NotImplementedError(f"No implementation for option {choice}")
else:
raise TypeError(
f"Type {type(option)} of option {choice} not of type BaseMenu or Method"
)
def navigate_to_menu(self, menu, instantiate: bool) -> None: def navigate_to_menu(self, menu, instantiate: bool) -> None:
""" """
@@ -196,4 +203,4 @@ class BaseMenu(ABC):
""" """
menu = menu() if instantiate else menu menu = menu() if instantiate else menu
menu.previous_menu = self menu.previous_menu = self
menu.start() menu.run()

View File

@@ -12,11 +12,10 @@ import inspect
import json import json
import textwrap import textwrap
from pathlib import Path from pathlib import Path
from typing import List, Dict from typing import List
from core.base_extension import BaseExtension from core.base_extension import BaseExtension
from core.menus import BACK_FOOTER from core.menus.base_menu import BaseMenu, Options
from core.menus.base_menu import BaseMenu
from utils.constants import RESET_FORMAT, COLOR_CYAN, COLOR_YELLOW from utils.constants import RESET_FORMAT, COLOR_CYAN, COLOR_YELLOW
@@ -24,12 +23,11 @@ from utils.constants import RESET_FORMAT, COLOR_CYAN, COLOR_YELLOW
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class ExtensionsMenu(BaseMenu): class ExtensionsMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__()
self.header = False
self.options: Options = self.get_options()
self.extensions = self.discover_extensions() self.extensions = self.discover_extensions()
super().__init__(
header=False,
options=self.get_options(),
footer_type=BACK_FOOTER,
)
def discover_extensions(self) -> List[BaseExtension]: def discover_extensions(self) -> List[BaseExtension]:
extensions = [] extensions = []
@@ -58,8 +56,8 @@ class ExtensionsMenu(BaseMenu):
return sorted(extensions, key=lambda ex: ex.metadata.get("index")) return sorted(extensions, key=lambda ex: ex.metadata.get("index"))
def get_options(self) -> Dict[str, BaseMenu]: def get_options(self) -> Options:
options = {} options: Options = {}
for extension in self.extensions: for extension in self.extensions:
index = extension.metadata.get("index") index = extension.metadata.get("index")
options[f"{index}"] = ExtensionSubmenu(extension) options[f"{index}"] = ExtensionSubmenu(extension)
@@ -93,17 +91,16 @@ class ExtensionsMenu(BaseMenu):
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class ExtensionSubmenu(BaseMenu): class ExtensionSubmenu(BaseMenu):
def __init__(self, extension: BaseExtension): def __init__(self, extension: BaseExtension):
super().__init__()
self.header = False
self.options = {
"1": extension.install_extension,
"2": extension.remove_extension,
}
self.extension = extension self.extension = extension
self.extension_name = extension.metadata.get("display_name") self.extension_name = extension.metadata.get("display_name")
self.extension_desc = extension.metadata.get("description") self.extension_desc = extension.metadata.get("description")
super().__init__(
header=False,
options={
"1": extension.install_extension,
"2": extension.remove_extension,
},
footer_type=BACK_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = f" [ {self.extension_name} ] " header = f" [ {self.extension_name} ] "

View File

@@ -13,7 +13,7 @@ from components.klipper import klipper_setup
from components.moonraker import moonraker_setup from components.moonraker import moonraker_setup
from components.webui_client import client_setup from components.webui_client import client_setup
from components.webui_client.client_config import client_config_setup from components.webui_client.client_config import client_config_setup
from core.menus import BACK_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import COLOR_GREEN, RESET_FORMAT from utils.constants import COLOR_GREEN, RESET_FORMAT
@@ -22,21 +22,18 @@ from utils.constants import COLOR_GREEN, RESET_FORMAT
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class InstallMenu(BaseMenu): class InstallMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=True, self.options = {
options={ "1": self.install_klipper,
"1": self.install_klipper, "2": self.install_moonraker,
"2": self.install_moonraker, "3": self.install_mainsail,
"3": self.install_mainsail, "4": self.install_fluidd,
"4": self.install_fluidd, "5": self.install_mainsail_config,
"5": self.install_mainsail_config, "6": self.install_fluidd_config,
"6": self.install_fluidd_config, "7": None,
"7": None, "8": None,
"8": None, "9": None,
"9": None, }
},
footer_type=BACK_FOOTER,
)
def print_menu(self): def print_menu(self):
header = " [ Installation Menu ] " header = " [ Installation Menu ] "

View File

@@ -17,7 +17,7 @@ from components.webui_client.client_utils import (
load_client_data, load_client_data,
get_current_client_config, get_current_client_config,
) )
from core.menus import QUIT_FOOTER from core.menus import FooterType
from core.menus.advanced_menu import AdvancedMenu from core.menus.advanced_menu import AdvancedMenu
from core.menus.backup_menu import BackupMenu from core.menus.backup_menu import BackupMenu
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
@@ -39,20 +39,19 @@ from utils.constants import (
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class MainMenu(BaseMenu): class MainMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=True, self.options = {
options={ "0": LogUploadMenu,
"0": LogUploadMenu, "1": InstallMenu,
"1": InstallMenu, "2": UpdateMenu,
"2": UpdateMenu, "3": RemoveMenu,
"3": RemoveMenu, "4": AdvancedMenu,
"4": AdvancedMenu, "5": BackupMenu,
"5": BackupMenu, "e": ExtensionsMenu,
"e": ExtensionsMenu, "s": SettingsMenu,
"s": SettingsMenu, }
}, self.footer_type = FooterType.QUIT
footer_type=QUIT_FOOTER,
)
self.kl_status = "" self.kl_status = ""
self.kl_repo = "" self.kl_repo = ""
self.mr_status = "" self.mr_status = ""

View File

@@ -15,7 +15,6 @@ from components.moonraker.menus.moonraker_remove_menu import (
) )
from components.webui_client.client_utils import load_client_data from components.webui_client.client_utils import load_client_data
from components.webui_client.menus.client_remove_menu import ClientRemoveMenu from components.webui_client.menus.client_remove_menu import ClientRemoveMenu
from core.menus import BACK_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import COLOR_RED, RESET_FORMAT from utils.constants import COLOR_RED, RESET_FORMAT
@@ -24,25 +23,22 @@ from utils.constants import COLOR_RED, RESET_FORMAT
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class RemoveMenu(BaseMenu): class RemoveMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=True, self.options = {
options={ "1": KlipperRemoveMenu,
"1": KlipperRemoveMenu, "2": MoonrakerRemoveMenu,
"2": MoonrakerRemoveMenu, "3": ClientRemoveMenu(client=load_client_data("mainsail")),
"3": ClientRemoveMenu(client=load_client_data("mainsail")), "4": ClientRemoveMenu(client=load_client_data("fluidd")),
"4": ClientRemoveMenu(client=load_client_data("fluidd")), "5": None,
"5": None, "6": None,
"6": None, "7": None,
"7": None, "8": None,
"8": None, "9": None,
"9": None, "10": None,
"10": None, "11": None,
"11": None, "12": None,
"12": None, "13": None,
"13": None, }
},
footer_type=BACK_FOOTER,
)
def print_menu(self): def print_menu(self):
header = " [ Remove Menu ] " header = " [ Remove Menu ] "

View File

@@ -13,7 +13,7 @@ from core.menus.base_menu import BaseMenu
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class SettingsMenu(BaseMenu): class SettingsMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__(header=True, options={}) super().__init__()
def print_menu(self): def print_menu(self):
print("self") print("self")

View File

@@ -25,7 +25,6 @@ from components.webui_client.client_utils import (
load_client_data, load_client_data,
get_client_config_status, get_client_config_status,
) )
from core.menus import BACK_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from utils.constants import ( from utils.constants import (
COLOR_GREEN, COLOR_GREEN,
@@ -40,23 +39,21 @@ from utils.constants import (
# noinspection PyMethodMayBeStatic # noinspection PyMethodMayBeStatic
class UpdateMenu(BaseMenu): class UpdateMenu(BaseMenu):
def __init__(self): def __init__(self):
super().__init__( super().__init__()
header=True, self.options = {
options={ "0": self.update_all,
"0": self.update_all, "1": self.update_klipper,
"1": self.update_klipper, "2": self.update_moonraker,
"2": self.update_moonraker, "3": self.update_mainsail,
"3": self.update_mainsail, "4": self.update_fluidd,
"4": self.update_fluidd, "5": self.update_mainsail_config,
"5": self.update_mainsail_config, "6": self.update_fluidd_config,
"6": self.update_fluidd_config, "7": self.update_klipperscreen,
"7": self.update_klipperscreen, "8": self.update_mobileraker,
"8": self.update_mobileraker, "9": self.update_crowsnest,
"9": self.update_crowsnest, "10": self.upgrade_system_packages,
"10": self.upgrade_system_packages, }
},
footer_type=BACK_FOOTER,
)
self.kl_local = f"{COLOR_WHITE}{RESET_FORMAT}" self.kl_local = f"{COLOR_WHITE}{RESET_FORMAT}"
self.kl_remote = f"{COLOR_WHITE}{RESET_FORMAT}" self.kl_remote = f"{COLOR_WHITE}{RESET_FORMAT}"
self.mr_local = f"{COLOR_WHITE}{RESET_FORMAT}" self.mr_local = f"{COLOR_WHITE}{RESET_FORMAT}"

View File

@@ -22,7 +22,6 @@ from components.klipper.klipper_dialogs import (
from core.base_extension import BaseExtension from core.base_extension import BaseExtension
from core.instance_manager.base_instance import BaseInstance from core.instance_manager.base_instance import BaseInstance
from core.instance_manager.instance_manager import InstanceManager from core.instance_manager.instance_manager import InstanceManager
from core.menus import BACK_FOOTER
from core.menus.base_menu import BaseMenu from core.menus.base_menu import BaseMenu
from core.repo_manager.repo_manager import RepoManager from core.repo_manager.repo_manager import RepoManager
from utils.constants import COLOR_YELLOW, COLOR_CYAN, RESET_FORMAT from utils.constants import COLOR_YELLOW, COLOR_CYAN, RESET_FORMAT
@@ -44,7 +43,7 @@ class MainsailThemeInstallerExtension(BaseExtension):
def install_extension(self, **kwargs) -> None: def install_extension(self, **kwargs) -> None:
install_menu = MainsailThemeInstallMenu(self.instances) install_menu = MainsailThemeInstallMenu(self.instances)
install_menu.start() install_menu.run()
def remove_extension(self, **kwargs) -> None: def remove_extension(self, **kwargs) -> None:
print_instance_overview( print_instance_overview(
@@ -79,14 +78,13 @@ class MainsailThemeInstallMenu(BaseMenu):
) )
def __init__(self, instances: List[Klipper]): def __init__(self, instances: List[Klipper]):
self.instances = instances super().__init__()
self.header = False
self.themes: List[ThemeData] = self.load_themes() self.themes: List[ThemeData] = self.load_themes()
options = {f"{index}": self.install_theme for index in range(len(self.themes))} options = {f"{index}": self.install_theme for index in range(len(self.themes))}
super().__init__( self.options = options
header=False,
options=options, self.instances = instances
footer_type=BACK_FOOTER,
)
def print_menu(self) -> None: def print_menu(self) -> None:
header = " [ Mainsail Theme Installer ] " header = " [ Mainsail Theme Installer ] "

View File

@@ -13,6 +13,6 @@ from utils.logger import Logger
def main(): def main():
try: try:
MainMenu().start() MainMenu().run()
except KeyboardInterrupt: except KeyboardInterrupt:
Logger.print_ok("\nHappy printing!\n", prefix=False) Logger.print_ok("\nHappy printing!\n", prefix=False)