From 6a310f3927b45c8a28de51415fd30f734a1aa3cf Mon Sep 17 00:00:00 2001 From: Ash Martian Date: Tue, 28 May 2024 17:46:32 -0700 Subject: [PATCH 1/5] Handle mising tk binaries --- __init__.py | 46 +++++++++++++++++++++++----------------------- dir_loop.py | 2 +- dir_picker.py | 45 +++++++++++++++++++++++++++++++-------------- web/js/gir.js | 12 ++++++++++++ 4 files changed, 67 insertions(+), 38 deletions(-) diff --git a/__init__.py b/__init__.py index 91e00e4..7793fd0 100644 --- a/__init__.py +++ b/__init__.py @@ -1,40 +1,40 @@ # __init__.py - -from .dir_picker import DirPicker -from .dir_loop import LoopyDir -from .image_nabber import ImageNabber import importlib.util +import sys def install_tkinter(): - # Helper function to install the tkinter module if not already installed try: importlib.import_module('tkinter') except ImportError: + print("[ComfyUI-DirGir] Attempting to install tkinter") try: - import pip - pip.main(['install', 'tk']) - # If macOS, attempt to install via brew + import subprocess import platform - if platform.system() == 'Darwin': - try: - import subprocess - subprocess.run(['brew', 'install', 'python-tk']) - except FileNotFoundError: - pass - # If Linux, attempt to install via apt - elif platform.system() == 'Linux': - try: - import subprocess - subprocess.run(['apt', 'install', 'python3-tk']) - except FileNotFoundError: - pass - except: - print("Could not install tkinter") + system = platform.system() + if system == 'Darwin': + result = subprocess.run(['brew', 'install', 'python-tk'], check=True) + if result.returncode != 0: + raise Exception("Brew installation failed, ensure you have brew installed (https://brew.sh/)") + elif system == 'Linux': + result = subprocess.run(['sudo', 'apt', '-y', 'install', 'python3-tk'], check=True) + if result.returncode != 0: + raise Exception("Apt installation failed") + else: + result = subprocess.run([sys.executable, '-m', 'pip', 'install', 'tk'], check=True) + if result.returncode != 0: + raise Exception("Pip installation failed") + except Exception as e: + print("[ComfyUI-DirGir] Could not install tkinter, try setting TCL_LIBRARY and TK_LIBRARY environment variables to the location of your tcl and tk libraries (https://www.magicsplat.com/tcl-installer/index.html#downloads)") + print(e) install_tkinter() +from .dir_picker import DirPicker +from .dir_loop import LoopyDir +from .image_nabber import ImageNabber + WEB_DIRECTORY = "./web" NODE_CLASS_MAPPINGS = { diff --git a/dir_loop.py b/dir_loop.py index c677b4e..12502bf 100644 --- a/dir_loop.py +++ b/dir_loop.py @@ -59,7 +59,7 @@ def iterate_directory(cls, directory, filter_type, filter_value, loop_index, pro if len(cls.matched_files) == 0: # No files found, reset index loop_indexes[id] = 0 - print("No files found in directory" + directory) + print("[ComfyUI-DirGir] No files found in directory" + directory) return (0, 0, "", "", []) # Ensure loop_index is within bounds diff --git a/dir_picker.py b/dir_picker.py index c61fbce..cc1ca6a 100644 --- a/dir_picker.py +++ b/dir_picker.py @@ -1,11 +1,19 @@ # dir_picker.py from aiohttp import web -import tkinter as tk import json -from tkinter import filedialog import server import os +try: + import tkinter as tk + from tkinter import filedialog + hasTK = True +except ImportError as e: + hasTK = False + print("[ComfyUI-DirGir] Could not import filedialog from tkinter, please ensure tkinter is installed (https://www.tutorialspoint.com/how-to-install-tkinter-in-python)") + print(e) + + picked_dirs = {} current_path = os.path.abspath(os.path.dirname(__file__)) @@ -62,17 +70,26 @@ async def select_directory(cls, request): def select_folder(id): # This method remains synchronous defaultPath = picked_dirs.get(id) or "~" - root = tk.Tk() - root.withdraw() - root.attributes('-topmost', True) - root.lift() - root.focus_force() - folder_path = filedialog.askdirectory( - initialdir=defaultPath, title="Select a directory") - filedialog.dialogstates = {} # Clear the dialog state - root.quit() - root.destroy() - print("Selected folder:", folder_path) + if hasTK: + try: + root = tk.Tk() + root.withdraw() + root.attributes('-topmost', True) + root.lift() + root.focus_force() + folder_path = filedialog.askdirectory( + initialdir=defaultPath, title="Select a directory") + filedialog.dialogstates = {} # Clear the dialog state + root.quit() + root.destroy() + print("[ComfyUI-DirGir] Selected folder:", folder_path) + except Exception as e: + print("[ComfyUI-DirGir] Could not select folder") + print(e) + folder_path = None + else: + folder_path = None + print("[ComfyUI-DirGir] Could not import filedialog from tkinter, please ensure tkinter is installed (https://www.tutorialspoint.com/how-to-install-tkinter-in-python)") return folder_path or defaultPath @@ -85,7 +102,7 @@ async def select_folder_route(request): @server.PromptServer.instance.routes.get("/gir-dir/get-directory") async def get_last_selected_directory(request): load_picked_dirs() - return web.json_response({'selected_folder': picked_dirs.get(request.rel_url.query.get('id', ''))}) + return web.json_response({'selected_folder': picked_dirs.get(request.rel_url.query.get('id', '')), 'hasTK': hasTK}) @server.PromptServer.instance.routes.get("/gir-dir/set-directory") diff --git a/web/js/gir.js b/web/js/gir.js index edb59d2..047531f 100644 --- a/web/js/gir.js +++ b/web/js/gir.js @@ -4,6 +4,7 @@ import { api } from '../../../scripts/api.js'; import { app } from '../../../scripts/app.js'; // console.log(app); +let hasTk = false; function getDirectoryPath(node_id) { return new Promise((resolve, reject) => { @@ -33,6 +34,9 @@ function getCurrentDirectory(node_id) { return response.json(); }) .then(data => { + if(data.hasTk) { + hasTk = true; + } resolve(data.selected_folder); }) .catch(error => { @@ -120,6 +124,10 @@ app.registerExtension({ getDirectoryPath(node.id).then(directory => { // Add a text element to the node that displays the selected directory element.innerHTML = directory; + if(!hasTk) { + console.log('Tkinter not installed'); + console.log(widget) + } node.setOutputData("directory", directory); node.onResize?.(node.size); node.widgets.filter(w => w.name === "Selected Directory").forEach(w => w.value = directory); @@ -136,6 +144,10 @@ app.registerExtension({ element.innerHTML = directory; node.setOutputData("directory", directory); node.widgets.filter(w => w.name === "Selected Directory").forEach(w => w.value = directory); + if (!hasTk) { + console.log('Tkinter not installed'); + node.widgets.filter(w => w.name === "Select Directory").forEach(w => w.disabled = true) + } } }); From c25a59277d80a12600de73e781c9bfc079dceb94 Mon Sep 17 00:00:00 2001 From: Ash Martian Date: Tue, 28 May 2024 17:49:32 -0700 Subject: [PATCH 2/5] fit typo --- web/js/gir.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/js/gir.js b/web/js/gir.js index 047531f..c440e21 100644 --- a/web/js/gir.js +++ b/web/js/gir.js @@ -34,7 +34,7 @@ function getCurrentDirectory(node_id) { return response.json(); }) .then(data => { - if(data.hasTk) { + if(data.hasTK) { hasTk = true; } resolve(data.selected_folder); From 7a258c74f025ea5cd943115d363b25267e0b7e7f Mon Sep 17 00:00:00 2001 From: Ash Martian Date: Tue, 28 May 2024 17:51:16 -0700 Subject: [PATCH 3/5] bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 622ada4..fb374bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-dirgir" description = "A collection of ComfyUI directory automation utility nodes. Directory Get It Right adds a GUI directory browser, and smart directory loop/iteration node that supports regex and file extension filtering." -version = "1.0.0" +version = "1.0.1" license = "LICENSE" dependencies = ["aiohttp", "tk"] From 9ff10f9e5ead8c2eedcda64b1c9088ae728e9314 Mon Sep 17 00:00:00 2001 From: Ash Martian Date: Tue, 28 May 2024 17:51:56 -0700 Subject: [PATCH 4/5] Fix ComfyUI Craftsman link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 378d286..d4bfb57 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Utility nodes to get directories right in ComfyUI. Ever want to select a random ![Scoot](docs/GIR_scoot.gif) -To create this custom node pack, I uploaded the sparse ComfyUI documentation, a few custom node sources, and app js source code to an OpenAi GPTs [ComfyUI Craftsman](https://chat.openai.com/g/g-pYtHuQdGh-comfyui-craftsman]), this GPTs is good at answering questions and offering guidance based on real ComfyUI implementations. +To create this custom node pack, I uploaded the sparse ComfyUI documentation, a few custom node sources, and app js source code to an OpenAi GPTs [ComfyUI Craftsman](https://chat.openai.com/g/g-pYtHuQdGh-comfyui-craftsman), this GPTs is good at answering questions and offering guidance based on real ComfyUI implementations. ## Installation From 348f8eb28a15809fa25bfb0b00d906457f203715 Mon Sep 17 00:00:00 2001 From: Ash Martian Date: Tue, 28 May 2024 17:54:14 -0700 Subject: [PATCH 5/5] Cleanup console logs --- web/js/gir.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/js/gir.js b/web/js/gir.js index c440e21..b749a2b 100644 --- a/web/js/gir.js +++ b/web/js/gir.js @@ -125,8 +125,7 @@ app.registerExtension({ // Add a text element to the node that displays the selected directory element.innerHTML = directory; if(!hasTk) { - console.log('Tkinter not installed'); - console.log(widget) + console.error('Tkinter not installed'); } node.setOutputData("directory", directory); node.onResize?.(node.size); @@ -145,7 +144,6 @@ app.registerExtension({ node.setOutputData("directory", directory); node.widgets.filter(w => w.name === "Selected Directory").forEach(w => w.value = directory); if (!hasTk) { - console.log('Tkinter not installed'); node.widgets.filter(w => w.name === "Select Directory").forEach(w => w.disabled = true) } }