Compare commits

...

8 Commits

Author SHA1 Message Date
Thijs Triemstra
4c511017f1 README: Update KlipperScreen link and contributor name (#753)
Update KlipperScreen link and contributor name

update maintainer for klipperscreen
2025-11-30 17:42:36 +01:00
Clifford
372bab8847 feat(gcode_shell_command): allowing for expanding env vars (#747)
allowing for expanding env vars
2025-11-23 12:53:52 +01:00
Charlie Lima
d5062d41de refactor: remove dependency on libatlas-base-dev (#744)
Remove dependency on libatlas-base-dev

Co-authored-by: charlie-lima-bean <ktoaster@pm.me>
2025-11-23 09:25:05 +01:00
dw-0
e9459bd68e fix(backup): correct backup folder path display in menu 2025-11-09 11:58:03 +01:00
dw-0
ee460663c9 fix(spoolman): ensure proper file handling when adding Spoolman entry 2025-10-28 12:12:36 +01:00
dw-0
6f0e0146ef fix(client): improve version retrieval logic and handle JSON errors 2025-10-27 19:00:08 +01:00
dw-0
229f317025 fix(backup): do not create redundant subdirectory on single file backup 2025-10-27 09:47:09 +01:00
dw-0
48c0ae7227 fix(backup): allow reusing existing backup directory and enhance copy options 2025-10-27 09:30:33 +01:00
7 changed files with 61 additions and 27 deletions

View File

@@ -143,7 +143,7 @@ changes!**
<tr>
<th><h3><a href="https://github.com/fluidd-core/fluidd">Fluidd</a></h3></th>
<th><h3><a href="https://github.com/jordanruthe/KlipperScreen">KlipperScreen</a></h3></th>
<th><h3><a href="https://github.com/KlipperScreen/KlipperScreen">KlipperScreen</a></h3></th>
<th><h3><a href="https://github.com/OctoPrint/OctoPrint">OctoPrint</a></h3></th>
</tr>
<tr>
@@ -153,7 +153,7 @@ changes!**
</tr>
<tr>
<th>by <a href="https://github.com/fluidd-core">fluidd-core</a></th>
<th>by <a href="https://github.com/jordanruthe">jordanruthe</a></th>
<th>by <a href="https://github.com/alfrix">alfrix</a></th>
<th>by <a href="https://github.com/OctoPrint">OctoPrint</a></th>
</tr>

View File

@@ -237,7 +237,6 @@ def install_input_shaper_deps() -> None:
"If you agree, the following additional system packages will be installed:",
"● python3-numpy",
"● python3-matplotlib",
"● libatlas-base-dev",
"● libopenblas-dev",
"\n\n",
"Also, the following Python package will be installed:",
@@ -253,7 +252,6 @@ def install_input_shaper_deps() -> None:
apt_deps = (
"python3-numpy",
"python3-matplotlib",
"libatlas-base-dev",
"libopenblas-dev",
)
check_install_dependencies({*apt_deps})

View File

@@ -11,6 +11,7 @@ from __future__ import annotations
import json
import re
import shutil
from json import JSONDecodeError
from pathlib import Path
from subprocess import PIPE, CalledProcessError, run
from typing import List, get_args
@@ -151,18 +152,36 @@ def symlink_webui_nginx_log(
def get_local_client_version(client: BaseWebClient) -> str | None:
relinfo_file = client.client_dir.joinpath("release_info.json")
version_file = client.client_dir.joinpath(".version")
default = "n/a"
if not client.client_dir.exists():
return None
if not relinfo_file.is_file() and not version_file.is_file():
return "n/a"
return default
# try to get version from release_info.json first
if relinfo_file.is_file():
with open(relinfo_file, "r") as f:
return str(json.load(f)["version"])
else:
with open(version_file, "r") as f:
return f.readlines()[0]
try:
if relinfo_file.stat().st_size == 0:
raise JSONDecodeError("Empty file", "", 0)
with open(relinfo_file, "r", encoding="utf-8") as f:
data = json.load(f)
raw_version = data.get("version")
if raw_version is not None:
parsed = str(raw_version).strip()
if parsed:
return parsed
except (JSONDecodeError, OSError):
Logger.print_error("Invalid 'release_info.json'")
# fallback to .version file
if version_file.is_file():
try:
with open(version_file, "r") as f:
line = f.readline().strip()
return line or default
except OSError:
Logger.print_error("Unable to read '.version'")
return default
def get_remote_client_version(client: BaseWebClient) -> str | None:

View File

@@ -58,7 +58,7 @@ class BackupMenu(BaseMenu):
def print_menu(self) -> None:
line1 = Color.apply(
"INFO: Backups are located in '~/kiauh-backups'", Color.YELLOW
"INFO: Backups are located in '~/kiauh_backups'", Color.YELLOW
)
menu = textwrap.dedent(
f"""

View File

@@ -62,16 +62,16 @@ class BackupService:
target_name
or f"{source_path.stem}_{self.timestamp}{source_path.suffix}"
)
if target_path is not None:
backup_path = self._backup_root.joinpath(target_path, filename)
else:
backup_path = self._backup_root.joinpath(filename)
backup_path.mkdir(parents=True, exist_ok=True)
shutil.copy2(source_path, backup_path)
backup_dir = self._backup_root
if target_path is not None:
backup_dir = self._backup_root.joinpath(target_path)
backup_dir.mkdir(parents=True, exist_ok=True)
shutil.copy2(source_path, backup_dir.joinpath(filename))
Logger.print_ok(
f"Successfully backed up '{source_path}' to '{backup_path}'"
f"Successfully backed up '{source_path}' to '{backup_dir}'"
)
return True
@@ -109,7 +109,16 @@ class BackupService:
else:
backup_path = self._backup_root.joinpath(backup_dir_name)
shutil.copytree(source_path, backup_path)
if backup_path.exists():
Logger.print_info(f"Reusing existing backup directory '{backup_path}'")
shutil.copytree(
source_path,
backup_path,
dirs_exist_ok=True,
symlinks=True,
ignore_dangling_symlinks=True,
)
Logger.print_ok(
f"Successfully backed up '{source_path}' to '{backup_path}'"

View File

@@ -16,6 +16,7 @@ class ShellCommand:
self.gcode = self.printer.lookup_object("gcode")
cmd = config.get("command")
cmd = os.path.expanduser(cmd)
cmd = os.path.expandvars(cmd)
self.command = shlex.split(cmd)
self.timeout = config.getfloat("timeout", 2.0, above=0.0)
self.verbose = config.getboolean("verbose", True)

View File

@@ -8,6 +8,7 @@
# ======================================================================= #
import re
from pathlib import Path
from subprocess import CalledProcessError, run
from typing import List, Tuple
@@ -311,13 +312,19 @@ class SpoolmanExtension(BaseExtension):
mrsvc.load_instances()
mr_instances = mrsvc.get_all_instances()
for instance in mr_instances:
asvc_path = instance.data_dir.joinpath("moonraker.asvc")
if asvc_path.exists():
if "Spoolman" in open(asvc_path).read():
Logger.print_info(f"Spoolman already in {asvc_path}. Skipping...")
continue
asvc_path: Path = instance.data_dir.joinpath("moonraker.asvc")
if asvc_path.exists() and asvc_path.is_file():
with open(asvc_path, "a+") as f:
if "Spoolman" in f.read():
Logger.print_info(
f"Spoolman already in {asvc_path}. Skipping..."
)
continue
content: List[str] = f.readlines()
if content and not content[-1].endswith("\n"):
f.write("\n")
with open(asvc_path, "a") as f:
f.write("Spoolman\n")
Logger.print_ok(f"Spoolman added to {asvc_path}!")