From 040bcaa987502d51cdb64d5eb47c52577f71777d Mon Sep 17 00:00:00 2001 From: Robin Huang Date: Thu, 28 Nov 2024 13:58:56 -0800 Subject: [PATCH 1/5] Backup --- backup.py | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 backup.py diff --git a/backup.py b/backup.py new file mode 100644 index 00000000..5773b8a7 --- /dev/null +++ b/backup.py @@ -0,0 +1,86 @@ +import os +import re +import platform +import glob +import subprocess +import sys + +def get_logs_directory(): + system = platform.system() + if system == "Darwin": # macOS + return os.path.expanduser("~/Library/Logs/ComfyUI") + if system == "Windows": + appdata = os.getenv("APPDATA") + if appdata is None: + raise EnvironmentError("APPDATA environment variable is not set") + return os.path.join(appdata, "ComfyUI", "logs") + + raise NotImplementedError(f"System {system} not supported") + +def parse_log_file(log_path): + custom_nodes = set() + pattern = r"custom_nodes[/\\]([^/\\\s]+)(?:\.py)?" + + with open(log_path, 'r', encoding='utf-8') as file: + content = file.read() + matches = re.finditer(pattern, content) + + for match in matches: + node_name = match.group(1) + # Exclude specific nodes + if node_name not in ["ComfyUI-Manager", "websocket_image_save.py"]: + custom_nodes.add(node_name) + + return custom_nodes + +def get_sorted_log_files(): + try: + logs_dir = get_logs_directory() + except EnvironmentError: + print("Failed to get logs directory") + return [] + + log_files = glob.glob(os.path.join(logs_dir, "comfyui*.log")) + + # Sort files by modification time, newest first + return sorted(log_files, key=os.path.getmtime, reverse=True) + +def install_custom_nodes(nodes_list): + if not nodes_list: + print("No custom nodes to install") + return + + current_dir = os.path.dirname(os.path.abspath(__file__)) + cm_cli_path = os.path.join(current_dir, "cm-cli.py") + + if not os.path.exists(cm_cli_path): + print("ComfyUI-Manager CLI not found") + return + + nodes_str = " ".join(nodes_list) + + try: + cmd = [sys.executable, cm_cli_path, "install", *nodes_list] + subprocess.run(cmd, check=True) + print(f"Successfully installed nodes: {nodes_str}") + except subprocess.CalledProcessError as e: + print(f"Error installing nodes: {e}") + +def main(): + log_files = get_sorted_log_files() + if not log_files: + print("No log files found") + return + + custom_nodes = set() + for log_file in log_files: + nodes = parse_log_file(log_file) + if nodes: + custom_nodes.update(nodes) + print(f"Found custom nodes: {custom_nodes}") + install_custom_nodes(custom_nodes) + +if __name__ == "__main__": + #main() + print(parse_log_file("/Users/junhanhuang/Downloads/comfyui_2024-11-28T00-22-15-857Z.log")) + From cfade11352ce7f93e14773da104ce74ceaae1aa1 Mon Sep 17 00:00:00 2001 From: Robin Huang Date: Thu, 28 Nov 2024 15:12:17 -0800 Subject: [PATCH 2/5] Take install path for cm-cli. --- cm-cli.py | 19 ++++++++++++------- glob/manager_core.py | 6 +++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/cm-cli.py b/cm-cli.py index cb0e7c98..365b5931 100644 --- a/cm-cli.py +++ b/cm-cli.py @@ -54,7 +54,7 @@ def check_comfyui_hash(): core.comfy_ui_commit_datetime = repo.head.commit.committed_datetime -check_comfyui_hash() # This is a preparation step for manager_core +# check_comfyui_hash() # This is a preparation step for manager_core def read_downgrade_blacklist(): @@ -202,10 +202,11 @@ class Ctx: cm_ctx = Ctx() -def install_node(node_name, is_all=False, cnt_msg=''): +def install_node(node_name, is_all=False, cnt_msg='', install_path=None): if core.is_valid_url(node_name): # install via urls - res = core.gitclone_install([node_name]) + print(f"Installing {node_name} to {install_path}") + res = core.gitclone_install([node_name], install_path=install_path) if not res: print(f"[bold red]ERROR: An error occurred while installing '{node_name}'.[/bold red]") else: @@ -219,7 +220,7 @@ def install_node(node_name, is_all=False, cnt_msg=''): elif os.path.exists(node_path + '.disabled'): enable_node(node_name) else: - res = core.gitclone_install(node_item['files'], instant_execution=True, msg_prefix=f"[{cnt_msg}] ") + res = core.gitclone_install(node_item['files'], instant_execution=True, msg_prefix=f"[{cnt_msg}] ", install_path=install_path) if not res: print(f"[bold red]ERROR: An error occurred while installing '{node_name}'.[/bold red]") else: @@ -469,7 +470,7 @@ def auto_save_snapshot(): print(f"Current snapshot is saved as `{path}`") -def for_each_nodes(nodes, act, allow_all=True): +def for_each_nodes(nodes, act, allow_all=True, install_path=None): is_all = False if allow_all and 'all' in nodes: is_all = True @@ -481,7 +482,7 @@ def for_each_nodes(nodes, act, allow_all=True): i = 1 for x in nodes: try: - act(x, is_all=is_all, cnt_msg=f'{i}/{total}') + act(x, is_all=is_all, cnt_msg=f'{i}/{total}', install_path=install_path) except Exception as e: print(f"ERROR: {e}") traceback.print_exc() @@ -513,9 +514,13 @@ def install( None, help="[remote|local|cache]" ), + install_path: str = typer.Option( + None, + help="Specify the installation path" + ), ): cm_ctx.set_channel_mode(channel, mode) - for_each_nodes(nodes, act=install_node) + for_each_nodes(nodes, act=install_node, install_path=install_path) @app.command(help="Reinstall custom nodes") diff --git a/glob/manager_core.py b/glob/manager_core.py index 8ea3572c..4db9fcc8 100644 --- a/glob/manager_core.py +++ b/glob/manager_core.py @@ -572,7 +572,7 @@ def is_valid_url(url): return False -def gitclone_install(files, instant_execution=False, msg_prefix=''): +def gitclone_install(files, instant_execution=False, msg_prefix='', install_path=None): print(f"{msg_prefix}Install: {files}") for url in files: if not is_valid_url(url): @@ -582,9 +582,9 @@ def gitclone_install(files, instant_execution=False, msg_prefix=''): if url.endswith("/"): url = url[:-1] try: - print(f"Download: git clone '{url}'") + print(f"Download: git clone '{url}' to {install_path}") repo_name = os.path.splitext(os.path.basename(url))[0] - repo_path = os.path.join(get_default_custom_nodes_path(), repo_name) + repo_path = os.path.join(install_path or get_default_custom_nodes_path(), repo_name) # Clone the repository from the remote URL if not instant_execution and platform.system() == 'Windows': From 41dc4076265bf41a7cc001bbc2086b282f003bae Mon Sep 17 00:00:00 2001 From: Robin Huang Date: Thu, 28 Nov 2024 15:59:25 -0800 Subject: [PATCH 3/5] Remove unused. --- backup.py | 86 ------------------------------------------------------- 1 file changed, 86 deletions(-) delete mode 100644 backup.py diff --git a/backup.py b/backup.py deleted file mode 100644 index 5773b8a7..00000000 --- a/backup.py +++ /dev/null @@ -1,86 +0,0 @@ -import os -import re -import platform -import glob -import subprocess -import sys - -def get_logs_directory(): - system = platform.system() - if system == "Darwin": # macOS - return os.path.expanduser("~/Library/Logs/ComfyUI") - if system == "Windows": - appdata = os.getenv("APPDATA") - if appdata is None: - raise EnvironmentError("APPDATA environment variable is not set") - return os.path.join(appdata, "ComfyUI", "logs") - - raise NotImplementedError(f"System {system} not supported") - -def parse_log_file(log_path): - custom_nodes = set() - pattern = r"custom_nodes[/\\]([^/\\\s]+)(?:\.py)?" - - with open(log_path, 'r', encoding='utf-8') as file: - content = file.read() - matches = re.finditer(pattern, content) - - for match in matches: - node_name = match.group(1) - # Exclude specific nodes - if node_name not in ["ComfyUI-Manager", "websocket_image_save.py"]: - custom_nodes.add(node_name) - - return custom_nodes - -def get_sorted_log_files(): - try: - logs_dir = get_logs_directory() - except EnvironmentError: - print("Failed to get logs directory") - return [] - - log_files = glob.glob(os.path.join(logs_dir, "comfyui*.log")) - - # Sort files by modification time, newest first - return sorted(log_files, key=os.path.getmtime, reverse=True) - -def install_custom_nodes(nodes_list): - if not nodes_list: - print("No custom nodes to install") - return - - current_dir = os.path.dirname(os.path.abspath(__file__)) - cm_cli_path = os.path.join(current_dir, "cm-cli.py") - - if not os.path.exists(cm_cli_path): - print("ComfyUI-Manager CLI not found") - return - - nodes_str = " ".join(nodes_list) - - try: - cmd = [sys.executable, cm_cli_path, "install", *nodes_list] - subprocess.run(cmd, check=True) - print(f"Successfully installed nodes: {nodes_str}") - except subprocess.CalledProcessError as e: - print(f"Error installing nodes: {e}") - -def main(): - log_files = get_sorted_log_files() - if not log_files: - print("No log files found") - return - - custom_nodes = set() - for log_file in log_files: - nodes = parse_log_file(log_file) - if nodes: - custom_nodes.update(nodes) - print(f"Found custom nodes: {custom_nodes}") - install_custom_nodes(custom_nodes) - -if __name__ == "__main__": - #main() - print(parse_log_file("/Users/junhanhuang/Downloads/comfyui_2024-11-28T00-22-15-857Z.log")) - From 02307e64351f7b95a48d950c54f8cfeb47bebc58 Mon Sep 17 00:00:00 2001 From: Robin Huang Date: Fri, 29 Nov 2024 16:03:56 -0800 Subject: [PATCH 4/5] Add no deps. --- cm-cli.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/cm-cli.py b/cm-cli.py index 365b5931..93aaa553 100644 --- a/cm-cli.py +++ b/cm-cli.py @@ -83,6 +83,10 @@ class Ctx: self.mode = 'remote' self.processed_install = set() self.custom_node_map_cache = None + self.no_deps = False + + def set_no_deps(self, no_deps): + self.no_deps = no_deps def set_channel_mode(self, channel, mode): if mode is not None: @@ -202,7 +206,7 @@ class Ctx: cm_ctx = Ctx() -def install_node(node_name, is_all=False, cnt_msg='', install_path=None): +def install_node(node_name, is_all=False, cnt_msg='', install_path=None, no_deps=False): if core.is_valid_url(node_name): # install via urls print(f"Installing {node_name} to {install_path}") @@ -220,7 +224,7 @@ def install_node(node_name, is_all=False, cnt_msg='', install_path=None): elif os.path.exists(node_path + '.disabled'): enable_node(node_name) else: - res = core.gitclone_install(node_item['files'], instant_execution=True, msg_prefix=f"[{cnt_msg}] ", install_path=install_path) + res = core.gitclone_install(node_item['files'], instant_execution=True, msg_prefix=f"[{cnt_msg}] ", install_path=install_path, no_deps=no_deps) if not res: print(f"[bold red]ERROR: An error occurred while installing '{node_name}'.[/bold red]") else: @@ -470,7 +474,7 @@ def auto_save_snapshot(): print(f"Current snapshot is saved as `{path}`") -def for_each_nodes(nodes, act, allow_all=True, install_path=None): +def for_each_nodes(nodes, act, allow_all=True, install_path=None, no_deps=False): is_all = False if allow_all and 'all' in nodes: is_all = True @@ -482,7 +486,7 @@ def for_each_nodes(nodes, act, allow_all=True, install_path=None): i = 1 for x in nodes: try: - act(x, is_all=is_all, cnt_msg=f'{i}/{total}', install_path=install_path) + act(x, is_all=is_all, cnt_msg=f'{i}/{total}', install_path=install_path, no_deps=no_deps) except Exception as e: print(f"ERROR: {e}") traceback.print_exc() @@ -518,9 +522,18 @@ def install( None, help="Specify the installation path" ), + no_deps: Annotated[ + Optional[bool], + typer.Option( + "--no-deps", + show_default=False, + help="Skip installing any Python dependencies", + ), + ] = False, ): cm_ctx.set_channel_mode(channel, mode) - for_each_nodes(nodes, act=install_node, install_path=install_path) + cm_ctx.set_no_deps(no_deps) + for_each_nodes(nodes, act=install_node, install_path=install_path, no_deps=no_deps) @app.command(help="Reinstall custom nodes") From ad5fae39acfbd73a7c00a8713f64ad61fcb4000f Mon Sep 17 00:00:00 2001 From: Robin Huang Date: Fri, 29 Nov 2024 16:04:02 -0800 Subject: [PATCH 5/5] Add no deps. --- glob/manager_core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/glob/manager_core.py b/glob/manager_core.py index 4db9fcc8..080604f6 100644 --- a/glob/manager_core.py +++ b/glob/manager_core.py @@ -420,7 +420,7 @@ def __win_check_git_pull(path): process.wait() -def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=False): +def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=False, no_deps=False): install_script_path = os.path.join(repo_path, "install.py") requirements_path = os.path.join(repo_path, "requirements.txt") @@ -428,7 +428,7 @@ def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=Fa install_cmd = ["#LAZY-INSTALL-SCRIPT", sys.executable] try_install_script(url, repo_path, install_cmd) else: - if os.path.exists(requirements_path): + if os.path.exists(requirements_path) and not no_deps: print("Install: pip packages") pip_fixer = PIPFixer(get_installed_packages()) with open(requirements_path, "r") as requirements_file: @@ -572,7 +572,7 @@ def is_valid_url(url): return False -def gitclone_install(files, instant_execution=False, msg_prefix='', install_path=None): +def gitclone_install(files, instant_execution=False, msg_prefix='', install_path=None, no_deps=False): print(f"{msg_prefix}Install: {files}") for url in files: if not is_valid_url(url): @@ -596,7 +596,7 @@ def gitclone_install(files, instant_execution=False, msg_prefix='', install_path repo.git.clear_cache() repo.close() - if not execute_install_script(url, repo_path, instant_execution=instant_execution): + if not execute_install_script(url, repo_path, instant_execution=instant_execution, no_deps=no_deps): return False except Exception as e: