mirror of
https://github.com/dw-0/kiauh.git
synced 2025-12-14 19:14:27 +05:00
Compare commits
6 Commits
v6.0.0-alp
...
v6.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a63cf8c9d9 | ||
|
|
02ed3e7da0 | ||
|
|
4427ae94af | ||
|
|
81b7b156b9 | ||
|
|
2df364512b | ||
|
|
dfa0036326 |
6
kiauh.py
6
kiauh.py
@@ -9,7 +9,13 @@
|
|||||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||||
# ======================================================================= #
|
# ======================================================================= #
|
||||||
|
|
||||||
|
import io
|
||||||
|
import sys
|
||||||
|
|
||||||
from kiauh.main import main
|
from kiauh.main import main
|
||||||
|
|
||||||
|
# ensure that all output is utf-8 encoded
|
||||||
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
4
kiauh.sh
4
kiauh.sh
@@ -10,7 +10,7 @@
|
|||||||
#=======================================================================#
|
#=======================================================================#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
clear
|
clear -x
|
||||||
|
|
||||||
# make sure we have the correct permissions while running the script
|
# make sure we have the correct permissions while running the script
|
||||||
umask 022
|
umask 022
|
||||||
@@ -110,7 +110,7 @@ function launch_kiauh_v6() {
|
|||||||
|
|
||||||
export PYTHONPATH="${entrypoint}"
|
export PYTHONPATH="${entrypoint}"
|
||||||
|
|
||||||
clear
|
clear -x
|
||||||
python3 "${entrypoint}/kiauh.py"
|
python3 "${entrypoint}/kiauh.py"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ from utils.input_utils import get_confirm
|
|||||||
from utils.instance_utils import get_instances
|
from utils.instance_utils import get_instances
|
||||||
|
|
||||||
|
|
||||||
def install_client_config(client_data: BaseWebClient) -> None:
|
def install_client_config(client_data: BaseWebClient, cfg_backup=True) -> None:
|
||||||
client_config: BaseWebClientConfig = client_data.client_config
|
client_config: BaseWebClientConfig = client_data.client_config
|
||||||
display_name = client_config.display_name
|
display_name = client_config.display_name
|
||||||
|
|
||||||
@@ -56,7 +56,8 @@ def install_client_config(client_data: BaseWebClient) -> None:
|
|||||||
download_client_config(client_config)
|
download_client_config(client_config)
|
||||||
create_client_config_symlink(client_config, kl_instances)
|
create_client_config_symlink(client_config, kl_instances)
|
||||||
|
|
||||||
backup_printer_config_dir()
|
if cfg_backup:
|
||||||
|
backup_printer_config_dir()
|
||||||
|
|
||||||
add_config_section(
|
add_config_section(
|
||||||
section=f"update_manager {client_config.name}",
|
section=f"update_manager {client_config.name}",
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ def print_client_port_select_dialog(
|
|||||||
dialog_content.extend(
|
dialog_content.extend(
|
||||||
[
|
[
|
||||||
"\n\n",
|
"\n\n",
|
||||||
"The following ports were found to be in use already:",
|
"The following ports were found to be already in use:",
|
||||||
*[f"● {port}" for port in ports_in_use],
|
*[f"● {p}" for p in ports_in_use if p != port],
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,9 @@ from components.webui_client.client_utils import (
|
|||||||
symlink_webui_nginx_log,
|
symlink_webui_nginx_log,
|
||||||
)
|
)
|
||||||
from core.instance_manager.instance_manager import InstanceManager
|
from core.instance_manager.instance_manager import InstanceManager
|
||||||
from core.logger import Logger
|
from core.logger import DialogCustomColor, DialogType, Logger
|
||||||
from utils.common import check_install_dependencies
|
from core.settings.kiauh_settings import KiauhSettings
|
||||||
|
from utils.common import backup_printer_config_dir, check_install_dependencies
|
||||||
from utils.config_utils import add_config_section
|
from utils.config_utils import add_config_section
|
||||||
from utils.fs_utils import unzip
|
from utils.fs_utils import unzip
|
||||||
from utils.input_utils import get_confirm
|
from utils.input_utils import get_confirm
|
||||||
@@ -49,16 +50,11 @@ from utils.sys_utils import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def install_client(client: BaseWebClient) -> None:
|
def install_client(
|
||||||
if client is None:
|
client: BaseWebClient,
|
||||||
raise ValueError("Missing parameter client_data!")
|
settings: KiauhSettings,
|
||||||
|
reinstall: bool = False,
|
||||||
if client.client_dir.exists():
|
) -> None:
|
||||||
Logger.print_info(
|
|
||||||
f"{client.display_name} seems to be already installed! Skipped ..."
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
mr_instances: List[Moonraker] = get_instances(Moonraker)
|
mr_instances: List[Moonraker] = get_instances(Moonraker)
|
||||||
|
|
||||||
enable_remotemode = False
|
enable_remotemode = False
|
||||||
@@ -88,7 +84,10 @@ def install_client(client: BaseWebClient) -> None:
|
|||||||
question = f"Download the recommended {client_config.display_name}?"
|
question = f"Download the recommended {client_config.display_name}?"
|
||||||
install_client_cfg = get_confirm(question, allow_go_back=False)
|
install_client_cfg = get_confirm(question, allow_go_back=False)
|
||||||
|
|
||||||
port: int = get_client_port_selection(client)
|
default_port: int = int(settings.get(client.name, "port"))
|
||||||
|
port: int = (
|
||||||
|
default_port if reinstall else get_client_port_selection(client, settings)
|
||||||
|
)
|
||||||
|
|
||||||
check_install_dependencies({"nginx"})
|
check_install_dependencies({"nginx"})
|
||||||
|
|
||||||
@@ -96,20 +95,22 @@ def install_client(client: BaseWebClient) -> None:
|
|||||||
download_client(client)
|
download_client(client)
|
||||||
if enable_remotemode and client.client == WebClientType.MAINSAIL:
|
if enable_remotemode and client.client == WebClientType.MAINSAIL:
|
||||||
enable_mainsail_remotemode()
|
enable_mainsail_remotemode()
|
||||||
if mr_instances:
|
|
||||||
add_config_section(
|
backup_printer_config_dir()
|
||||||
section=f"update_manager {client.name}",
|
add_config_section(
|
||||||
instances=mr_instances,
|
section=f"update_manager {client.name}",
|
||||||
options=[
|
instances=mr_instances,
|
||||||
("type", "web"),
|
options=[
|
||||||
("channel", "stable"),
|
("type", "web"),
|
||||||
("repo", str(client.repo_path)),
|
("channel", "stable"),
|
||||||
("path", str(client.client_dir)),
|
("repo", str(client.repo_path)),
|
||||||
],
|
("path", str(client.client_dir)),
|
||||||
)
|
],
|
||||||
InstanceManager.restart_all(mr_instances)
|
)
|
||||||
|
InstanceManager.restart_all(mr_instances)
|
||||||
|
|
||||||
if install_client_cfg and kl_instances:
|
if install_client_cfg and kl_instances:
|
||||||
install_client_config(client)
|
install_client_config(client, False)
|
||||||
|
|
||||||
copy_upstream_nginx_cfg()
|
copy_upstream_nginx_cfg()
|
||||||
copy_common_vars_nginx_cfg()
|
copy_common_vars_nginx_cfg()
|
||||||
@@ -127,12 +128,24 @@ def install_client(client: BaseWebClient) -> None:
|
|||||||
cmd_sysctl_service("nginx", "restart")
|
cmd_sysctl_service("nginx", "restart")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Logger.print_error(f"{client.display_name} installation failed!\n{e}")
|
Logger.print_error(e)
|
||||||
|
Logger.print_dialog(
|
||||||
|
DialogType.ERROR,
|
||||||
|
center_content=True,
|
||||||
|
content=[f"{client.display_name} installation failed!"],
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
log = f"Open {client.display_name} now on: http://{get_ipv4_addr()}:{port}"
|
# noinspection HttpUrlsUsage
|
||||||
Logger.print_ok(f"{client.display_name} installation complete!", start="\n")
|
Logger.print_dialog(
|
||||||
Logger.print_ok(log, prefix=False, end="\n\n")
|
DialogType.CUSTOM,
|
||||||
|
custom_title=f"{client.display_name} installation complete!",
|
||||||
|
custom_color=DialogCustomColor.GREEN,
|
||||||
|
center_content=True,
|
||||||
|
content=[
|
||||||
|
f"Open {client.display_name} now on: http://{get_ipv4_addr()}:{port}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def download_client(client: BaseWebClient) -> None:
|
def download_client(client: BaseWebClient) -> None:
|
||||||
|
|||||||
@@ -370,19 +370,26 @@ def read_ports_from_nginx_configs() -> List[int]:
|
|||||||
return sorted(ports_to_ints_list, key=lambda x: int(x))
|
return sorted(ports_to_ints_list, key=lambda x: int(x))
|
||||||
|
|
||||||
|
|
||||||
def get_client_port_selection(client: BaseWebClient) -> int:
|
def get_client_port_selection(
|
||||||
settings = KiauhSettings()
|
client: BaseWebClient,
|
||||||
|
settings: KiauhSettings,
|
||||||
|
reconfigure=False,
|
||||||
|
) -> int:
|
||||||
default_port: int = int(settings.get(client.name, "port"))
|
default_port: int = int(settings.get(client.name, "port"))
|
||||||
|
|
||||||
ports_in_use: List[int] = read_ports_from_nginx_configs()
|
ports_in_use: List[int] = read_ports_from_nginx_configs()
|
||||||
next_free_port: int = get_next_free_port(ports_in_use)
|
next_free_port: int = get_next_free_port(ports_in_use)
|
||||||
|
|
||||||
port: int = next_free_port if default_port in ports_in_use else default_port
|
port: int = (
|
||||||
|
next_free_port
|
||||||
|
if not reconfigure and default_port in ports_in_use
|
||||||
|
else default_port
|
||||||
|
)
|
||||||
|
|
||||||
print_client_port_select_dialog(client.display_name, port, ports_in_use)
|
print_client_port_select_dialog(client.display_name, port, ports_in_use)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
question = f"Configure {client.display_name} for port"
|
_type = "Reconfigure" if reconfigure else "Configure"
|
||||||
|
question = f"{_type} {client.display_name} for port"
|
||||||
port_input = get_number_input(question, min_count=80, default=port)
|
port_input = get_number_input(question, min_count=80, default=port)
|
||||||
|
|
||||||
if port_input not in ports_in_use:
|
if port_input not in ports_in_use:
|
||||||
@@ -400,3 +407,23 @@ def get_next_free_port(ports_in_use: List[int]) -> int:
|
|||||||
used_ports = set(map(int, ports_in_use))
|
used_ports = set(map(int, ports_in_use))
|
||||||
|
|
||||||
return min(valid_ports - used_ports)
|
return min(valid_ports - used_ports)
|
||||||
|
|
||||||
|
|
||||||
|
def set_listen_port(client: BaseWebClient, curr_port: int, new_port: int) -> None:
|
||||||
|
"""
|
||||||
|
Set the port the client should listen on in the NGINX config
|
||||||
|
:param curr_port: The current port the client listens on
|
||||||
|
:param new_port: The new port to set
|
||||||
|
:param client: The client to set the port for
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
config = NGINX_SITES_AVAILABLE.joinpath(client.name)
|
||||||
|
with open(config, "r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if "listen" in line:
|
||||||
|
lines[i] = line.replace(str(curr_port), str(new_port))
|
||||||
|
|
||||||
|
with open(config, "w") as f:
|
||||||
|
f.writelines(lines)
|
||||||
|
|||||||
104
kiauh/components/webui_client/menus/client_install_menu.py
Normal file
104
kiauh/components/webui_client/menus/client_install_menu.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# ======================================================================= #
|
||||||
|
# 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 __future__ import annotations
|
||||||
|
|
||||||
|
import textwrap
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
|
from components.webui_client.base_data import BaseWebClient
|
||||||
|
from components.webui_client.client_setup import install_client
|
||||||
|
from components.webui_client.client_utils import (
|
||||||
|
get_client_port_selection,
|
||||||
|
set_listen_port,
|
||||||
|
)
|
||||||
|
from core.constants import COLOR_CYAN, COLOR_GREEN, RESET_FORMAT
|
||||||
|
from core.logger import DialogCustomColor, DialogType, Logger
|
||||||
|
from core.menus import Option
|
||||||
|
from core.menus.base_menu import BaseMenu
|
||||||
|
from core.settings.kiauh_settings import KiauhSettings, WebUiSettings
|
||||||
|
from utils.sys_utils import cmd_sysctl_service, get_ipv4_addr
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
class ClientInstallMenu(BaseMenu):
|
||||||
|
def __init__(
|
||||||
|
self, client: BaseWebClient, previous_menu: Type[BaseMenu] | None = None
|
||||||
|
):
|
||||||
|
super().__init__()
|
||||||
|
self.previous_menu: Type[BaseMenu] | None = previous_menu
|
||||||
|
self.client: BaseWebClient = client
|
||||||
|
self.settings = KiauhSettings()
|
||||||
|
self.client_settings: WebUiSettings = self.settings[client.name]
|
||||||
|
|
||||||
|
def set_previous_menu(self, previous_menu: Type[BaseMenu] | None) -> None:
|
||||||
|
from core.menus.install_menu import InstallMenu
|
||||||
|
|
||||||
|
self.previous_menu = previous_menu if previous_menu is not None else InstallMenu
|
||||||
|
|
||||||
|
def set_options(self) -> None:
|
||||||
|
self.options = {
|
||||||
|
"1": Option(method=self.reinstall_client),
|
||||||
|
"2": Option(method=self.change_listen_port),
|
||||||
|
}
|
||||||
|
|
||||||
|
def print_menu(self) -> None:
|
||||||
|
client_name = self.client.display_name
|
||||||
|
|
||||||
|
header = f" [ Installation Menu > {client_name} ] "
|
||||||
|
color = COLOR_GREEN
|
||||||
|
count = 62 - len(color) - len(RESET_FORMAT)
|
||||||
|
port = f"(Current: {COLOR_CYAN}{int(self.client_settings.port)}{RESET_FORMAT})"
|
||||||
|
menu = textwrap.dedent(
|
||||||
|
f"""
|
||||||
|
╔═══════════════════════════════════════════════════════╗
|
||||||
|
║ {color}{header:~^{count}}{RESET_FORMAT} ║
|
||||||
|
╟───────────────────────────────────────────────────────╢
|
||||||
|
║ 1) Reinstall {client_name:16} ║
|
||||||
|
║ 2) Reconfigure Listen Port {port:<34} ║
|
||||||
|
╟───────────────────────────────────────────────────────╢
|
||||||
|
"""
|
||||||
|
)[1:]
|
||||||
|
print(menu, end="")
|
||||||
|
|
||||||
|
def reinstall_client(self, **kwargs) -> None:
|
||||||
|
install_client(self.client, settings=self.settings, reinstall=True)
|
||||||
|
|
||||||
|
def change_listen_port(self, **kwargs) -> None:
|
||||||
|
curr_port = int(self.client_settings.port)
|
||||||
|
new_port = get_client_port_selection(
|
||||||
|
self.client,
|
||||||
|
self.settings,
|
||||||
|
reconfigure=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd_sysctl_service("nginx", "stop")
|
||||||
|
set_listen_port(self.client, curr_port, new_port)
|
||||||
|
|
||||||
|
Logger.print_status("Saving new port configuration ...")
|
||||||
|
self.client_settings.port = new_port
|
||||||
|
self.settings.save()
|
||||||
|
Logger.print_ok("Port configuration saved!")
|
||||||
|
|
||||||
|
cmd_sysctl_service("nginx", "start")
|
||||||
|
|
||||||
|
# noinspection HttpUrlsUsage
|
||||||
|
Logger.print_dialog(
|
||||||
|
DialogType.CUSTOM,
|
||||||
|
custom_title="Port reconfiguration complete!",
|
||||||
|
custom_color=DialogCustomColor.GREEN,
|
||||||
|
center_content=True,
|
||||||
|
content=[
|
||||||
|
f"Open {self.client.display_name} now on: "
|
||||||
|
f"http://{get_ipv4_addr()}:{new_port}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _go_back(self, **kwargs) -> None:
|
||||||
|
if self.previous_menu is not None:
|
||||||
|
self.previous_menu().run()
|
||||||
@@ -29,7 +29,7 @@ from utils.input_utils import get_selection_input
|
|||||||
|
|
||||||
|
|
||||||
def clear() -> None:
|
def clear() -> None:
|
||||||
subprocess.call("clear", shell=True)
|
subprocess.call("clear -x", shell=True)
|
||||||
|
|
||||||
|
|
||||||
def print_header() -> None:
|
def print_header() -> None:
|
||||||
|
|||||||
@@ -15,13 +15,17 @@ from components.crowsnest.crowsnest import install_crowsnest
|
|||||||
from components.klipper import klipper_setup
|
from components.klipper import klipper_setup
|
||||||
from components.klipperscreen.klipperscreen import install_klipperscreen
|
from components.klipperscreen.klipperscreen import install_klipperscreen
|
||||||
from components.moonraker import moonraker_setup
|
from components.moonraker import moonraker_setup
|
||||||
from components.webui_client import client_setup
|
from components.webui_client.client_config.client_config_setup import (
|
||||||
from components.webui_client.client_config import client_config_setup
|
install_client_config,
|
||||||
|
)
|
||||||
|
from components.webui_client.client_setup import install_client
|
||||||
from components.webui_client.fluidd_data import FluiddData
|
from components.webui_client.fluidd_data import FluiddData
|
||||||
from components.webui_client.mainsail_data import MainsailData
|
from components.webui_client.mainsail_data import MainsailData
|
||||||
|
from components.webui_client.menus.client_install_menu import ClientInstallMenu
|
||||||
from core.constants import COLOR_GREEN, RESET_FORMAT
|
from core.constants import COLOR_GREEN, RESET_FORMAT
|
||||||
from core.menus import Option
|
from core.menus import Option
|
||||||
from core.menus.base_menu import BaseMenu
|
from core.menus.base_menu import BaseMenu
|
||||||
|
from core.settings.kiauh_settings import KiauhSettings
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyUnusedLocal
|
# noinspection PyUnusedLocal
|
||||||
@@ -80,16 +84,24 @@ class InstallMenu(BaseMenu):
|
|||||||
moonraker_setup.install_moonraker()
|
moonraker_setup.install_moonraker()
|
||||||
|
|
||||||
def install_mainsail(self, **kwargs) -> None:
|
def install_mainsail(self, **kwargs) -> None:
|
||||||
client_setup.install_client(MainsailData())
|
client: MainsailData = MainsailData()
|
||||||
|
if client.client_dir.exists():
|
||||||
|
ClientInstallMenu(client, self.__class__).run()
|
||||||
|
else:
|
||||||
|
install_client(client, settings=KiauhSettings())
|
||||||
|
|
||||||
def install_mainsail_config(self, **kwargs) -> None:
|
def install_mainsail_config(self, **kwargs) -> None:
|
||||||
client_config_setup.install_client_config(MainsailData())
|
install_client_config(MainsailData())
|
||||||
|
|
||||||
def install_fluidd(self, **kwargs) -> None:
|
def install_fluidd(self, **kwargs) -> None:
|
||||||
client_setup.install_client(FluiddData())
|
client: FluiddData = FluiddData()
|
||||||
|
if client.client_dir.exists():
|
||||||
|
ClientInstallMenu(client, self.__class__).run()
|
||||||
|
else:
|
||||||
|
install_client(client, settings=KiauhSettings())
|
||||||
|
|
||||||
def install_fluidd_config(self, **kwargs) -> None:
|
def install_fluidd_config(self, **kwargs) -> None:
|
||||||
client_config_setup.install_client_config(FluiddData())
|
install_client_config(FluiddData())
|
||||||
|
|
||||||
def install_klipperscreen(self, **kwargs) -> None:
|
def install_klipperscreen(self, **kwargs) -> None:
|
||||||
install_klipperscreen()
|
install_klipperscreen()
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ from __future__ import annotations
|
|||||||
import textwrap
|
import textwrap
|
||||||
from typing import Literal, Tuple, Type
|
from typing import Literal, Tuple, Type
|
||||||
|
|
||||||
|
from components.klipper.klipper_utils import get_klipper_status
|
||||||
|
from components.moonraker.moonraker_utils import get_moonraker_status
|
||||||
from core.constants import COLOR_CYAN, COLOR_GREEN, RESET_FORMAT
|
from core.constants import COLOR_CYAN, COLOR_GREEN, RESET_FORMAT
|
||||||
from core.logger import DialogType, Logger
|
from core.logger import DialogType, Logger
|
||||||
from core.menus import Option
|
from core.menus import Option
|
||||||
@@ -26,8 +28,8 @@ class SettingsMenu(BaseMenu):
|
|||||||
def __init__(self, previous_menu: Type[BaseMenu] | None = None) -> None:
|
def __init__(self, previous_menu: Type[BaseMenu] | None = None) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.previous_menu: Type[BaseMenu] | None = previous_menu
|
self.previous_menu: Type[BaseMenu] | None = previous_menu
|
||||||
self.klipper_repo: str | None = None
|
self.klipper_status = get_klipper_status()
|
||||||
self.moonraker_repo: str | None = None
|
self.moonraker_status = get_moonraker_status()
|
||||||
self.mainsail_unstable: bool | None = None
|
self.mainsail_unstable: bool | None = None
|
||||||
self.fluidd_unstable: bool | None = None
|
self.fluidd_unstable: bool | None = None
|
||||||
self.auto_backups_enabled: bool | None = None
|
self.auto_backups_enabled: bool | None = None
|
||||||
@@ -49,31 +51,41 @@ class SettingsMenu(BaseMenu):
|
|||||||
|
|
||||||
def print_menu(self) -> None:
|
def print_menu(self) -> None:
|
||||||
header = " [ KIAUH Settings ] "
|
header = " [ KIAUH Settings ] "
|
||||||
color = COLOR_CYAN
|
color, rst = COLOR_CYAN, RESET_FORMAT
|
||||||
count = 62 - len(color) - len(RESET_FORMAT)
|
count = 62 - len(color) - len(rst)
|
||||||
checked = f"[{COLOR_GREEN}x{RESET_FORMAT}]"
|
checked = f"[{COLOR_GREEN}x{rst}]"
|
||||||
unchecked = "[ ]"
|
unchecked = "[ ]"
|
||||||
|
|
||||||
|
kl_repo: str = f"{color}{self.klipper_status.repo}{rst}"
|
||||||
|
kl_branch: str = f"{color}{self.klipper_status.branch}{rst}"
|
||||||
|
kl_owner: str = f"{color}{self.klipper_status.owner}{rst}"
|
||||||
|
mr_repo: str = f"{color}{self.moonraker_status.repo}{rst}"
|
||||||
|
mr_branch: str = f"{color}{self.moonraker_status.branch}{rst}"
|
||||||
|
mr_owner: str = f"{color}{self.moonraker_status.owner}{rst}"
|
||||||
o1 = checked if self.mainsail_unstable else unchecked
|
o1 = checked if self.mainsail_unstable else unchecked
|
||||||
o2 = checked if self.fluidd_unstable else unchecked
|
o2 = checked if self.fluidd_unstable else unchecked
|
||||||
o3 = checked if self.auto_backups_enabled else unchecked
|
o3 = checked if self.auto_backups_enabled else unchecked
|
||||||
menu = textwrap.dedent(
|
menu = textwrap.dedent(
|
||||||
f"""
|
f"""
|
||||||
╔═══════════════════════════════════════════════════════╗
|
╔═══════════════════════════════════════════════════════╗
|
||||||
║ {color}{header:~^{count}}{RESET_FORMAT} ║
|
║ {color}{header:~^{count}}{rst} ║
|
||||||
╟───────────────────────────────────────────────────────╢
|
╟───────────────────────────────────────────────────────╢
|
||||||
║ Klipper source repository: ║
|
║ Klipper: ║
|
||||||
║ ● {self.klipper_repo:<67} ║
|
║ ● Repo: {kl_repo:51} ║
|
||||||
║ ║
|
║ ● Owner: {kl_owner:51} ║
|
||||||
║ Moonraker source repository: ║
|
║ ● Branch: {kl_branch:51} ║
|
||||||
║ ● {self.moonraker_repo:<67} ║
|
╟───────────────────────────────────────────────────────╢
|
||||||
║ ║
|
║ Moonraker: ║
|
||||||
║ Install unstable Webinterface releases: ║
|
║ ● Repo: {mr_repo:51} ║
|
||||||
|
║ ● Owner: {mr_owner:51} ║
|
||||||
|
║ ● Branch: {mr_branch:51} ║
|
||||||
|
╟───────────────────────────────────────────────────────╢
|
||||||
|
║ Install unstable releases: ║
|
||||||
║ {o1} Mainsail ║
|
║ {o1} Mainsail ║
|
||||||
║ {o2} Fluidd ║
|
║ {o2} Fluidd ║
|
||||||
║ ║
|
╟───────────────────────────────────────────────────────╢
|
||||||
║ Auto-Backup: ║
|
║ Auto-Backup: ║
|
||||||
║ {o3} Automatic backup before update ║
|
║ {o3} Automatic backup before update ║
|
||||||
║ ║
|
|
||||||
╟───────────────────────────────────────────────────────╢
|
╟───────────────────────────────────────────────────────╢
|
||||||
║ 1) Set Klipper source repository ║
|
║ 1) Set Klipper source repository ║
|
||||||
║ 2) Set Moonraker source repository ║
|
║ 2) Set Moonraker source repository ║
|
||||||
@@ -89,25 +101,10 @@ class SettingsMenu(BaseMenu):
|
|||||||
|
|
||||||
def _load_settings(self) -> None:
|
def _load_settings(self) -> None:
|
||||||
self.settings = KiauhSettings()
|
self.settings = KiauhSettings()
|
||||||
|
|
||||||
self._format_repo_str("klipper")
|
|
||||||
self._format_repo_str("moonraker")
|
|
||||||
|
|
||||||
self.auto_backups_enabled = self.settings.kiauh.backup_before_update
|
self.auto_backups_enabled = self.settings.kiauh.backup_before_update
|
||||||
self.mainsail_unstable = self.settings.mainsail.unstable_releases
|
self.mainsail_unstable = self.settings.mainsail.unstable_releases
|
||||||
self.fluidd_unstable = self.settings.fluidd.unstable_releases
|
self.fluidd_unstable = self.settings.fluidd.unstable_releases
|
||||||
|
|
||||||
def _format_repo_str(self, repo_name: Literal["klipper", "moonraker"]) -> None:
|
|
||||||
repo: RepoSettings = self.settings[repo_name]
|
|
||||||
repo_str = f"{'/'.join(repo.repo_url.rsplit('/', 2)[-2:])}"
|
|
||||||
branch_str = f"({COLOR_CYAN}@ {repo.branch}{RESET_FORMAT})"
|
|
||||||
|
|
||||||
setattr(
|
|
||||||
self,
|
|
||||||
f"{repo_name}_repo",
|
|
||||||
f"{COLOR_CYAN}{repo_str}{RESET_FORMAT} {branch_str}",
|
|
||||||
)
|
|
||||||
|
|
||||||
def _gather_input(self) -> Tuple[str, str]:
|
def _gather_input(self) -> Tuple[str, str]:
|
||||||
Logger.print_dialog(
|
Logger.print_dialog(
|
||||||
DialogType.ATTENTION,
|
DialogType.ATTENTION,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class ComponentStatus:
|
|||||||
status: StatusCode
|
status: StatusCode
|
||||||
owner: str | None = None
|
owner: str | None = None
|
||||||
repo: str | None = None
|
repo: str | None = None
|
||||||
|
branch: str = ""
|
||||||
local: str | None = None
|
local: str | None = None
|
||||||
remote: str | None = None
|
remote: str | None = None
|
||||||
instances: int | None = None
|
instances: int | None = None
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from core.constants import (
|
|||||||
from core.logger import DialogType, Logger
|
from core.logger import DialogType, Logger
|
||||||
from core.types import ComponentStatus, StatusCode
|
from core.types import ComponentStatus, StatusCode
|
||||||
from utils.git_utils import (
|
from utils.git_utils import (
|
||||||
|
get_current_branch,
|
||||||
get_local_commit,
|
get_local_commit,
|
||||||
get_local_tags,
|
get_local_tags,
|
||||||
get_remote_commit,
|
get_remote_commit,
|
||||||
@@ -103,7 +104,12 @@ def get_install_status(
|
|||||||
"""
|
"""
|
||||||
from utils.instance_utils import get_instances
|
from utils.instance_utils import get_instances
|
||||||
|
|
||||||
checks = [repo_dir.exists()]
|
checks = []
|
||||||
|
branch: str = ""
|
||||||
|
|
||||||
|
if repo_dir.exists():
|
||||||
|
checks.append(True)
|
||||||
|
branch = get_current_branch(repo_dir)
|
||||||
|
|
||||||
if env_dir is not None:
|
if env_dir is not None:
|
||||||
checks.append(env_dir.exists())
|
checks.append(env_dir.exists())
|
||||||
@@ -131,6 +137,7 @@ def get_install_status(
|
|||||||
instances=instances,
|
instances=instances,
|
||||||
owner=org,
|
owner=org,
|
||||||
repo=repo,
|
repo=repo,
|
||||||
|
branch=branch,
|
||||||
local=get_local_commit(repo_dir),
|
local=get_local_commit(repo_dir),
|
||||||
remote=get_remote_commit(repo_dir),
|
remote=get_remote_commit(repo_dir),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
# ======================================================================= #
|
# ======================================================================= #
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
@@ -26,6 +27,9 @@ def add_config_section(
|
|||||||
instances: List[InstanceType],
|
instances: List[InstanceType],
|
||||||
options: List[ConfigOption] | None = None,
|
options: List[ConfigOption] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
if not instances:
|
||||||
|
return
|
||||||
|
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
cfg_file = instance.cfg_file
|
cfg_file = instance.cfg_file
|
||||||
Logger.print_status(f"Add section '[{section}]' to '{cfg_file}' ...")
|
Logger.print_status(f"Add section '[{section}]' to '{cfg_file}' ...")
|
||||||
@@ -69,7 +73,7 @@ def add_config_section_at_top(section: str, instances: List[InstanceType]) -> No
|
|||||||
tmp.writelines(org_content)
|
tmp.writelines(org_content)
|
||||||
|
|
||||||
cfg_file.unlink()
|
cfg_file.unlink()
|
||||||
tmp_cfg_path.rename(cfg_file)
|
shutil.move(tmp_cfg_path, cfg_file)
|
||||||
|
|
||||||
Logger.print_ok("OK!")
|
Logger.print_ok("OK!")
|
||||||
|
|
||||||
|
|||||||
@@ -87,12 +87,29 @@ def get_repo_name(repo: Path) -> Tuple[str, str]:
|
|||||||
orga: str = substrings[0] if substrings[0] else "-"
|
orga: str = substrings[0] if substrings[0] else "-"
|
||||||
name: str = substrings[1] if substrings[1] else "-"
|
name: str = substrings[1] if substrings[1] else "-"
|
||||||
|
|
||||||
return orga, name
|
return orga, name.replace(".git", "")
|
||||||
|
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
return "-", "-"
|
return "-", "-"
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_branch(repo: Path) -> str:
|
||||||
|
"""
|
||||||
|
Get the current branch of a local Git repository
|
||||||
|
:param repo: Path to the local Git repository
|
||||||
|
:return: Current branch
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cmd = ["git", "branch", "--show-current"]
|
||||||
|
result: str = check_output(cmd, stderr=DEVNULL, cwd=repo).decode(
|
||||||
|
encoding="utf-8"
|
||||||
|
)
|
||||||
|
return result.strip()
|
||||||
|
|
||||||
|
except CalledProcessError:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]:
|
def get_local_tags(repo_path: Path, _filter: str | None = None) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Get all tags of a local Git repository
|
Get all tags of a local Git repository
|
||||||
@@ -209,8 +226,8 @@ def get_local_commit(repo: Path) -> str | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmd = f"cd {repo} && git describe HEAD --always --tags | cut -d '-' -f 1,2"
|
cmd = "git describe HEAD --always --tags | cut -d '-' -f 1,2"
|
||||||
return check_output(cmd, shell=True, text=True).strip()
|
return check_output(cmd, shell=True, text=True, cwd=repo).strip()
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -220,12 +237,15 @@ def get_remote_commit(repo: Path) -> str | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# get locally checked out branch
|
branch = get_current_branch(repo)
|
||||||
branch_cmd = f"cd {repo} && git branch | grep -E '\*'"
|
cmd = f"git describe 'origin/{branch}' --always --tags | cut -d '-' -f 1,2"
|
||||||
branch = check_output(branch_cmd, shell=True, text=True)
|
return check_output(
|
||||||
branch = branch.split("*")[-1].strip()
|
cmd,
|
||||||
cmd = f"cd {repo} && git describe 'origin/{branch}' --always --tags | cut -d '-' -f 1,2"
|
shell=True,
|
||||||
return check_output(cmd, shell=True, text=True).strip()
|
text=True,
|
||||||
|
cwd=repo,
|
||||||
|
stderr=DEVNULL,
|
||||||
|
).strip()
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user