Compare commits

..

5 Commits

Author SHA1 Message Date
dw-0
6225ee59d0 fix: add sysd_dir to base_folders
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-31 08:18:22 +02:00
dw-0
535c50a3ac fix: better check for still existing services during removal
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-31 08:17:59 +02:00
dw-0
e26315f469 chore: remove unused menu attribute from Option class
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-25 20:25:12 +02:00
dw-0
b77f1356bf chore(extension): update print menu to use new style
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-25 20:07:13 +02:00
dw-0
d201f54cee refactor(extension): fix typing
Signed-off-by: Dominik Willner <th33xitus@gmail.com>
2024-08-25 20:03:56 +02:00
19 changed files with 139 additions and 123 deletions

View File

@@ -18,6 +18,7 @@ from core.logger import Logger
from utils.fs_utils import run_remove_routines
from utils.input_utils import get_selection_input
from utils.instance_utils import get_instances
from utils.sys_utils import unit_file_exists
def run_klipper_removal(
@@ -35,7 +36,7 @@ def run_klipper_removal(
else:
Logger.print_info("No Klipper Services installed! Skipped ...")
if (remove_dir or remove_env) and klipper_instances:
if (remove_dir or remove_env) and unit_file_exists("klipper", suffix="service"):
Logger.print_info("There are still other Klipper services installed:")
Logger.print_info(f"'{KLIPPER_DIR}' was not removed.", prefix=False)
Logger.print_info(f"'{KLIPPER_ENV_DIR}' was not removed.", prefix=False)

View File

@@ -35,11 +35,11 @@ class KlipperRemoveMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"a": Option(method=self.toggle_all, menu=False),
"1": Option(method=self.toggle_remove_klipper_service, menu=False),
"2": Option(method=self.toggle_remove_klipper_dir, menu=False),
"3": Option(method=self.toggle_remove_klipper_env, menu=False),
"c": Option(method=self.run_removal_process, menu=False),
"a": Option(method=self.toggle_all),
"1": Option(method=self.toggle_remove_klipper_service),
"2": Option(method=self.toggle_remove_klipper_dir),
"3": Option(method=self.toggle_remove_klipper_env),
"c": Option(method=self.run_removal_process),
}
def print_menu(self) -> None:

View File

@@ -47,10 +47,10 @@ class KlipperBuildFirmwareMenu(BaseMenu):
def set_options(self) -> None:
if len(self.missing_deps) == 0:
self.input_label_txt = "Press ENTER to continue"
self.default_option = Option(method=self.start_build_process, menu=False)
self.default_option = Option(method=self.start_build_process)
else:
self.input_label_txt = "Press ENTER to install dependencies"
self.default_option = Option(method=self.install_missing_deps, menu=False)
self.default_option = Option(method=self.install_missing_deps)
def print_menu(self) -> None:
header = " [ Build Firmware Menu ] "

View File

@@ -61,8 +61,8 @@ class KlipperFlashMethodMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(self.select_regular, menu=False),
"2": Option(self.select_sdcard, menu=False),
"1": Option(self.select_regular),
"2": Option(self.select_sdcard),
}
def print_menu(self) -> None:
@@ -123,10 +123,10 @@ class KlipperFlashCommandMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(self.select_flash, menu=False),
"2": Option(self.select_serialflash, menu=False),
"1": Option(self.select_flash),
"2": Option(self.select_serialflash),
}
self.default_option = Option(self.select_flash, menu=False)
self.default_option = Option(self.select_flash)
def print_menu(self) -> None:
menu = textwrap.dedent(
@@ -174,9 +174,9 @@ class KlipperSelectMcuConnectionMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(method=self.select_usb, menu=False),
"2": Option(method=self.select_dfu, menu=False),
"3": Option(method=self.select_usb_dfu, menu=False),
"1": Option(method=self.select_usb),
"2": Option(method=self.select_dfu),
"3": Option(method=self.select_usb_dfu),
}
def print_menu(self) -> None:
@@ -393,11 +393,11 @@ class KlipperFlashOverviewMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"Y": Option(self.execute_flash, menu=False),
"N": Option(self.abort_process, menu=False),
"Y": Option(self.execute_flash),
"N": Option(self.abort_process),
}
self.default_option = Option(self.execute_flash, menu=False)
self.default_option = Option(self.execute_flash)
def print_menu(self) -> None:
header = "!!! ATTENTION !!!"

