@@ -48,10 +48,12 @@ from utils.logger import Logger
|
|||||||
from utils.system_utils import mask_system_service
|
from utils.system_utils import mask_system_service
|
||||||
|
|
||||||
|
|
||||||
def get_klipper_status() -> Dict[
|
def get_klipper_status() -> (
|
||||||
|
Dict[
|
||||||
Literal["status", "status_code", "instances", "repo", "local", "remote"],
|
Literal["status", "status_code", "instances", "repo", "local", "remote"],
|
||||||
Union[str, int],
|
Union[str, int],
|
||||||
]:
|
]
|
||||||
|
):
|
||||||
status = get_install_status_common(Klipper, KLIPPER_DIR, KLIPPER_ENV_DIR)
|
status = get_install_status_common(Klipper, KLIPPER_DIR, KLIPPER_ENV_DIR)
|
||||||
return {
|
return {
|
||||||
"status": status.get("status"),
|
"status": status.get("status"),
|
||||||
@@ -69,7 +71,9 @@ def check_is_multi_install(
|
|||||||
return not existing_instances and install_count > 1
|
return not existing_instances and install_count > 1
|
||||||
|
|
||||||
|
|
||||||
def check_is_single_to_multi_conversion(existing_instances: List[Klipper]) -> bool:
|
def check_is_single_to_multi_conversion(
|
||||||
|
existing_instances: List[Klipper],
|
||||||
|
) -> bool:
|
||||||
return len(existing_instances) == 1 and existing_instances[0].suffix == ""
|
return len(existing_instances) == 1 and existing_instances[0].suffix == ""
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -130,9 +130,15 @@ def remove_polkit_rules() -> None:
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
command = [f"{MOONRAKER_DIR}/scripts/set-policykit-rules.sh", "--clear"]
|
command = [
|
||||||
|
f"{MOONRAKER_DIR}/scripts/set-policykit-rules.sh",
|
||||||
|
"--clear",
|
||||||
|
]
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
command, stderr=subprocess.PIPE, stdout=subprocess.DEVNULL, check=True
|
command,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
check=True,
|
||||||
)
|
)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
Logger.print_error(f"Error while removing policykit rules: {e}")
|
Logger.print_error(f"Error while removing policykit rules: {e}")
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ import sys
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from components.webui_client import MAINSAIL_DIR
|
from components.webui_client import MAINSAIL_DIR
|
||||||
from components.webui_client.client_utils import enable_mainsail_remotemode, get_existing_clients
|
from components.webui_client.client_utils import (
|
||||||
|
enable_mainsail_remotemode,
|
||||||
|
get_existing_clients,
|
||||||
|
)
|
||||||
from kiauh import KIAUH_CFG
|
from kiauh import KIAUH_CFG
|
||||||
from components.klipper.klipper import Klipper
|
from components.klipper.klipper import Klipper
|
||||||
from components.moonraker import (
|
from components.moonraker import (
|
||||||
@@ -170,7 +173,10 @@ def install_moonraker_polkit() -> None:
|
|||||||
try:
|
try:
|
||||||
command = [POLKIT_SCRIPT, "--disable-systemctl"]
|
command = [POLKIT_SCRIPT, "--disable-systemctl"]
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
command, stderr=subprocess.PIPE, stdout=subprocess.DEVNULL, text=True
|
command,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
text=True,
|
||||||
)
|
)
|
||||||
if result.returncode != 0 or result.stderr:
|
if result.returncode != 0 or result.stderr:
|
||||||
Logger.print_error(f"{result.stderr}", False)
|
Logger.print_error(f"{result.stderr}", False)
|
||||||
|
|||||||
@@ -32,10 +32,12 @@ from utils.system_utils import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_moonraker_status() -> Dict[
|
def get_moonraker_status() -> (
|
||||||
|
Dict[
|
||||||
Literal["status", "status_code", "instances", "repo", "local", "remote"],
|
Literal["status", "status_code", "instances", "repo", "local", "remote"],
|
||||||
Union[str, int],
|
Union[str, int],
|
||||||
]:
|
]
|
||||||
|
):
|
||||||
status = get_install_status_common(Moonraker, MOONRAKER_DIR, MOONRAKER_ENV_DIR)
|
status = get_install_status_common(Moonraker, MOONRAKER_DIR, MOONRAKER_ENV_DIR)
|
||||||
return {
|
return {
|
||||||
"status": status.get("status"),
|
"status": status.get("status"),
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ from kiauh import KIAUH_CFG
|
|||||||
from components.klipper.klipper import Klipper
|
from components.klipper.klipper import Klipper
|
||||||
from components.moonraker.moonraker import Moonraker
|
from components.moonraker.moonraker import Moonraker
|
||||||
from components.webui_client import ClientConfigData, ClientName, ClientData
|
from components.webui_client import ClientConfigData, ClientName, ClientData
|
||||||
from components.webui_client.client_dialogs import print_client_already_installed_dialog
|
from components.webui_client.client_dialogs import (
|
||||||
|
print_client_already_installed_dialog,
|
||||||
|
)
|
||||||
from components.webui_client.client_utils import (
|
from components.webui_client.client_utils import (
|
||||||
load_client_data,
|
load_client_data,
|
||||||
backup_client_config_data,
|
backup_client_config_data,
|
||||||
@@ -29,8 +31,9 @@ from core.repo_manager.repo_manager import RepoManager
|
|||||||
from utils.common import backup_printer_config_dir
|
from utils.common import backup_printer_config_dir
|
||||||
from utils.filesystem_utils import (
|
from utils.filesystem_utils import (
|
||||||
create_symlink,
|
create_symlink,
|
||||||
add_config_section, add_config_section_at_top,
|
add_config_section,
|
||||||
)
|
add_config_section_at_top,
|
||||||
|
)
|
||||||
from utils.input_utils import get_confirm
|
from utils.input_utils import get_confirm
|
||||||
from utils.logger import Logger
|
from utils.logger import Logger
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,9 @@ def get_client_status(client: ClientData) -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_client_config_status(client: ClientData) -> Dict[
|
def get_client_config_status(
|
||||||
|
client: ClientData,
|
||||||
|
) -> Dict[
|
||||||
Literal["repo", "local", "remote"],
|
Literal["repo", "local", "remote"],
|
||||||
Union[str, int],
|
Union[str, int],
|
||||||
]:
|
]:
|
||||||
|
|||||||
@@ -108,7 +108,12 @@ class InstanceManager:
|
|||||||
def enable_instance(self) -> None:
|
def enable_instance(self) -> None:
|
||||||
Logger.print_status(f"Enabling {self.instance_service_full} ...")
|
Logger.print_status(f"Enabling {self.instance_service_full} ...")
|
||||||
try:
|
try:
|
||||||
command = ["sudo", "systemctl", "enable", self.instance_service_full]
|
command = [
|
||||||
|
"sudo",
|
||||||
|
"systemctl",
|
||||||
|
"enable",
|
||||||
|
self.instance_service_full,
|
||||||
|
]
|
||||||
if subprocess.run(command, check=True):
|
if subprocess.run(command, check=True):
|
||||||
Logger.print_ok(f"{self.instance_service_full} enabled.")
|
Logger.print_ok(f"{self.instance_service_full} enabled.")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
@@ -118,7 +123,12 @@ class InstanceManager:
|
|||||||
def disable_instance(self) -> None:
|
def disable_instance(self) -> None:
|
||||||
Logger.print_status(f"Disabling {self.instance_service_full} ...")
|
Logger.print_status(f"Disabling {self.instance_service_full} ...")
|
||||||
try:
|
try:
|
||||||
command = ["sudo", "systemctl", "disable", self.instance_service_full]
|
command = [
|
||||||
|
"sudo",
|
||||||
|
"systemctl",
|
||||||
|
"disable",
|
||||||
|
self.instance_service_full,
|
||||||
|
]
|
||||||
if subprocess.run(command, check=True):
|
if subprocess.run(command, check=True):
|
||||||
Logger.print_ok(f"{self.instance_service_full} disabled.")
|
Logger.print_ok(f"{self.instance_service_full} disabled.")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
@@ -128,7 +138,12 @@ class InstanceManager:
|
|||||||
def start_instance(self) -> None:
|
def start_instance(self) -> None:
|
||||||
Logger.print_status(f"Starting {self.instance_service_full} ...")
|
Logger.print_status(f"Starting {self.instance_service_full} ...")
|
||||||
try:
|
try:
|
||||||
command = ["sudo", "systemctl", "start", self.instance_service_full]
|
command = [
|
||||||
|
"sudo",
|
||||||
|
"systemctl",
|
||||||
|
"start",
|
||||||
|
self.instance_service_full,
|
||||||
|
]
|
||||||
if subprocess.run(command, check=True):
|
if subprocess.run(command, check=True):
|
||||||
Logger.print_ok(f"{self.instance_service_full} started.")
|
Logger.print_ok(f"{self.instance_service_full} started.")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
@@ -138,7 +153,12 @@ class InstanceManager:
|
|||||||
def restart_instance(self) -> None:
|
def restart_instance(self) -> None:
|
||||||
Logger.print_status(f"Restarting {self.instance_service_full} ...")
|
Logger.print_status(f"Restarting {self.instance_service_full} ...")
|
||||||
try:
|
try:
|
||||||
command = ["sudo", "systemctl", "restart", self.instance_service_full]
|
command = [
|
||||||
|
"sudo",
|
||||||
|
"systemctl",
|
||||||
|
"restart",
|
||||||
|
self.instance_service_full,
|
||||||
|
]
|
||||||
if subprocess.run(command, check=True):
|
if subprocess.run(command, check=True):
|
||||||
Logger.print_ok(f"{self.instance_service_full} restarted.")
|
Logger.print_ok(f"{self.instance_service_full} restarted.")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
|
|||||||
@@ -68,7 +68,11 @@ class MainMenu(BaseMenu):
|
|||||||
def init_status(self) -> None:
|
def init_status(self) -> None:
|
||||||
status_vars = ["kl", "mr", "ms", "fl", "ks", "mb", "cn"]
|
status_vars = ["kl", "mr", "ms", "fl", "ks", "mb", "cn"]
|
||||||
for var in status_vars:
|
for var in status_vars:
|
||||||
setattr(self, f"{var}_status", f"{COLOR_RED}Not installed!{RESET_FORMAT}")
|
setattr(
|
||||||
|
self,
|
||||||
|
f"{var}_status",
|
||||||
|
f"{COLOR_RED}Not installed!{RESET_FORMAT}",
|
||||||
|
)
|
||||||
|
|
||||||
def fetch_status(self) -> None:
|
def fetch_status(self) -> None:
|
||||||
# klipper
|
# klipper
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
from components.klipper.menus.klipper_remove_menu import KlipperRemoveMenu
|
from components.klipper.menus.klipper_remove_menu import KlipperRemoveMenu
|
||||||
from components.moonraker.menus.moonraker_remove_menu import MoonrakerRemoveMenu
|
from components.moonraker.menus.moonraker_remove_menu import (
|
||||||
|
MoonrakerRemoveMenu,
|
||||||
|
)
|
||||||
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 import BACK_FOOTER
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ class GcodeShellCmdExtension(BaseExtension):
|
|||||||
overwrite = True
|
overwrite = True
|
||||||
if extension_installed:
|
if extension_installed:
|
||||||
overwrite = get_confirm(
|
overwrite = get_confirm(
|
||||||
"Extension seems to be installed already. Overwrite?", True, False
|
"Extension seems to be installed already. Overwrite?",
|
||||||
|
True,
|
||||||
|
False,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not overwrite:
|
if not overwrite:
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ from typing import List, Union
|
|||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
from components.klipper.klipper import Klipper
|
from components.klipper.klipper import Klipper
|
||||||
from components.klipper.klipper_dialogs import print_instance_overview, DisplayType
|
from components.klipper.klipper_dialogs import (
|
||||||
|
print_instance_overview,
|
||||||
|
DisplayType,
|
||||||
|
)
|
||||||
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
|
||||||
@@ -146,7 +149,9 @@ class MainsailThemeInstallMenu(BaseMenu):
|
|||||||
Logger.print_info(theme_data.get("short_note"), prefix=False, end="\n\n")
|
Logger.print_info(theme_data.get("short_note"), prefix=False, end="\n\n")
|
||||||
|
|
||||||
|
|
||||||
def get_printer_selection(instances: List[BaseInstance], is_install: bool) -> Union[List[BaseInstance], None]:
|
def get_printer_selection(
|
||||||
|
instances: List[BaseInstance], is_install: bool
|
||||||
|
) -> Union[List[BaseInstance], None]:
|
||||||
options = [str(i) for i in range(len(instances))]
|
options = [str(i) for i in range(len(instances))]
|
||||||
options.extend(["a", "A", "b", "B"])
|
options.extend(["a", "A", "b", "B"])
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,11 @@ def get_confirm(
|
|||||||
|
|
||||||
|
|
||||||
def get_number_input(
|
def get_number_input(
|
||||||
question: str, min_count: int, max_count=None, default=None, allow_go_back=False
|
question: str,
|
||||||
|
min_count: int,
|
||||||
|
max_count=None,
|
||||||
|
default=None,
|
||||||
|
allow_go_back=False,
|
||||||
) -> Union[int, None]:
|
) -> Union[int, None]:
|
||||||
"""
|
"""
|
||||||
Helper method to get a number input from the user
|
Helper method to get a number input from the user
|
||||||
|
|||||||
@@ -130,7 +130,12 @@ def install_python_requirements(target: Path, requirements: Path) -> None:
|
|||||||
update_python_pip(target)
|
update_python_pip(target)
|
||||||
|
|
||||||
Logger.print_status("Installing Python requirements ...")
|
Logger.print_status("Installing Python requirements ...")
|
||||||
command = [target.joinpath("bin/pip"), "install", "-r", f"{requirements}"]
|
command = [
|
||||||
|
target.joinpath("bin/pip"),
|
||||||
|
"install",
|
||||||
|
"-r",
|
||||||
|
f"{requirements}",
|
||||||
|
]
|
||||||
result = subprocess.run(command, stderr=subprocess.PIPE, text=True)
|
result = subprocess.run(command, stderr=subprocess.PIPE, text=True)
|
||||||
|
|
||||||
if result.returncode != 0 or result.stderr:
|
if result.returncode != 0 or result.stderr:
|
||||||
@@ -196,7 +201,10 @@ def check_package_install(packages: List[str]) -> List[str]:
|
|||||||
for package in packages:
|
for package in packages:
|
||||||
command = ["dpkg-query", "-f'${Status}'", "--show", package]
|
command = ["dpkg-query", "-f'${Status}'", "--show", package]
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True
|
command,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
text=True,
|
||||||
)
|
)
|
||||||
if "installed" not in result.stdout.strip("'").split():
|
if "installed" not in result.stdout.strip("'").split():
|
||||||
not_installed.append(package)
|
not_installed.append(package)
|
||||||
|
|||||||
@@ -8,22 +8,26 @@ import shlex
|
|||||||
import subprocess
|
import subprocess
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class ShellCommand:
|
class ShellCommand:
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.name = config.get_name().split()[-1]
|
self.name = config.get_name().split()[-1]
|
||||||
self.printer = config.get_printer()
|
self.printer = config.get_printer()
|
||||||
self.gcode = self.printer.lookup_object('gcode')
|
self.gcode = self.printer.lookup_object("gcode")
|
||||||
cmd = config.get('command')
|
cmd = config.get("command")
|
||||||
cmd = os.path.expanduser(cmd)
|
cmd = os.path.expanduser(cmd)
|
||||||
self.command = shlex.split(cmd)
|
self.command = shlex.split(cmd)
|
||||||
self.timeout = config.getfloat('timeout', 2., above=0.)
|
self.timeout = config.getfloat("timeout", 2.0, above=0.0)
|
||||||
self.verbose = config.getboolean('verbose', True)
|
self.verbose = config.getboolean("verbose", True)
|
||||||
self.proc_fd = None
|
self.proc_fd = None
|
||||||
self.partial_output = ""
|
self.partial_output = ""
|
||||||
self.gcode.register_mux_command(
|
self.gcode.register_mux_command(
|
||||||
"RUN_SHELL_COMMAND", "CMD", self.name,
|
"RUN_SHELL_COMMAND",
|
||||||
|
"CMD",
|
||||||
|
self.name,
|
||||||
self.cmd_RUN_SHELL_COMMAND,
|
self.cmd_RUN_SHELL_COMMAND,
|
||||||
desc=self.cmd_RUN_SHELL_COMMAND_help)
|
desc=self.cmd_RUN_SHELL_COMMAND_help,
|
||||||
|
)
|
||||||
|
|
||||||
def _process_output(self, eventime):
|
def _process_output(self, eventime):
|
||||||
if self.proc_fd is None:
|
if self.proc_fd is None:
|
||||||
@@ -33,11 +37,11 @@ class ShellCommand:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
data = self.partial_output + data.decode()
|
data = self.partial_output + data.decode()
|
||||||
if '\n' not in data:
|
if "\n" not in data:
|
||||||
self.partial_output = data
|
self.partial_output = data
|
||||||
return
|
return
|
||||||
elif data[-1] != '\n':
|
elif data[-1] != "\n":
|
||||||
split = data.rfind('\n') + 1
|
split = data.rfind("\n") + 1
|
||||||
self.partial_output = data[split:]
|
self.partial_output = data[split:]
|
||||||
data = data[:split]
|
data = data[:split]
|
||||||
else:
|
else:
|
||||||
@@ -45,16 +49,19 @@ class ShellCommand:
|
|||||||
self.gcode.respond_info(data)
|
self.gcode.respond_info(data)
|
||||||
|
|
||||||
cmd_RUN_SHELL_COMMAND_help = "Run a linux shell command"
|
cmd_RUN_SHELL_COMMAND_help = "Run a linux shell command"
|
||||||
|
|
||||||
def cmd_RUN_SHELL_COMMAND(self, params):
|
def cmd_RUN_SHELL_COMMAND(self, params):
|
||||||
gcode_params = params.get('PARAMS','')
|
gcode_params = params.get("PARAMS", "")
|
||||||
gcode_params = shlex.split(gcode_params)
|
gcode_params = shlex.split(gcode_params)
|
||||||
reactor = self.printer.get_reactor()
|
reactor = self.printer.get_reactor()
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen(
|
proc = subprocess.Popen(
|
||||||
self.command + gcode_params, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
self.command + gcode_params,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
logging.exception(
|
logging.exception("shell_command: Command {%s} failed" % (self.name))
|
||||||
"shell_command: Command {%s} failed" % (self.name))
|
|
||||||
raise self.gcode.error("Error running command {%s}" % (self.name))
|
raise self.gcode.error("Error running command {%s}" % (self.name))
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
self.proc_fd = proc.stdout.fileno()
|
self.proc_fd = proc.stdout.fileno()
|
||||||
@@ -64,7 +71,7 @@ class ShellCommand:
|
|||||||
endtime = eventtime + self.timeout
|
endtime = eventtime + self.timeout
|
||||||
complete = False
|
complete = False
|
||||||
while eventtime < endtime:
|
while eventtime < endtime:
|
||||||
eventtime = reactor.pause(eventtime + .05)
|
eventtime = reactor.pause(eventtime + 0.05)
|
||||||
if proc.poll() is not None:
|
if proc.poll() is not None:
|
||||||
complete = True
|
complete = True
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user