Compare commits

..

1 Commits

Author SHA1 Message Date
dw-0
d6d5109dea Merge ad56b51e70 into 099d47df2f 2024-01-29 20:50:45 +01:00
52 changed files with 170 additions and 596 deletions

View File

@@ -1,32 +0,0 @@
#!/usr/bin/env python3
# ======================================================================= #
# Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# #
# 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 abc import abstractmethod, ABC
from typing import Dict
# noinspection PyUnusedLocal
# noinspection PyMethodMayBeStatic
class BaseExtension(ABC):
def __init__(self, metadata: Dict[str, str]):
self.metadata = metadata
@abstractmethod
def install_extension(self, **kwargs) -> None:
raise NotImplementedError(
"Subclasses must implement the install_extension method"
)
@abstractmethod
def remove_extension(self, **kwargs) -> None:
raise NotImplementedError(
"Subclasses must implement the remove_extension method"
)

View File

@@ -13,7 +13,7 @@ import subprocess
import sys
import textwrap
from abc import abstractmethod, ABC
from typing import Dict, Any, Literal, Union, Callable, Type
from typing import Dict, Any, Literal
from kiauh.core.menus import QUIT_FOOTER, BACK_FOOTER, BACK_HELP_FOOTER
from kiauh.utils.constants import (
@@ -97,24 +97,23 @@ class BaseMenu(ABC):
def __init__(
self,
options: Dict[str, Union[Callable, Any]],
options: Dict[int, Any],
options_offset: int = 0,
header: bool = True,
footer_type: Literal[
"QUIT_FOOTER", "BACK_FOOTER", "BACK_HELP_FOOTER"
] = QUIT_FOOTER,
):
self.previous_menu = None
self.options = options
self.options_offset = options_offset
self.header = header
self.footer_type = footer_type
@abstractmethod
def print_menu(self) -> None:
def print_menu(self):
raise NotImplementedError("Subclasses must implement the print_menu method")
def print_footer(self) -> None:
def print_footer(self):
footer_type_map = {
QUIT_FOOTER: print_quit_footer,
BACK_FOOTER: print_back_footer,
@@ -123,29 +122,33 @@ class BaseMenu(ABC):
footer_function = footer_type_map.get(self.footer_type, print_quit_footer)
footer_function()
def display(self) -> None:
def display(self):
# clear()
if self.header:
print_header()
self.print_menu()
self.print_footer()
def handle_user_input(self) -> str:
def handle_user_input(self):
while True:
choice = input(f"{COLOR_CYAN}###### Perform action: {RESET_FORMAT}").lower()
option = self.options.get(choice, None)
choice = input(f"{COLOR_CYAN}###### Perform action: {RESET_FORMAT}")
has_navi_option = self.footer_type in self.NAVI_OPTIONS
user_navigated = choice in self.NAVI_OPTIONS[self.footer_type]
if has_navi_option and user_navigated:
if choice.isdigit() and 0 <= int(choice) < len(self.options):
return choice
if option is not None:
elif choice.isalpha() and (
self.footer_type in self.NAVI_OPTIONS
and choice.lower() in self.NAVI_OPTIONS[self.footer_type]
):
return choice
else:
Logger.print_error("Invalid input!", False)
error_msg = (
"Invalid input!"
if choice.isalpha() or (not self.options and len(self.options) < 1)
else f"Invalid input! Select a number between {min(self.options)} and {max(self.options)}."
)
Logger.print_error(error_msg, False)
def start(self) -> None:
def start(self):
while True:
self.display()
choice = self.handle_user_input()
@@ -155,18 +158,16 @@ class BaseMenu(ABC):
sys.exit(0)
elif choice == "b":
return
elif choice == "h":
elif choice == "p":
print("help!")
else:
self.execute_option(choice)
self.execute_option(int(choice))
def execute_option(self, choice: str) -> None:
def execute_option(self, choice):
option = self.options.get(choice, None)
if isinstance(option, type) and issubclass(option, BaseMenu):
self.navigate_to_menu(option, True)
elif isinstance(option, BaseMenu):
self.navigate_to_menu(option, False)
self.navigate_to_submenu(option)
elif callable(option):
option(opt_index=choice)
elif option is None:
@@ -176,14 +177,7 @@ class BaseMenu(ABC):
f"Type {type(option)} of option {choice} not of type BaseMenu or Method"
)
def navigate_to_menu(self, menu, instantiate: bool) -> None:
"""
Method for handling the actual menu switch. Can either take in a menu type or an already
instantiated menu class. Use instantiated menu classes only if the menu requires specific input parameters
:param menu: A menu type or menu instance
:param instantiate: Specify if the menu requires instantiation
:return: None
"""
menu = menu() if instantiate else menu
menu.previous_menu = self
menu.start()
def navigate_to_submenu(self, submenu_class):
submenu = submenu_class()
submenu.previous_menu = self
submenu.start()

View File

@@ -1,135 +0,0 @@
#!/usr/bin/env python3
# ======================================================================= #
# Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# #
# 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 #
# ======================================================================= #
import json
import textwrap
import importlib
import inspect
from pathlib import Path
from typing import List, Dict
from kiauh.core.base_extension import BaseExtension
from kiauh.core.menus import BACK_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.utils.constants import RESET_FORMAT, COLOR_CYAN, COLOR_YELLOW
# noinspection PyUnusedLocal
# noinspection PyMethodMayBeStatic
class ExtensionsMenu(BaseMenu):
def __init__(self):
self.extensions = self.discover_extensions()
super().__init__(
header=True,
options=self.get_options(),
footer_type=BACK_FOOTER,
)
def discover_extensions(self) -> List[BaseExtension]:
extensions = []
extensions_dir = Path(__file__).resolve().parents[2].joinpath("extensions")
for extension in extensions_dir.iterdir():
metadata_json = Path(extension).joinpath("metadata.json")
if not metadata_json.exists():
continue
try:
with open(metadata_json, "r") as m:
metadata = json.load(m).get("metadata")
module_name = (
f"kiauh.extensions.{extension.name}.{metadata.get('module')}"
)
name, extension = inspect.getmembers(
importlib.import_module(module_name),
predicate=lambda o: inspect.isclass(o)
and issubclass(o, BaseExtension)
and o != BaseExtension,
)[0]
extensions.append(extension(metadata))
except (IOError, json.JSONDecodeError, ImportError) as e:
print(f"Failed loading extension {extension}: {e}")
return sorted(extensions, key=lambda ex: ex.metadata.get("index"))
def get_options(self) -> Dict[str, BaseMenu]:
options = {}
for extension in self.extensions:
index = extension.metadata.get("index")
options[f"{index}"] = ExtensionSubmenu(extension)
return options
def print_menu(self):
header = " [ Extensions Menu ] "
color = COLOR_CYAN
line1 = f"{COLOR_YELLOW}Available Extensions:{RESET_FORMAT}"
count = 62 - len(color) - len(RESET_FORMAT)
menu = textwrap.dedent(
f"""
/=======================================================\\
| {color}{header:~^{count}}{RESET_FORMAT} |
|-------------------------------------------------------|
| {line1:<62} |
| |
"""
)[1:]
print(menu, end="")
for extension in self.extensions:
index = extension.metadata.get("index")
name = extension.metadata.get("display_name")
row = f"{index}) {name}"
print(f"| {row:<53} |")
# noinspection PyUnusedLocal
# noinspection PyMethodMayBeStatic
class ExtensionSubmenu(BaseMenu):
def __init__(self, extension: BaseExtension):
self.extension = extension
self.extension_name = extension.metadata.get("display_name")
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:
header = f" [ {self.extension_name} ] "
color = COLOR_YELLOW
count = 62 - len(color) - len(RESET_FORMAT)
wrapper = textwrap.TextWrapper(55, initial_indent="| ", subsequent_indent="| ")
lines = wrapper.wrap(self.extension_desc)
formatted_lines = [f"{line:<55} |" for line in lines]
description_text = "\n".join(formatted_lines)
menu = textwrap.dedent(
f"""
/=======================================================\\
| {color}{header:~^{count}}{RESET_FORMAT} |
|-------------------------------------------------------|
"""
)[1:]
menu += f"{description_text}\n"
menu += textwrap.dedent(
"""
|-------------------------------------------------------|
| 1) Install |
| 2) Remove |
"""
)[1:]
print(menu, end="")

View File

@@ -13,9 +13,9 @@ import textwrap
from kiauh.core.menus import BACK_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.components.klipper import klipper_setup
from kiauh.components.mainsail import mainsail_setup
from kiauh.components.moonraker import moonraker_setup
from kiauh.modules.klipper import klipper_setup
from kiauh.modules.mainsail import mainsail_setup
from kiauh.modules.moonraker import moonraker_setup
from kiauh.utils.constants import COLOR_GREEN, RESET_FORMAT
@@ -26,17 +26,17 @@ class InstallMenu(BaseMenu):
super().__init__(
header=True,
options={
"1": self.install_klipper,
"2": self.install_moonraker,
"3": self.install_mainsail,
"4": self.install_fluidd,
"5": self.install_klipperscreen,
"6": self.install_pretty_gcode,
"7": self.install_telegram_bot,
"8": self.install_obico,
"9": self.install_octoeverywhere,
"10": self.install_mobileraker,
"11": self.install_crowsnest,
1: self.install_klipper,
2: self.install_moonraker,
3: self.install_mainsail,
4: self.install_fluidd,
5: self.install_klipperscreen,
6: self.install_pretty_gcode,
7: self.install_telegram_bot,
8: self.install_obico,
9: self.install_octoeverywhere,
10: self.install_mobileraker,
11: self.install_crowsnest,
},
footer_type=BACK_FOOTER,
)

View File

@@ -14,15 +14,14 @@ import textwrap
from kiauh.core.menus import QUIT_FOOTER
from kiauh.core.menus.advanced_menu import AdvancedMenu
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.core.menus.extensions_menu import ExtensionsMenu
from kiauh.core.menus.install_menu import InstallMenu
from kiauh.core.menus.remove_menu import RemoveMenu
from kiauh.core.menus.settings_menu import SettingsMenu
from kiauh.core.menus.update_menu import UpdateMenu
from kiauh.components.klipper.klipper_utils import get_klipper_status
from kiauh.components.log_uploads.menus.log_upload_menu import LogUploadMenu
from kiauh.components.mainsail.mainsail_utils import get_mainsail_status
from kiauh.components.moonraker.moonraker_utils import get_moonraker_status
from kiauh.modules.klipper.klipper_utils import get_klipper_status
from kiauh.modules.log_uploads.menus.log_upload_menu import LogUploadMenu
from kiauh.modules.mainsail.mainsail_utils import get_mainsail_status
from kiauh.modules.moonraker.moonraker_utils import get_moonraker_status
from kiauh.utils.constants import (
COLOR_MAGENTA,
COLOR_CYAN,
@@ -38,14 +37,13 @@ class MainMenu(BaseMenu):
super().__init__(
header=True,
options={
"0": LogUploadMenu,
"1": InstallMenu,
"2": UpdateMenu,
"3": RemoveMenu,
"4": AdvancedMenu,
"5": None,
"e": ExtensionsMenu,
"s": SettingsMenu,
0: LogUploadMenu,
1: InstallMenu,
2: UpdateMenu,
3: RemoveMenu,
4: AdvancedMenu,
5: None,
6: SettingsMenu,
},
footer_type=QUIT_FOOTER,
)
@@ -115,13 +113,13 @@ class MainMenu(BaseMenu):
| 4) [Advanced] |------------------------------------|
| 5) [Backup] | Mainsail: {self.ms_status:<26} |
| | Fluidd: {self.fl_status:<26} |
| E) [Extensions] | KlipperScreen: {self.ks_status:<26} |
| 6) [Settings] | KlipperScreen: {self.ks_status:<26} |
| | Mobileraker: {self.mb_status:<26} |
| | |
| | Crowsnest: {self.cn_status:<26} |
| | Telegram Bot: {self.tg_status:<26} |
| | Obico: {self.ob_status:<26} |
| S) [Settings] | OctoEverywhere: {self.oe_status:<26} |
| | OctoEverywhere: {self.oe_status:<26} |
|-------------------------------------------------------|
| {COLOR_CYAN}{footer1:^16}{RESET_FORMAT} | {footer2:^43} |
"""

View File

@@ -13,9 +13,9 @@ import textwrap
from kiauh.core.menus import BACK_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.components.klipper.menus.klipper_remove_menu import KlipperRemoveMenu
from kiauh.components.mainsail.menus.mainsail_remove_menu import MainsailRemoveMenu
from kiauh.components.moonraker.menus.moonraker_remove_menu import MoonrakerRemoveMenu
from kiauh.modules.klipper.menus.klipper_remove_menu import KlipperRemoveMenu
from kiauh.modules.mainsail.menus.mainsail_remove_menu import MainsailRemoveMenu
from kiauh.modules.moonraker.menus.moonraker_remove_menu import MoonrakerRemoveMenu
from kiauh.utils.constants import COLOR_RED, RESET_FORMAT
@@ -26,19 +26,19 @@ class RemoveMenu(BaseMenu):
super().__init__(
header=True,
options={
"1": KlipperRemoveMenu,
"2": MoonrakerRemoveMenu,
"3": MainsailRemoveMenu,
"5": self.remove_fluidd,
"6": self.remove_klipperscreen,
"7": self.remove_crowsnest,
"8": self.remove_mjpgstreamer,
"9": self.remove_pretty_gcode,
"10": self.remove_telegram_bot,
"11": self.remove_obico,
"12": self.remove_octoeverywhere,
"13": self.remove_mobileraker,
"14": self.remove_nginx,
1: KlipperRemoveMenu,
2: MoonrakerRemoveMenu,
3: MainsailRemoveMenu,
5: self.remove_fluidd,
6: self.remove_klipperscreen,
7: self.remove_crowsnest,
8: self.remove_mjpgstreamer,
9: self.remove_pretty_gcode,
10: self.remove_telegram_bot,
11: self.remove_obico,
12: self.remove_octoeverywhere,
13: self.remove_mobileraker,
14: self.remove_nginx,
},
footer_type=BACK_FOOTER,
)

View File

@@ -13,17 +13,17 @@ import textwrap
from kiauh.core.menus import BACK_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.components.klipper.klipper_setup import update_klipper
from kiauh.components.klipper.klipper_utils import (
from kiauh.modules.klipper.klipper_setup import update_klipper
from kiauh.modules.klipper.klipper_utils import (
get_klipper_status,
)
from kiauh.components.mainsail.mainsail_setup import update_mainsail
from kiauh.components.mainsail.mainsail_utils import (
from kiauh.modules.mainsail.mainsail_setup import update_mainsail
from kiauh.modules.mainsail.mainsail_utils import (
get_mainsail_local_version,
get_mainsail_remote_version,
)
from kiauh.components.moonraker.moonraker_setup import update_moonraker
from kiauh.components.moonraker.moonraker_utils import get_moonraker_status
from kiauh.modules.moonraker.moonraker_setup import update_moonraker
from kiauh.modules.moonraker.moonraker_utils import get_moonraker_status
from kiauh.utils.constants import COLOR_GREEN, RESET_FORMAT, COLOR_YELLOW, COLOR_WHITE
@@ -34,19 +34,19 @@ class UpdateMenu(BaseMenu):
super().__init__(
header=True,
options={
"0": self.update_all,
"1": self.update_klipper,
"2": self.update_moonraker,
"3": self.update_mainsail,
"4": self.update_fluidd,
"5": self.update_klipperscreen,
"6": self.update_pgc_for_klipper,
"7": self.update_telegram_bot,
"8": self.update_moonraker_obico,
"9": self.update_octoeverywhere,
"10": self.update_mobileraker,
"11": self.update_crowsnest,
"12": self.upgrade_system_packages,
0: self.update_all,
1: self.update_klipper,
2: self.update_moonraker,
3: self.update_mainsail,
4: self.update_fluidd,
5: self.update_klipperscreen,
6: self.update_pgc_for_klipper,
7: self.update_telegram_bot,
8: self.update_moonraker_obico,
9: self.update_octoeverywhere,
10: self.update_mobileraker,
11: self.update_crowsnest,
12: self.upgrade_system_packages,
},
footer_type=BACK_FOOTER,
)

View File

@@ -1,22 +0,0 @@
#!/usr/bin/env python3
# ======================================================================= #
# Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# #
# 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 pathlib import Path
EXT_MODULE_NAME = "gcode_shell_command.py"
MODULE_PATH = Path(__file__).resolve().parent
MODULE_ASSETS = MODULE_PATH.joinpath("assets")
KLIPPER_DIR = Path.home().joinpath("klipper")
KLIPPER_EXTRAS = KLIPPER_DIR.joinpath("klippy/extras")
EXTENSION_SRC = MODULE_ASSETS.joinpath(EXT_MODULE_NAME)
EXTENSION_TARGET_PATH = KLIPPER_EXTRAS.joinpath(EXT_MODULE_NAME)
EXAMPLE_CFG_SRC = MODULE_ASSETS.joinpath("shell_command.cfg")

View File

@@ -1,87 +0,0 @@
# Run a shell command via gcode
#
# Copyright (C) 2019 Eric Callahan <arksine.code@gmail.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import os
import shlex
import subprocess
import logging
class ShellCommand:
def __init__(self, config):
self.name = config.get_name().split()[-1]
self.printer = config.get_printer()
self.gcode = self.printer.lookup_object('gcode')
cmd = config.get('command')
cmd = os.path.expanduser(cmd)
self.command = shlex.split(cmd)
self.timeout = config.getfloat('timeout', 2., above=0.)
self.verbose = config.getboolean('verbose', True)
self.proc_fd = None
self.partial_output = ""
self.gcode.register_mux_command(
"RUN_SHELL_COMMAND", "CMD", self.name,
self.cmd_RUN_SHELL_COMMAND,
desc=self.cmd_RUN_SHELL_COMMAND_help)
def _process_output(self, eventime):
if self.proc_fd is None:
return
try:
data = os.read(self.proc_fd, 4096)
except Exception:
pass
data = self.partial_output + data.decode()
if '\n' not in data:
self.partial_output = data
return
elif data[-1] != '\n':
split = data.rfind('\n') + 1
self.partial_output = data[split:]
data = data[:split]
else:
self.partial_output = ""
self.gcode.respond_info(data)
cmd_RUN_SHELL_COMMAND_help = "Run a linux shell command"
def cmd_RUN_SHELL_COMMAND(self, params):
gcode_params = params.get('PARAMS','')
gcode_params = shlex.split(gcode_params)
reactor = self.printer.get_reactor()
try:
proc = subprocess.Popen(
self.command + gcode_params, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
except Exception:
logging.exception(
"shell_command: Command {%s} failed" % (self.name))
raise self.gcode.error("Error running command {%s}" % (self.name))
if self.verbose:
self.proc_fd = proc.stdout.fileno()
self.gcode.respond_info("Running Command {%s}...:" % (self.name))
hdl = reactor.register_fd(self.proc_fd, self._process_output)
eventtime = reactor.monotonic()
endtime = eventtime + self.timeout
complete = False
while eventtime < endtime:
eventtime = reactor.pause(eventtime + .05)
if proc.poll() is not None:
complete = True
break
if not complete:
proc.terminate()
if self.verbose:
if self.partial_output:
self.gcode.respond_info(self.partial_output)
self.partial_output = ""
if complete:
msg = "Command {%s} finished\n" % (self.name)
else:
msg = "Command {%s} timed out" % (self.name)
self.gcode.respond_info(msg)
reactor.unregister_fd(hdl)
self.proc_fd = None
def load_config_prefix(config):
return ShellCommand(config)

View File

@@ -1,7 +0,0 @@
[gcode_shell_command hello_world]
command: echo hello world
timeout: 2.
verbose: True
[gcode_macro HELLO_WORLD]
gcode:
RUN_SHELL_COMMAND CMD=hello_world

View File

@@ -1,127 +0,0 @@
#!/usr/bin/env python3
# ======================================================================= #
# Copyright (C) 2020 - 2024 Dominik Willner <th33xitus@gmail.com> #
# #
# 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 #
# ======================================================================= #
import os
import shutil
from typing import List
from kiauh.components.klipper.klipper import Klipper
from kiauh.core.backup_manager.backup_manager import BackupManager
from kiauh.core.base_extension import BaseExtension
from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.extensions.gcode_shell_cmd import (
EXTENSION_TARGET_PATH,
EXTENSION_SRC,
KLIPPER_DIR,
EXAMPLE_CFG_SRC,
KLIPPER_EXTRAS,
)
from kiauh.utils.filesystem_utils import check_file_exist
from kiauh.utils.input_utils import get_confirm
from kiauh.utils.logger import Logger
# noinspection PyMethodMayBeStatic
class GcodeShellCmdExtension(BaseExtension):
def install_extension(self, **kwargs) -> None:
install_example = get_confirm("Create an example shell command?", False, False)
klipper_dir_exists = check_file_exist(KLIPPER_DIR)
if not klipper_dir_exists:
Logger.print_warn(
"No Klipper directory found! Unable to install extension."
)
return
extension_installed = check_file_exist(EXTENSION_TARGET_PATH)
overwrite = True
if extension_installed:
overwrite = get_confirm(
"Extension seems to be installed already. Overwrite?", True, False
)
if not overwrite:
Logger.print_warn("Installation aborted due to user request.")
return
im = InstanceManager(Klipper)
im.stop_all_instance()
try:
Logger.print_status(f"Copy extension to '{KLIPPER_EXTRAS}' ...")
shutil.copy(EXTENSION_SRC, EXTENSION_TARGET_PATH)
except OSError as e:
Logger.print_error(f"Unable to install extension: {e}")
return
if install_example:
self.install_example_cfg(im.instances)
im.start_all_instance()
Logger.print_ok("Installing G-Code Shell Command extension successfull!")
def remove_extension(self, **kwargs) -> None:
extension_installed = check_file_exist(EXTENSION_TARGET_PATH)
if not extension_installed:
Logger.print_info("Extension does not seem to be installed! Skipping ...")
return
question = "Do you really want to remove the extension?"
if get_confirm(question, True, False):
try:
Logger.print_status(f"Removing '{EXTENSION_TARGET_PATH}' ...")
os.remove(EXTENSION_TARGET_PATH)
Logger.print_ok("Extension successfully removed!")
except OSError as e:
Logger.print_error(f"Unable to remove extension: {e}")
Logger.print_warn("PLEASE NOTE:")
Logger.print_warn(
"Remaining gcode shell command will cause Klipper to throw an error."
)
Logger.print_warn("Make sure to remove them from the printer.cfg!")
def install_example_cfg(self, instances: List[Klipper]):
cfg_dirs = [instance.cfg_dir for instance in instances]
# copy extension to klippy/extras
for cfg_dir in cfg_dirs:
Logger.print_status(f"Create shell_command.cfg in '{cfg_dir}' ...")
if check_file_exist(cfg_dir.joinpath("shell_command.cfg")):
Logger.print_info("File already exists! Skipping ...")
continue
try:
shutil.copy(EXAMPLE_CFG_SRC, cfg_dir)
Logger.print_ok("Done!")
except OSError as e:
Logger.warn(f"Unable to create example config: {e}")
# backup each printer.cfg before modification
bm = BackupManager()
for instance in instances:
bm.backup_file(
[instance.cfg_file],
custom_filename=f"{instance.suffix}.printer.cfg",
)
# add section to printer.cfg if not already defined
section = "include shell_command.cfg"
cfg_files = [instance.cfg_file for instance in instances]
for cfg_file in cfg_files:
Logger.print_status(f"Include shell_command.cfg in '{cfg_file}' ...")
cm = ConfigManager(cfg_file)
if cm.config.has_section(section):
Logger.print_info("Section already defined! Skipping ...")
continue
cm.config.add_section(section)
cm.write_config()
Logger.print_ok("Done!")

View File

@@ -1,9 +0,0 @@
{
"metadata": {
"index": 1,
"module": "gcode_shell_cmd_extension",
"maintained_by": "dw-0",
"display_name": "G-Code Shell Command",
"description": "Allows to run a shell command from gcode."
}
}

View File

@@ -14,7 +14,7 @@ from pathlib import Path
from typing import List
from kiauh.core.instance_manager.base_instance import BaseInstance
from kiauh.components.klipper import KLIPPER_DIR, KLIPPER_ENV_DIR, MODULE_PATH
from kiauh.modules.klipper import KLIPPER_DIR, KLIPPER_ENV_DIR, MODULE_PATH
from kiauh.utils.constants import SYSTEMD
from kiauh.utils.logger import Logger
@@ -52,10 +52,10 @@ class Klipper(BaseInstance):
def create(self) -> None:
Logger.print_status("Creating new Klipper Instance ...")
service_template_path = MODULE_PATH.joinpath("assets/klipper.service")
service_template_path = MODULE_PATH.joinpath("res/klipper.service")
service_file_name = self.get_service_file_name(extension=True)
service_file_target = SYSTEMD.joinpath(service_file_name)
env_template_file_path = MODULE_PATH.joinpath("assets/klipper.env")
env_template_file_path = MODULE_PATH.joinpath("res/klipper.env")
env_file_target = self.sysd_dir.joinpath("klipper.env")
try:

View File

@@ -13,9 +13,9 @@ import shutil
from typing import List, Union
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.components.klipper import KLIPPER_DIR, KLIPPER_ENV_DIR
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.klipper.klipper_dialogs import print_instance_overview
from kiauh.modules.klipper import KLIPPER_DIR, KLIPPER_ENV_DIR
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.klipper.klipper_dialogs import print_instance_overview
from kiauh.utils.filesystem_utils import remove_file
from kiauh.utils.input_utils import get_selection_input
from kiauh.utils.logger import Logger

View File

@@ -15,16 +15,16 @@ from kiauh import KIAUH_CFG
from kiauh.core.backup_manager.backup_manager import BackupManager
from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.components.klipper import (
from kiauh.modules.klipper import (
EXIT_KLIPPER_SETUP,
DEFAULT_KLIPPER_REPO_URL,
KLIPPER_DIR,
KLIPPER_ENV_DIR,
KLIPPER_REQUIREMENTS_TXT,
)
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.klipper.klipper_dialogs import print_update_warn_dialog
from kiauh.components.klipper.klipper_utils import (
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.klipper.klipper_dialogs import print_update_warn_dialog
from kiauh.modules.klipper.klipper_utils import (
handle_disruptive_system_packages,
check_user_groups,
handle_to_multi_instance_conversion,
@@ -37,7 +37,7 @@ from kiauh.components.klipper.klipper_utils import (
handle_instance_naming,
)
from kiauh.core.repo_manager.repo_manager import RepoManager
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.utils.input_utils import get_confirm
from kiauh.utils.logger import Logger
from kiauh.utils.system_utils import (

View File

@@ -24,16 +24,16 @@ from kiauh.core.instance_manager.base_instance import BaseInstance
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.core.instance_manager.name_scheme import NameScheme
from kiauh.core.repo_manager.repo_manager import RepoManager
from kiauh.components.klipper import MODULE_PATH, KLIPPER_DIR, KLIPPER_ENV_DIR
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.klipper.klipper_dialogs import (
from kiauh.modules.klipper import MODULE_PATH, KLIPPER_DIR, KLIPPER_ENV_DIR
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.klipper.klipper_dialogs import (
print_missing_usergroup_dialog,
print_instance_overview,
print_select_instance_count_dialog,
print_select_custom_name_dialog,
)
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.components.moonraker.moonraker_utils import moonraker_to_multi_conversion
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.modules.moonraker.moonraker_utils import moonraker_to_multi_conversion
from kiauh.utils.common import get_install_status_common
from kiauh.utils.constants import CURRENT_USER
from kiauh.utils.input_utils import get_confirm, get_string_input, get_number_input
@@ -264,7 +264,7 @@ def create_example_printer_cfg(instance: Klipper) -> None:
Logger.print_info(f"'{instance.cfg_file}' already exists.")
return
source = MODULE_PATH.joinpath("assets/printer.cfg")
source = MODULE_PATH.joinpath("res/printer.cfg")
target = instance.cfg_file
try:
shutil.copy(source, target)

View File

@@ -13,7 +13,8 @@ import textwrap
from kiauh.core.menus import BACK_HELP_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.components.klipper import klipper_remove
from kiauh.modules.klipper import klipper_remove
from kiauh.modules.moonraker import moonraker_remove
from kiauh.utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
@@ -23,12 +24,12 @@ class KlipperRemoveMenu(BaseMenu):
super().__init__(
header=False,
options={
"0": self.toggle_all,
"1": self.toggle_remove_klipper_service,
"2": self.toggle_remove_klipper_dir,
"3": self.toggle_remove_klipper_env,
"4": self.toggle_delete_klipper_logs,
"5": self.run_removal_process,
0: self.toggle_all,
1: self.toggle_remove_klipper_service,
2: self.toggle_remove_klipper_dir,
3: self.toggle_remove_klipper_env,
4: self.toggle_delete_klipper_logs,
5: self.run_removal_process,
},
footer_type=BACK_HELP_FOOTER,
)

View File

@@ -15,8 +15,8 @@ from pathlib import Path
import urllib.request
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.log_uploads import LogFile
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.log_uploads import LogFile
from kiauh.utils.logger import Logger

View File

@@ -13,8 +13,8 @@ import textwrap
from kiauh.core.menus import BACK_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.components.log_uploads.log_upload_utils import upload_logfile
from kiauh.components.log_uploads.log_upload_utils import get_logfile_list
from kiauh.modules.log_uploads.log_upload_utils import upload_logfile
from kiauh.modules.log_uploads.log_upload_utils import get_logfile_list
from kiauh.utils.constants import RESET_FORMAT, COLOR_YELLOW

View File

@@ -17,10 +17,10 @@ from typing import List
from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.mainsail import MAINSAIL_DIR, MAINSAIL_CONFIG_DIR
from kiauh.components.mainsail.mainsail_utils import backup_config_json
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.mainsail import MAINSAIL_DIR, MAINSAIL_CONFIG_DIR
from kiauh.modules.mainsail.mainsail_utils import backup_config_json
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.utils import NGINX_SITES_AVAILABLE, NGINX_SITES_ENABLED
from kiauh.utils.filesystem_utils import remove_file
from kiauh.utils.logger import Logger

View File

@@ -17,27 +17,27 @@ from kiauh import KIAUH_CFG
from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.core.repo_manager.repo_manager import RepoManager
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.mainsail import (
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.mainsail import (
MAINSAIL_URL,
MAINSAIL_DIR,
MAINSAIL_CONFIG_DIR,
MAINSAIL_CONFIG_REPO_URL,
MODULE_PATH,
)
from kiauh.components.mainsail.mainsail_dialogs import (
from kiauh.modules.mainsail.mainsail_dialogs import (
print_moonraker_not_found_dialog,
print_mainsail_already_installed_dialog,
print_install_mainsail_config_dialog,
print_mainsail_port_select_dialog,
)
from kiauh.components.mainsail.mainsail_utils import (
from kiauh.modules.mainsail.mainsail_utils import (
restore_config_json,
enable_mainsail_remotemode,
backup_config_json,
symlink_webui_nginx_log,
)
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.utils import NGINX_SITES_AVAILABLE, NGINX_SITES_ENABLED
from kiauh.utils.common import check_install_dependencies
from kiauh.utils.filesystem_utils import (
@@ -229,7 +229,7 @@ def patch_moonraker_conf(
Logger.print_info("Section already exist. Skipped ...")
return
template = MODULE_PATH.joinpath("assets", template_file)
template = MODULE_PATH.joinpath("res", template_file)
with open(template, "r") as t:
template_content = "\n"
template_content += t.read()

View File

@@ -16,8 +16,8 @@ from pathlib import Path
from typing import List
from kiauh.core.backup_manager.backup_manager import BackupManager
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.mainsail import MAINSAIL_CONFIG_JSON, MAINSAIL_DIR
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.mainsail import MAINSAIL_CONFIG_JSON, MAINSAIL_DIR
from kiauh.utils import NGINX_SITES_AVAILABLE, NGINX_CONFD
from kiauh.utils.common import get_install_status_webui
from kiauh.utils.logger import Logger

View File

@@ -13,7 +13,7 @@ import textwrap
from kiauh.core.menus import BACK_HELP_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.components.mainsail import mainsail_remove
from kiauh.modules.mainsail import mainsail_remove
from kiauh.utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
@@ -23,13 +23,13 @@ class MainsailRemoveMenu(BaseMenu):
super().__init__(
header=False,
options={
"0": self.toggle_all,
"1": self.toggle_remove_mainsail,
"2": self.toggle_remove_ms_config,
"3": self.toggle_backup_config_json,
"4": self.toggle_remove_updater_section,
"5": self.toggle_remove_printer_cfg_include,
"6": self.run_removal_process,
0: self.toggle_all,
1: self.toggle_remove_mainsail,
2: self.toggle_remove_ms_config,
3: self.toggle_backup_config_json,
4: self.toggle_remove_updater_section,
5: self.toggle_remove_printer_cfg_include,
6: self.run_removal_process,
},
footer_type=BACK_HELP_FOOTER,
)

View File

@@ -13,7 +13,7 @@ import textwrap
from kiauh.core.menus import BACK_HELP_FOOTER
from kiauh.core.menus.base_menu import BaseMenu
from kiauh.components.moonraker import moonraker_remove
from kiauh.modules.moonraker import moonraker_remove
from kiauh.utils.constants import RESET_FORMAT, COLOR_RED, COLOR_CYAN
@@ -23,13 +23,13 @@ class MoonrakerRemoveMenu(BaseMenu):
super().__init__(
header=False,
options={
"0": self.toggle_all,
"1": self.toggle_remove_moonraker_service,
"2": self.toggle_remove_moonraker_dir,
"3": self.toggle_remove_moonraker_env,
"4": self.toggle_remove_moonraker_polkit,
"5": self.toggle_delete_moonraker_logs,
"6": self.run_removal_process,
0: self.toggle_all,
1: self.toggle_remove_moonraker_service,
2: self.toggle_remove_moonraker_dir,
3: self.toggle_remove_moonraker_env,
4: self.toggle_remove_moonraker_polkit,
5: self.toggle_delete_moonraker_logs,
6: self.run_removal_process,
},
footer_type=BACK_HELP_FOOTER,
)

View File

@@ -15,7 +15,7 @@ from typing import List, Union
from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.base_instance import BaseInstance
from kiauh.components.moonraker import MOONRAKER_DIR, MOONRAKER_ENV_DIR, MODULE_PATH
from kiauh.modules.moonraker import MOONRAKER_DIR, MOONRAKER_ENV_DIR, MODULE_PATH
from kiauh.utils.constants import SYSTEMD
from kiauh.utils.logger import Logger
@@ -39,8 +39,8 @@ class Moonraker(BaseInstance):
def create(self, create_example_cfg: bool = False) -> None:
Logger.print_status("Creating new Moonraker Instance ...")
service_template_path = MODULE_PATH.joinpath("assets/moonraker.service")
env_template_file_path = MODULE_PATH.joinpath("assets/moonraker.env")
service_template_path = MODULE_PATH.joinpath("res/moonraker.service")
env_template_file_path = MODULE_PATH.joinpath("res/moonraker.env")
service_file_name = self.get_service_file_name(extension=True)
service_file_target = SYSTEMD.joinpath(service_file_name)
env_file_target = self.sysd_dir.joinpath("moonraker.env")

View File

@@ -13,8 +13,8 @@ import textwrap
from typing import List
from kiauh.core.menus.base_menu import print_back_footer
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.utils.constants import COLOR_GREEN, RESET_FORMAT, COLOR_YELLOW, COLOR_CYAN

View File

@@ -14,9 +14,9 @@ import subprocess
from typing import List, Union
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.components.klipper.klipper_dialogs import print_instance_overview
from kiauh.components.moonraker import MOONRAKER_DIR, MOONRAKER_ENV_DIR
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.modules.klipper.klipper_dialogs import print_instance_overview
from kiauh.modules.moonraker import MOONRAKER_DIR, MOONRAKER_ENV_DIR
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.utils.filesystem_utils import remove_file
from kiauh.utils.input_utils import get_selection_input
from kiauh.utils.logger import Logger

View File

@@ -18,12 +18,12 @@ from kiauh import KIAUH_CFG
from kiauh.core.backup_manager.backup_manager import BackupManager
from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.components.klipper.klipper import Klipper
from kiauh.components.klipper.klipper_dialogs import print_instance_overview
from kiauh.modules.klipper.klipper import Klipper
from kiauh.modules.klipper.klipper_dialogs import print_instance_overview
from kiauh.core.repo_manager.repo_manager import RepoManager
from kiauh.components.mainsail import MAINSAIL_DIR
from kiauh.components.mainsail.mainsail_utils import enable_mainsail_remotemode
from kiauh.components.moonraker import (
from kiauh.modules.mainsail import MAINSAIL_DIR
from kiauh.modules.mainsail.mainsail_utils import enable_mainsail_remotemode
from kiauh.modules.moonraker import (
EXIT_MOONRAKER_SETUP,
DEFAULT_MOONRAKER_REPO_URL,
MOONRAKER_DIR,
@@ -34,9 +34,9 @@ from kiauh.components.moonraker import (
POLKIT_USR_FILE,
POLKIT_SCRIPT,
)
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.components.moonraker.moonraker_dialogs import print_moonraker_overview
from kiauh.components.moonraker.moonraker_utils import create_example_moonraker_conf
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.modules.moonraker.moonraker_dialogs import print_moonraker_overview
from kiauh.modules.moonraker.moonraker_utils import create_example_moonraker_conf
from kiauh.utils.filesystem_utils import check_file_exist
from kiauh.utils.input_utils import (
get_confirm,

View File

@@ -15,15 +15,15 @@ from typing import Dict, Literal, List, Union
from kiauh.core.config_manager.config_manager import ConfigManager
from kiauh.core.instance_manager.instance_manager import InstanceManager
from kiauh.core.repo_manager.repo_manager import RepoManager
from kiauh.components.mainsail import MAINSAIL_DIR
from kiauh.components.mainsail.mainsail_utils import enable_mainsail_remotemode
from kiauh.components.moonraker import (
from kiauh.modules.mainsail import MAINSAIL_DIR
from kiauh.modules.mainsail.mainsail_utils import enable_mainsail_remotemode
from kiauh.modules.moonraker import (
DEFAULT_MOONRAKER_PORT,
MODULE_PATH,
MOONRAKER_DIR,
MOONRAKER_ENV_DIR,
)
from kiauh.components.moonraker.moonraker import Moonraker
from kiauh.modules.moonraker.moonraker import Moonraker
from kiauh.utils.common import get_install_status_common
from kiauh.utils.logger import Logger
from kiauh.utils.system_utils import (
@@ -56,7 +56,7 @@ def create_example_moonraker_conf(
Logger.print_info(f"'{instance.cfg_file}' already exists.")
return
source = MODULE_PATH.joinpath("assets/moonraker.conf")
source = MODULE_PATH.joinpath("res/moonraker.conf")
target = instance.cfg_file
try:
shutil.copy(source, target)

View File

@@ -79,7 +79,7 @@ def copy_upstream_nginx_cfg() -> None:
Creates an upstream.conf in /etc/nginx/conf.d
:return: None
"""
source = MODULE_PATH.joinpath("assets/upstreams.conf")
source = MODULE_PATH.joinpath("res/upstreams.conf")
target = NGINX_CONFD.joinpath("upstreams.conf")
try:
command = ["sudo", "cp", source, target]
@@ -95,7 +95,7 @@ def copy_common_vars_nginx_cfg() -> None:
Creates a common_vars.conf in /etc/nginx/conf.d
:return: None
"""
source = MODULE_PATH.joinpath("assets/common_vars.conf")
source = MODULE_PATH.joinpath("res/common_vars.conf")
target = NGINX_CONFD.joinpath("common_vars.conf")
try:
command = ["sudo", "cp", source, target]
@@ -115,7 +115,7 @@ def create_nginx_cfg(name: str, port: int, root_dir: Path) -> None:
:return: None
"""
tmp = Path.home().joinpath(f"{name}.tmp")
shutil.copy(MODULE_PATH.joinpath("assets/nginx_cfg"), tmp)
shutil.copy(MODULE_PATH.joinpath("res/nginx_cfg"), tmp)
with open(tmp, "r+") as f:
content = f.read()
content = content.replace("%NAME%", name)