View File

@@ -35,12 +35,12 @@ class MoonrakerRemoveMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"a": Option(method=self.toggle_all, menu=False),
"1": Option(method=self.toggle_remove_moonraker_service, menu=False),
"2": Option(method=self.toggle_remove_moonraker_dir, menu=False),
"3": Option(method=self.toggle_remove_moonraker_env, menu=False),
"4": Option(method=self.toggle_remove_moonraker_polkit, menu=False),
"c": Option(method=self.run_removal_process, menu=False),
"a": Option(method=self.toggle_all),
"1": Option(method=self.toggle_remove_moonraker_service),
"2": Option(method=self.toggle_remove_moonraker_dir),
"3": Option(method=self.toggle_remove_moonraker_env),
"4": Option(method=self.toggle_remove_moonraker_polkit),
"c": Option(method=self.run_removal_process),
}
def print_menu(self) -> None:

View File

@@ -19,6 +19,7 @@ from core.logger import Logger
from utils.fs_utils import run_remove_routines
from utils.input_utils import get_selection_input
from utils.instance_utils import get_instances
from utils.sys_utils import unit_file_exists
def run_moonraker_removal(
@@ -37,7 +38,8 @@ def run_moonraker_removal(
else:
Logger.print_info("No Moonraker Services installed! Skipped ...")
if (remove_polkit or remove_dir or remove_env) and instances:
delete_remaining: bool = remove_polkit or remove_dir or remove_env
if delete_remaining and unit_file_exists("moonraker", suffix="service"):
Logger.print_info("There are still other Moonraker services installed")
Logger.print_info(
"● Moonraker PolicyKit rules were not removed.", prefix=False

View File

@@ -38,11 +38,11 @@ class ClientRemoveMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"a": Option(method=self.toggle_all, menu=False),
"1": Option(method=self.toggle_rm_client, menu=False),
"2": Option(method=self.toggle_rm_client_config, menu=False),
"3": Option(method=self.toggle_backup_config_json, menu=False),
"c": Option(method=self.run_removal_process, menu=False),
"a": Option(method=self.toggle_all),
"1": Option(method=self.toggle_rm_client),
"2": Option(method=self.toggle_rm_client_config),
"3": Option(method=self.toggle_backup_config_json),
"c": Option(method=self.run_removal_process),
}
def print_menu(self) -> None:

View File

@@ -48,6 +48,7 @@ class BaseInstance:
self.log_dir,
self.gcodes_dir,
self.comms_dir,
self.sysd_dir,
]
def _set_is_legacy_instance(self) -> bool:

View File

@@ -18,13 +18,11 @@ class Option:
"""
Represents a menu option.
:param method: Method that will be used to call the menu option
:param menu: Flag for singaling that another menu will be opened
:param opt_index: Can be used to pass the user input to the menu option
:param opt_data: Can be used to pass any additional data to the menu option
"""
method: Callable | None = None
menu: bool = False
opt_index: str = ""
opt_data: Any = None

View File

@@ -43,13 +43,13 @@ class AdvancedMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(method=self.build, menu=True),
"2": Option(method=self.flash, menu=False),
"3": Option(method=self.build_flash, menu=False),
"4": Option(method=self.get_id, menu=False),
"5": Option(method=self.klipper_rollback, menu=True),
"6": Option(method=self.moonraker_rollback, menu=True),
"7": Option(method=self.change_hostname, menu=True),
"1": Option(method=self.build),
"2": Option(method=self.flash),
"3": Option(method=self.build_flash),
"4": Option(method=self.get_id),
"5": Option(method=self.klipper_rollback),
"6": Option(method=self.moonraker_rollback),
"7": Option(method=self.change_hostname),
}
def print_menu(self) -> None:

View File

