From 2dcd401955b164ea783dc9939ab1d06b053bea1d Mon Sep 17 00:00:00 2001 From: Nourepide Date: Sat, 16 Dec 2023 02:51:56 +0300 Subject: [PATCH] Split Loader.py 3 --- __init__.py | 4 +- boot/Backends.py | 7 +-- boot/Override.py | 4 +- boot/Paths.py | 62 +++++++++++++-------------- boot/Update.py | 109 ++++++++++++++++++++++++++++------------------- 5 files changed, 101 insertions(+), 85 deletions(-) diff --git a/__init__.py b/__init__.py index d559633..cf5d012 100644 --- a/__init__.py +++ b/__init__.py @@ -11,7 +11,7 @@ config = Config(logger).initiate() backends = Backends(logger).initiate() Update(logger, config, backends).initiate() -Paths(logger, config).initiate() -Override(logger, config).initiate() +Paths(logger, config, backends).initiate() +Override(logger, config, backends).initiate() NODE_CLASS_MAPPINGS = Modules(logger, config, backends).initiate() diff --git a/boot/Backends.py b/boot/Backends.py index 65bac4d..0a9480b 100644 --- a/boot/Backends.py +++ b/boot/Backends.py @@ -1,7 +1,8 @@ -import importlib +from importlib import import_module class Backends: + COMFY_UI = "main" TORCH = "torch" NUMPY = "numpy" CV2 = "cv2" @@ -11,14 +12,14 @@ class Backends: def __init__(self, logger): self.__logger = logger - self.__backends = [Backends.TORCH, Backends.NUMPY, Backends.CV2, Backends.PIL, Backends.REMBG, Backends.GIT] + self.__backends = [Backends.COMFY_UI, Backends.TORCH, Backends.NUMPY, Backends.CV2, Backends.PIL, Backends.REMBG, Backends.GIT] def initiate(self): dependencies = {} for backend in self.__backends: try: - importlib.import_module(backend) + import_module(backend) dependencies[backend] = True except ImportError: self.__logger.error(f"Loading {backend} library ended with an error.") diff --git a/boot/Override.py b/boot/Override.py index c8bee6f..d9fb79e 100644 --- a/boot/Override.py +++ b/boot/Override.py @@ -1,11 +1,11 @@ import nodes -from .Logger import Logger class Override: - def __init__(self, logger, config): + def __init__(self, logger, config, backends): self.__logger = logger self.__config = config + self.__backends = backends def initiate(self): override_nodes_len = 0 diff --git a/boot/Paths.py b/boot/Paths.py index 6b2a4ed..a6fd7a3 100644 --- a/boot/Paths.py +++ b/boot/Paths.py @@ -1,56 +1,52 @@ import os import platform from datetime import datetime +from importlib import import_module from pathlib import Path -import folder_paths +from .Backends import Backends class Paths: - ROOT_PATH = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - TEMPLATE_PATH = ROOT_PATH / "resources/template.json" - TIMESTAMP_PATH = ROOT_PATH / "resources/timestamp.json" - INFO_PATH = ROOT_PATH / "resources/info.json" + ROOT_PATH = Path(__file__).resolve().parent.parent + RESOURCE_PATH = ROOT_PATH / "resources" + TEMPLATE_PATH = RESOURCE_PATH / "template.json" + TIMESTAMP_PATH = RESOURCE_PATH / "timestamp.json" + INFO_PATH = RESOURCE_PATH / "info.json" + LOG_PATH = RESOURCE_PATH / f"logs/log_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S')}.log" CONFIG_PATH = ROOT_PATH / "config.json" GIT_PATH = ROOT_PATH / ".git" - LOG_PATH = ROOT_PATH / f"resources/logs/log_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S')}.log" - def __init__(self, logger, config): + def __init__(self, logger, config, backends): self.__logger = logger self.__config = config + self.__backends = backends def initiate(self): - fonts_folder_path = self.__get_fonts_folder_path() + if self.__backends[Backends.COMFY_UI]: + folder_paths = import_module("folder_paths") + fonts_folder_path = self.__get_font_paths(folder_paths) - os.environ["U2NET_HOME"] = folder_paths.models_dir + "/onnx" + os.environ["U2NET_HOME"] = str(Path(folder_paths.models_dir) / "onnx") - folder_paths.folder_names_and_paths["onnx"] = ([os.path.join(folder_paths.models_dir, "onnx")], {".onnx"}) - folder_paths.folder_names_and_paths["fonts"] = (fonts_folder_path, {".otf", ".ttf"}) + folder_paths.folder_names_and_paths.update({ + "onnx": ([Path(folder_paths.models_dir) / "onnx"], {".onnx"}), + "fonts": (fonts_folder_path, {".otf", ".ttf"}) + }) - def __get_fonts_folder_path(self): + def __get_font_paths(self, folder_paths): system = platform.system() - user_home = os.path.expanduser('~') + user_home = Path.home() - config_font_path = os.path.join(folder_paths.base_path, *self.__config["fonts"]["folder_path"].replace("\\", "/").split("/")) + config_font_path = Path(folder_paths.base_path) / Path(self.__config["fonts"]["folder_path"].replace("\\", "/")) + config_font_path.mkdir(parents=True, exist_ok=True) - if not os.path.exists(config_font_path): - os.makedirs(config_font_path, exist_ok=True) + system_fonts_paths = { + "Windows": [Path(os.environ.get("WINDIR", "")) / "Fonts"], + "Darwin": [Path("/Library") / "Fonts", user_home / "Library" / "Fonts"], + "Linux": [Path("/usr") / "share" / "fonts", Path("/usr") / "local" / "share" / "fonts", user_home / ".fonts"] + } - paths = [config_font_path] + paths = [config_font_path] + system_fonts_paths.get(system, []) - if self.__config["fonts"]["system_fonts"]: - if system == "Windows": - paths.append(os.path.join(os.environ["WINDIR"], "Fonts")) - elif system == "Darwin": - paths.append(os.path.join("/Library", "Fonts")) - elif system == "Linux": - paths.append(os.path.join("/usr", "share", "fonts")) - paths.append(os.path.join("/usr", "local", "share", "fonts")) - - if self.__config["fonts"]["user_fonts"]: - if system == "Darwin": - paths.append(os.path.join(user_home, "Library", "Fonts")) - elif system == "Linux": - paths.append(os.path.join(user_home, ".fonts")) - - return [path for path in paths if os.path.exists(path)] + return [str(path) for path in paths if path.exists()] diff --git a/boot/Update.py b/boot/Update.py index 0025442..360d847 100644 --- a/boot/Update.py +++ b/boot/Update.py @@ -1,5 +1,6 @@ import json import time +from importlib import import_module from .Backends import Backends from .Paths import Paths @@ -15,14 +16,14 @@ class Update: self.__config = config self.__backends = backends - if not Paths.CONFIG_PATH.exists(): + if not Paths.TIMESTAMP_PATH.exists(): self.__logger.info("Creating timestamp file.") self.__create_timestamp() self.__timestamp = self.__get_timestamp() def initiate(self): - confirm_unstable_agreement = self.__config["logger"]["confirm_unstable"] + confirm_unstable = self.__config["logger"]["confirm_unstable"] branch_name = self.__config["updates"]["branch_name"] search_frequency = self.__config["updates"]["search_frequency"].lower() time_difference = time.time() - self.__timestamp["timestamp"] @@ -35,23 +36,26 @@ class Update: "never": False } - try: - it_is_time_for_update = valid_frequencies[search_frequency] - except KeyError: - self.__logger.error(f"Unknown update frequency - {search_frequency}, available: {list(valid_frequencies.keys())}") - - return - - if not confirm_unstable_agreement and branch_name == "main" and search_frequency != "never": + if not confirm_unstable and branch_name == "main" and search_frequency != "never": self.__logger.warning_unstable_branch(branch_name) - if it_is_time_for_update: - if not (Paths.GIT_PATH.exists() and Paths.GIT_PATH.is_dir()): - self.__logger.error("Root directory of Allor is not a git repository. Update canceled.") + if self.__backends[Backends.GIT]: + if Paths.GIT_PATH.exists() and Paths.GIT_PATH.is_dir(): + repo = self.__repo() - return + self.__checkout(repo, branch_name) - self.__update_allor(branch_name) + try: + update_scheduled = valid_frequencies[search_frequency] + + if update_scheduled: + self.__pull(repo, branch_name) + except KeyError: + self.__logger.error(f"Unknown update frequency - {search_frequency}, available: {list(valid_frequencies.keys())}") + else: + self.__logger.error("Update canceled because Allor is not a git repository.") + else: + self.__logger.error("Update canceled because GitPython is not installed.") def __get_timestamp(self): with open(Paths.TIMESTAMP_PATH, "r") as f: @@ -65,46 +69,60 @@ class Update: with open(Paths.TIMESTAMP_PATH, "w", encoding="utf-8") as f: json.dump({"timestamp": time.time()}, f, ensure_ascii=False, indent=4) - def __update_allor(self, branch_name): - if self.__backends[Backends.GIT]: - import git + def __repo(self): + git = import_module("git") + repo = git.Repo - from git import Repo - from git import GitCommandError + return repo(Paths.ROOT_PATH, odbt=git.db.GitDB) - # noinspection PyTypeChecker, PyUnboundLocalVariable - repo = Repo(Paths.ROOT_PATH, odbt=git.db.GitDB) - current_commit = repo.head.commit.hexsha + def __checkout(self, repo, branch_name): + from git import GitCommandError + if repo.active_branch.name != branch_name: + if any([branch.name == branch_name for branch in repo.branches]): + try: + update_mode = self.__config["updates"]["update_mode"].lower() + valid_modes = ["soft", "hard"] + + if update_mode == "soft": + repo.git.checkout(branch_name) + elif update_mode == "hard": + repo.git.checkout(branch_name, force=True) + else: + self.__logger.error(f"Unknown update mode - {update_mode}, available: {valid_modes}") + except GitCommandError: + self.__logger.error(f"An error occurred while switching to the branch {branch_name}.") + else: + self.__logger.error(f"Branch with name {branch_name} not exist.") + + def __pull(self, repo, branch_name): + from git import GitCommandError + + try: repo.remotes.origin.fetch() - latest_commit = getattr(repo.remotes.origin.refs, branch_name).commit.hexsha + local_commits = list(repo.iter_commits(branch_name))[::-1] + remote_commits = list(repo.iter_commits(f"origin/{branch_name}"))[::-1] - if current_commit == latest_commit: - self.__logger.info("New updates not found.", self.__config["logger"]["updates_search"]) + incorrect_hex = any(lc != rc for lc, rc in zip(local_commits, remote_commits)) + + if incorrect_hex: + new_remote_commits = [] else: - self.__logger.info("New updates are available.", self.__config["logger"]["updates_search"]) + last_hex = next((i for i, (lc, rc) in enumerate(zip(local_commits, remote_commits)) if lc != rc), len(local_commits)) + new_remote_commits = remote_commits[last_hex:] if len(remote_commits) > len(local_commits) else [] + if incorrect_hex or new_remote_commits: if self.__config["updates"]["install_update"]: update_mode = self.__config["updates"]["update_mode"].lower() valid_modes = ["soft", "hard"] - if repo.active_branch.name != branch_name: - try: - repo.git.checkout(branch_name) - except GitCommandError: - self.__logger.error(f"An error occurred while switching to the branch {branch_name}.") - - return - if update_mode == "soft": - try: - repo.git.pull() - except GitCommandError: - self.__logger.error("An error occurred during the update. \n" - "It is recommended to use \"hard\" update mode. \n" - "But be careful, it erases all personal changes from Allor repository.") + if incorrect_hex: + self.__logger.warn("Incorrect hex of commits found in commits repository history.\n" + "Updating using \"soft\" update mode is unlikely to complete successfully.") + repo.git.pull() elif update_mode == "hard": repo.git.reset('--hard', 'origin/' + branch_name) else: @@ -112,8 +130,9 @@ class Update: return + self.__update_timestamp() self.__logger.info("Updates installed successfully.", self.__config["logger"]["install_complete"]) - - self.__update_timestamp() - else: - self.__logger.error("Update canceled because GitPython is not installed.") + except GitCommandError: + self.__logger.error("An error occurred during the updating.\n" + "It is recommended to use \"hard\" update mode.\n" + "But be careful, it erases all personal changes from Allor repository.")