From a4a3d5eecb96856c3d18544490cf3940d07d1750 Mon Sep 17 00:00:00 2001 From: dw-0 Date: Tue, 14 Nov 2023 21:28:13 +0100 Subject: [PATCH] feat(BackupManager): implement simple backup manager Signed-off-by: Dominik Willner --- kiauh/__init__.py | 14 +++++ kiauh/core/backup_manager/__init__.py | 0 kiauh/core/backup_manager/backup_manager.py | 69 +++++++++++++++++++++ kiauh/core/config_manager/config_manager.py | 17 +++-- kiauh/modules/klipper/klipper_setup.py | 15 +++-- kiauh/utils/common.py | 25 ++++++++ kiauh/utils/constants.py | 3 + 7 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 kiauh/core/backup_manager/__init__.py create mode 100644 kiauh/core/backup_manager/backup_manager.py create mode 100644 kiauh/utils/common.py diff --git a/kiauh/__init__.py b/kiauh/__init__.py index e69de29..f670517 100644 --- a/kiauh/__init__.py +++ b/kiauh/__init__.py @@ -0,0 +1,14 @@ +# !/usr/bin/env python + +# ======================================================================= # +# Copyright (C) 2020 - 2023 Dominik Willner # +# # +# 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 os.path import dirname, abspath + +APPLICATION_ROOT = dirname(dirname(abspath(__file__))) diff --git a/kiauh/core/backup_manager/__init__.py b/kiauh/core/backup_manager/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kiauh/core/backup_manager/backup_manager.py b/kiauh/core/backup_manager/backup_manager.py new file mode 100644 index 0000000..8a333a5 --- /dev/null +++ b/kiauh/core/backup_manager/backup_manager.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +# ======================================================================= # +# Copyright (C) 2020 - 2023 Dominik Willner # +# # +# 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 shutil +from pathlib import Path + +from kiauh.utils.common import get_current_date +from kiauh.utils.constants import KIAUH_BACKUP_DIR +from kiauh.utils.logger import Logger + + +# noinspection PyMethodMayBeStatic +class BackupManager: + def __init__( + self, backup_name: str, source: Path, backup_dir: Path = KIAUH_BACKUP_DIR + ): + self._backup_name = backup_name + self._source = source + self._backup_dir = backup_dir + + @property + def backup_name(self) -> str: + return self._backup_name + + @backup_name.setter + def backup_name(self, value: str): + self._backup_name = value + + @property + def source(self) -> Path: + return self._source + + @source.setter + def source(self, value: Path): + self._source = value + + @property + def backup_dir(self) -> Path: + return self._backup_dir + + @backup_dir.setter + def backup_dir(self, value: Path): + self._backup_dir = value + + def backup(self) -> None: + if self._source is None or not Path(self._source).exists(): + raise OSError + + try: + log = f"Creating backup of {self.backup_name} in {self.backup_dir} ..." + Logger.print_info(log) + date = get_current_date() + dest = Path( + f"{self.backup_dir}/{self.backup_name}/{date.get('date')}-{date.get('time')}" + ) + shutil.copytree(src=self.source, dst=dest) + except OSError as e: + Logger.print_error(f"Unable to backup source directory. Not exist.\n{e}") + return + + Logger.print_ok("Backup successfull!") diff --git a/kiauh/core/config_manager/config_manager.py b/kiauh/core/config_manager/config_manager.py index 0f80647..0237a27 100644 --- a/kiauh/core/config_manager/config_manager.py +++ b/kiauh/core/config_manager/config_manager.py @@ -14,6 +14,7 @@ import configparser from pathlib import Path from typing import Union +from kiauh import APPLICATION_ROOT from kiauh.utils.logger import Logger @@ -34,7 +35,7 @@ class ConfigManager: with open(self.config_file, "w") as cfg: self.config.write(cfg) - def get_value(self, section: str, key: str) -> Union[str, None]: + def get_value(self, section: str, key: str) -> Union[str, bool, None]: if not self.config.has_section(section): log = f"Section not defined. Unable to read section: [{section}]." Logger.print_error(log) @@ -45,17 +46,21 @@ class ConfigManager: Logger.print_error(log) return None - return self.config.get(section, key) + value = self.config.get(section, key) + if value == "True" or value == "true": + return True + elif value == "False" or value == "false": + return False + else: + return value def set_value(self, section: str, key: str, value: str): self.config.set(section, key, value) - def check_config_exists(self) -> bool: + def check_config_exist(self) -> bool: return True if self._get_cfg_location() else False def _get_cfg_location(self) -> str: - current_dir = os.path.dirname(os.path.abspath(__file__)) - project_dir = os.path.dirname(os.path.dirname(current_dir)) - cfg_path = os.path.join(project_dir, "kiauh.cfg") + cfg_path = os.path.join(APPLICATION_ROOT, "kiauh.cfg") return cfg_path if Path(cfg_path).exists() else None diff --git a/kiauh/modules/klipper/klipper_setup.py b/kiauh/modules/klipper/klipper_setup.py index fea9b6d..e7c4d52 100644 --- a/kiauh/modules/klipper/klipper_setup.py +++ b/kiauh/modules/klipper/klipper_setup.py @@ -14,6 +14,7 @@ import subprocess from pathlib import Path from typing import List, Union +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.modules.klipper import ( @@ -251,16 +252,22 @@ def remove_multi_instance( def update_klipper() -> None: print_update_warn_dialog() - if not get_confirm("Update Klipper now?"): return - instance_manager = InstanceManager(Klipper) - instance_manager.stop_all_instance() - cm = ConfigManager() cm.read_config() + if cm.get_value("kiauh", "backup_before_update"): + backup_manager = BackupManager(source=KLIPPER_DIR, backup_name="klipper") + backup_manager.backup() + backup_manager.backup_name = "klippy-env" + backup_manager.source = KLIPPER_ENV_DIR + backup_manager.backup() + + instance_manager = InstanceManager(Klipper) + instance_manager.stop_all_instance() + repo = str(cm.get_value("klipper", "repository_url") or DEFAULT_KLIPPER_REPO_URL) branch = str(cm.get_value("klipper", "branch") or "master") diff --git a/kiauh/utils/common.py b/kiauh/utils/common.py new file mode 100644 index 0000000..bc9a9fb --- /dev/null +++ b/kiauh/utils/common.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +# ======================================================================= # +# Copyright (C) 2020 - 2023 Dominik Willner # +# # +# 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 datetime import datetime +from typing import Dict, Literal + + +def get_current_date() -> Dict[Literal["date", "time"], str]: + """ + Get the current date | + :return: a Dict holding a date and time key:value pair + """ + now: datetime = datetime.today() + date: str = now.strftime("%Y-%m-%d") + time: str = now.strftime("%H-%M-%S") + + return {"date": date, "time": time} diff --git a/kiauh/utils/constants.py b/kiauh/utils/constants.py index 60662ce..08a4398 100644 --- a/kiauh/utils/constants.py +++ b/kiauh/utils/constants.py @@ -11,6 +11,7 @@ import os import pwd +from pathlib import Path # text colors and formats COLOR_MAGENTA = "\033[35m" # magenta @@ -19,6 +20,8 @@ COLOR_YELLOW = "\033[93m" # bright yellow COLOR_RED = "\033[91m" # bright red COLOR_CYAN = "\033[96m" # bright cyan RESET_FORMAT = "\033[0m" # reset format +# kiauh +KIAUH_BACKUP_DIR = f"{Path.home()}/kiauh-backups" # current user CURRENT_USER = pwd.getpwuid(os.getuid())[0] SYSTEMD = "/etc/systemd/system"