140 lines
3.8 KiB
Python
140 lines
3.8 KiB
Python
import os
|
|
import sys
|
|
import threading
|
|
import socket
|
|
import time
|
|
import subprocess
|
|
from typing import Optional
|
|
|
|
# ComfyUI server (aiohttp) hooks
|
|
from server import PromptServer
|
|
|
|
|
|
_LOCK = threading.Lock()
|
|
_THREAD: Optional[threading.Thread] = None
|
|
|
|
# You can change this if you want
|
|
DEFAULT_HOST = "127.0.0.1"
|
|
DEFAULT_PORT = 7860
|
|
|
|
|
|
def _is_port_open(host: str, port: int, timeout: float = 0.25) -> bool:
|
|
try:
|
|
with socket.create_connection((host, port), timeout=timeout):
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
def _pick_port(host: str, preferred: int) -> int:
|
|
# If preferred is free, use it. Otherwise scan a small range.
|
|
if not _is_port_open(host, preferred):
|
|
return preferred
|
|
for p in range(preferred + 1, preferred + 50):
|
|
if not _is_port_open(host, p):
|
|
return p
|
|
return preferred
|
|
|
|
|
|
def _run_gradio_server(host: str, port: int):
|
|
"""
|
|
Runs your existing workflow_to_html_generator.py Gradio app
|
|
inside this ComfyUI process (thread).
|
|
"""
|
|
try:
|
|
# Import your file that you copied into this custom node folder
|
|
import workflow_to_html_generator as gen
|
|
|
|
iface = gen.create_interface()
|
|
|
|
# queue() is fine; it's what you do in __main__
|
|
try:
|
|
iface.queue()
|
|
except Exception:
|
|
pass
|
|
|
|
iface.launch(
|
|
server_name=host,
|
|
server_port=port,
|
|
share=False,
|
|
inbrowser=False,
|
|
prevent_thread_lock=True,
|
|
)
|
|
except Exception as e:
|
|
print(f"[WebUI-Generator-Node] Failed to start generator: {e}", file=sys.stderr)
|
|
|
|
|
|
def ensure_generator_running():
|
|
"""
|
|
Starts the generator once (idempotent).
|
|
"""
|
|
global _THREAD
|
|
|
|
with _LOCK:
|
|
if _THREAD and _THREAD.is_alive():
|
|
return
|
|
|
|
host = os.environ.get("COMFY_WEBUI_GEN_HOST", DEFAULT_HOST)
|
|
preferred_port = int(os.environ.get("COMFY_WEBUI_GEN_PORT", str(DEFAULT_PORT)))
|
|
port = _pick_port(host, preferred_port)
|
|
|
|
os.environ["COMFY_WEBUI_GEN_EFFECTIVE_PORT"] = str(port)
|
|
|
|
t = threading.Thread(
|
|
target=_run_gradio_server,
|
|
args=(host, port),
|
|
daemon=True,
|
|
name="ComfyUI-WebUI-Generator-Gradio",
|
|
)
|
|
t.start()
|
|
_THREAD = t
|
|
|
|
|
|
def _open_path_in_explorer(path: str):
|
|
"""
|
|
Cross-platform folder open.
|
|
"""
|
|
path = os.path.abspath(path)
|
|
|
|
if sys.platform.startswith("win"):
|
|
os.startfile(path) # type: ignore[attr-defined]
|
|
elif sys.platform == "darwin":
|
|
subprocess.Popen(["open", path])
|
|
else:
|
|
subprocess.Popen(["xdg-open", path])
|
|
|
|
|
|
# -------------------------
|
|
# ComfyUI HTTP routes
|
|
# -------------------------
|
|
|
|
@PromptServer.instance.routes.get("/webui-generator/info")
|
|
async def webui_generator_info(request):
|
|
ensure_generator_running()
|
|
host = os.environ.get("COMFY_WEBUI_GEN_HOST", DEFAULT_HOST)
|
|
port = os.environ.get("COMFY_WEBUI_GEN_EFFECTIVE_PORT", str(DEFAULT_PORT))
|
|
return PromptServer.instance.json_response({
|
|
"host": host,
|
|
"port": int(port),
|
|
"url": f"http://{host}:{port}"
|
|
})
|
|
|
|
|
|
@PromptServer.instance.routes.post("/webui-generator/open-output")
|
|
async def webui_generator_open_output(request):
|
|
"""
|
|
Opens ComfyUI's output dir (or a custom one if you want later).
|
|
"""
|
|
try:
|
|
comfy_root = os.path.dirname(os.path.abspath(sys.argv[0]))
|
|
output_dir = os.path.join(comfy_root, "output")
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
_open_path_in_explorer(output_dir)
|
|
return PromptServer.instance.json_response({"ok": True, "path": output_dir})
|
|
except Exception as e:
|
|
return PromptServer.instance.json_response({"ok": False, "error": str(e)}, status=500)
|
|
|
|
|
|
# Start generator automatically when the custom node is imported (ComfyUI startup)
|
|
ensure_generator_running()
|