@@ -43,15 +43,15 @@ class BackupMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(method=self.backup_klipper, menu=False),
"2": Option(method=self.backup_moonraker, menu=False),
"3": Option(method=self.backup_printer_config, menu=False),
"4": Option(method=self.backup_moonraker_db, menu=False),
"5": Option(method=self.backup_mainsail, menu=False),
"6": Option(method=self.backup_fluidd, menu=False),
"7": Option(method=self.backup_mainsail_config, menu=False),
"8": Option(method=self.backup_fluidd_config, menu=False),
"9": Option(method=self.backup_klipperscreen, menu=False),
"1": Option(method=self.backup_klipper),
"2": Option(method=self.backup_moonraker),
"3": Option(method=self.backup_printer_config),
"4": Option(method=self.backup_moonraker_db),
"5": Option(method=self.backup_mainsail),
"6": Option(method=self.backup_fluidd),
"7": Option(method=self.backup_mainsail_config),
"8": Option(method=self.backup_fluidd_config),
"9": Option(method=self.backup_klipperscreen),
}
def print_menu(self) -> None:

View File

@@ -123,12 +123,12 @@ class BaseMenu(metaclass=PostInitCaller):
# conditionally add options based on footer type
if self.footer_type is FooterType.QUIT:
self.options["q"] = Option(method=self.__exit, menu=False)
self.options["q"] = Option(method=self.__exit)
if self.footer_type is FooterType.BACK:
self.options["b"] = Option(method=self.__go_back, menu=False)
self.options["b"] = Option(method=self.__go_back)
if self.footer_type is FooterType.BACK_HELP:
self.options["b"] = Option(method=self.__go_back, menu=False)
self.options["h"] = Option(method=self.__go_to_help, menu=False)
self.options["b"] = Option(method=self.__go_back)
self.options["h"] = Option(method=self.__go_to_help)
# if defined, add the default option to the options dict
if self.default_option is not None:
self.options[""] = self.default_option
@@ -184,7 +184,10 @@ class BaseMenu(metaclass=PostInitCaller):
:return: Option, str or None
"""
usr_input = usr_input.lower()
option = self.options.get(usr_input, Option(None, False, "", None))
option = self.options.get(
usr_input,
Option(method=None, opt_index="", opt_data=None),
)
# if option/usr_input is None/empty string, we execute the menus default option if specified
if (option is None or usr_input == "") and self.default_option is not None:

View File

@@ -40,16 +40,16 @@ class InstallMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(method=self.install_klipper, menu=False),
"2": Option(method=self.install_moonraker, menu=False),
"3": Option(method=self.install_mainsail, menu=False),
"4": Option(method=self.install_fluidd, menu=False),
"5": Option(method=self.install_mainsail_config, menu=False),
"6": Option(method=self.install_fluidd_config, menu=False),
"7": Option(method=self.install_klipperscreen, menu=False),
"8": Option(method=self.install_mobileraker, menu=False),
"9": Option(method=self.install_crowsnest, menu=False),
"10": Option(method=self.install_octoeverywhere, menu=False),
"1": Option(method=self.install_klipper),
"2": Option(method=self.install_moonraker),
"3": Option(method=self.install_mainsail),
"4": Option(method=self.install_fluidd),
"5": Option(method=self.install_mainsail_config),
"6": Option(method=self.install_fluidd_config),
"7": Option(method=self.install_klipperscreen),
"8": Option(method=self.install_mobileraker),
"9": Option(method=self.install_crowsnest),
"10": Option(method=self.install_octoeverywhere),
}
def print_menu(self) -> None:

View File

@@ -66,14 +66,14 @@ class MainMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"0": Option(method=self.log_upload_menu, menu=True),
"1": Option(method=self.install_menu, menu=True),
"2": Option(method=self.update_menu, menu=True),
"3": Option(method=self.remove_menu, menu=True),
"4": Option(method=self.advanced_menu, menu=True),
"5": Option(method=self.backup_menu, menu=True),
"e": Option(method=self.extension_menu, menu=True),
"s": Option(method=self.settings_menu, menu=True),
"0": Option(method=self.log_upload_menu),
"1": Option(method=self.install_menu),
"2": Option(method=self.update_menu),
"3": Option(method=self.remove_menu),
"4": Option(method=self.advanced_menu),
"5": Option(method=self.backup_menu),
"e": Option(method=self.extension_menu),
"s": Option(method=self.settings_menu),
}
def _init_status(self) -> None:

View File

@@ -41,14 +41,14 @@ class RemoveMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(method=self.remove_klipper, menu=True),
"2": Option(method=self.remove_moonraker, menu=True),
"3": Option(method=self.remove_mainsail, menu=True),
"4": Option(method=self.remove_fluidd, menu=True),
"5": Option(method=self.remove_klipperscreen, menu=True),
"6": Option(method=self.remove_mobileraker, menu=True),
"7": Option(method=self.remove_crowsnest, menu=True),
"8": Option(method=self.remove_octoeverywhere, menu=True),
"1": Option(method=self.remove_klipper),
"2": Option(method=self.remove_moonraker),
"3": Option(method=self.remove_mainsail),
"4": Option(method=self.remove_fluidd),
"5": Option(method=self.remove_klipperscreen),
"6": Option(method=self.remove_mobileraker),
"7": Option(method=self.remove_crowsnest),
"8": Option(method=self.remove_octoeverywhere),
}
def print_menu(self) -> None:

View File

@@ -48,11 +48,11 @@ class SettingsMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"1": Option(method=self.set_klipper_repo, menu=True),
"2": Option(method=self.set_moonraker_repo, menu=True),
"3": Option(method=self.toggle_mainsail_release, menu=True),
"4": Option(method=self.toggle_fluidd_release, menu=False),
"5": Option(method=self.toggle_backup_before_update, menu=False),
"1": Option(method=self.set_klipper_repo),
"2": Option(method=self.set_moonraker_repo),
"3": Option(method=self.toggle_mainsail_release),
"4": Option(method=self.toggle_fluidd_release),
"5": Option(method=self.toggle_backup_before_update),
}
def print_menu(self) -> None:

View File

@@ -50,13 +50,13 @@ from core.logger import DialogType, Logger
from core.menus import Option
from core.menus.base_menu import BaseMenu
from core.spinner import Spinner
from core.types import ComponentStatus
from utils.input_utils import get_confirm
from utils.sys_utils import (
get_upgradable_packages,
update_system_package_lists,
upgrade_system_packages,
)
from core.types import ComponentStatus
# noinspection PyUnusedLocal
@@ -102,18 +102,18 @@ class UpdateMenu(BaseMenu):
def set_options(self) -> None:
self.options = {
"a": Option(self.update_all, menu=False),
"1": Option(self.update_klipper, menu=False),
"2": Option(self.update_moonraker, menu=False),
"3": Option(self.update_mainsail, menu=False),
"4": Option(self.update_fluidd, menu=False),
"5": Option(self.update_mainsail_config, menu=False),
"6": Option(self.update_fluidd_config, menu=False),
"7": Option(self.update_klipperscreen, menu=False),
"8": Option(self.update_mobileraker, menu=False),
"9": Option(self.update_crowsnest, menu=False),
"10": Option(self.update_octoeverywhere, menu=False),
"11": Option(self.upgrade_system_packages, menu=False),
"a": Option(self.update_all),
"1": Option(self.update_klipper),
"2": Option(self.update_moonraker),
"3": Option(self.update_mainsail),
"4": Option(self.update_fluidd),
"5": Option(self.update_mainsail_config),
"6": Option(self.update_fluidd_config),
"7": Option(self.update_klipperscreen),
"8": Option(self.update_mobileraker),
"9": Option(self.update_crowsnest),
"10": Option(self.update_octoeverywhere),
"11": Option(self.upgrade_system_packages),
}
def print_menu(self) -> None:

View File

@@ -119,12 +119,12 @@ class ExtensionSubmenu(BaseMenu):
)
def set_options(self) -> None:
self.options["1"] = Option(self.extension.install_extension, menu=False)
self.options["1"] = Option(self.extension.install_extension)
if self.extension.metadata.get("updates"):
self.options["2"] = Option(self.extension.update_extension, menu=False)
self.options["3"] = Option(self.extension.remove_extension, menu=False)
self.options["2"] = Option(self.extension.update_extension)
self.options["3"] = Option(self.extension.remove_extension)
else:
self.options["2"] = Option(self.extension.remove_extension, menu=False)
self.options["2"] = Option(self.extension.remove_extension)
def print_menu(self) -> None:
header = f" [ {self.extension.metadata.get('display_name')} ] "

View File

@@ -12,7 +12,8 @@ import csv
import shutil
import textwrap
import urllib.request
from typing import List, Type, TypedDict, Union
from dataclasses import dataclass
from typing import Any, Dict, List, Type, Union
from components.klipper.klipper import Klipper
from components.klipper.klipper_dialogs import (
@@ -31,7 +32,8 @@ from utils.input_utils import get_selection_input
from utils.instance_utils import get_instances
class ThemeData(TypedDict):
@dataclass
class ThemeData:
name: str
short_note: str
author: str
@@ -102,36 +104,45 @@ class MainsailThemeInstallMenu(BaseMenu):
count = 62 - len(color) - len(RESET_FORMAT)
menu = textwrap.dedent(
f"""
/=======================================================\\
| {color}{header:~^{count}}{RESET_FORMAT} |
|-------------------------------------------------------|
| {line1:<62} |
| https://docs.mainsail.xyz/theming/themes |
|-------------------------------------------------------|
╔═══════════════════════════════════════════════════════╗
{color}{header:~^{count}}{RESET_FORMAT}
╟───────────────────────────────────────────────────────╢
{line1:<62}
https://docs.mainsail.xyz/theming/themes
╟───────────────────────────────────────────────────────╢
"""
)[1:]
for i, theme in enumerate(self.themes):
i = f" {i}" if i < 10 else f"{i}"
row = f"{i}) [{theme.get('name')}]"
menu += f"| {row:<53} |\n"
j: str = f" {i}" if i < 10 else f"{i}"
row: str = f"{j}) [{theme.name}]"
menu += f" {row:<53} \n"
print(menu, end="")
def load_themes(self) -> List[ThemeData]:
with urllib.request.urlopen(self.THEMES_URL) as response:
themes: List[ThemeData] = []
csv_data: str = response.read().decode().splitlines()
csv_reader = csv.DictReader(csv_data, delimiter=",")
content: str = response.read().decode()
csv_data: List[str] = content.splitlines()
fieldnames = ["name", "short_note", "author", "repo"]
csv_reader = csv.DictReader(csv_data, fieldnames=fieldnames, delimiter=",")
next(csv_reader) # skip the header of the csv file
for row in csv_reader:
row: ThemeData = row
themes.append(row)
row: Dict[str, str] # type: ignore
theme: ThemeData = ThemeData(**row)
themes.append(theme)
return themes
def install_theme(self, **kwargs):
index = int(kwargs.get("opt_index"))
def install_theme(self, **kwargs: Any):
opt_index: str | None = kwargs.get("opt_index", None)
if not opt_index:
raise ValueError("No option index provided")
index: int = int(opt_index)
theme_data: ThemeData = self.themes[index]
theme_author: str = theme_data.get("author")
theme_repo: str = theme_data.get("repo")
theme_author: str = theme_data.author
theme_repo: str = theme_data.repo
theme_repo_url: str = f"https://github.com/{theme_author}/{theme_repo}"
print_instance_overview(
@@ -149,9 +160,9 @@ class MainsailThemeInstallMenu(BaseMenu):
for printer in printer_list:
git_clone_wrapper(theme_repo_url, printer.cfg_dir.joinpath(".theme"))
if len(theme_data.get("short_note", "")) > 1:
if len(theme_data.short_note) > 1:
Logger.print_warn("Info from the creator:", prefix=False, start="\n")
Logger.print_info(theme_data.get("short_note"), prefix=False, end="\n\n")
Logger.print_info(theme_data.short_note, prefix=False, end="\n\n")
def get_printer_selection(