109 lines
4.0 KiB
Python
109 lines
4.0 KiB
Python
import uuid
|
|
from pathlib import Path
|
|
from aiohttp import web
|
|
|
|
import folder_paths
|
|
from server import PromptServer
|
|
from comfy_execution.graph import ExecutionBlocker
|
|
|
|
|
|
TEMP_SUBFOLDER = "minimal-pause-signals"
|
|
|
|
class AlwaysEqualProxy(str):
|
|
def __eq__(self, _):
|
|
return True
|
|
|
|
def __ne__(self, _):
|
|
return False
|
|
|
|
any_type = AlwaysEqualProxy("*")
|
|
|
|
# --- Helper to get signal file path ---
|
|
def get_signal_file_path(node_id: str) -> Path:
|
|
"""Gets the path for this node's signal file."""
|
|
temp_dir = Path(folder_paths.get_temp_directory())
|
|
signal_dir = temp_dir / TEMP_SUBFOLDER
|
|
signal_dir.mkdir(parents=True, exist_ok=True)
|
|
# File existence signals "continue"
|
|
return signal_dir / f"continue_{node_id}.signal"
|
|
|
|
# --- HTTP Route ---
|
|
if hasattr(PromptServer, 'instance') and PromptServer.instance is not None:
|
|
routes = PromptServer.instance.routes
|
|
@routes.post('/minimal_pause/signal_continue')
|
|
async def signal_continue_handler(request: web.Request) -> web.Response:
|
|
"""Creates the signal file to allow the node to continue."""
|
|
try:
|
|
# No JSON needed, just check for node_id in query or form data? Let's use JSON.
|
|
if request.content_type != 'application/json':
|
|
return web.json_response({"status": "error", "message": "Invalid content type"}, status=400)
|
|
data = await request.json()
|
|
node_id = data.get('node_id')
|
|
|
|
if not node_id:
|
|
return web.json_response({"status": "error", "message": "node_id missing"}, status=400)
|
|
|
|
signal_file = get_signal_file_path(node_id)
|
|
|
|
try:
|
|
# Create an empty file to signal continuation
|
|
signal_file.touch(exist_ok=True) # Create if doesn't exist, update timestamp if does
|
|
|
|
return web.json_response({"status": "ok", "message": "Continue signal sent."})
|
|
except IOError as e:
|
|
|
|
return web.json_response({"status": "error", "message": f"Failed to create signal file: {e}"}, status=500)
|
|
except Exception as e:
|
|
|
|
return web.json_response({"status": "error", "message": "Internal server error"}, status=500)
|
|
|
|
|
|
class MinimalPauseNode:
|
|
"""A node that simply pauses workflow execution until continued via UI."""
|
|
|
|
# Force execution so the file check always runs
|
|
@classmethod
|
|
def IS_CHANGED(cls, *args, **kwargs):
|
|
return str(uuid.uuid4())
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
# Takes any input type just to allow connection, but doesn't use it
|
|
return {
|
|
"required": {
|
|
"any": (any_type, {}), # Use Comfy's AnyType wildcard
|
|
},
|
|
"hidden": {
|
|
"prompt": "PROMPT",
|
|
"extra_pnginfo": "EXTRA_PNGINFO",
|
|
"unique_id": "UNIQUE_ID",
|
|
},
|
|
}
|
|
|
|
# Returns the same type it received
|
|
RETURN_TYPES = (any_type,)
|
|
RETURN_NAMES = ("any",)
|
|
FUNCTION = "pause_or_continue"
|
|
CATEGORY = "🎤MW/MW-Audio-Tools" # Simple category
|
|
OUTPUT_NODE = True # Passes data through
|
|
|
|
def pause_or_continue(self, any, unique_id: str, prompt=None, extra_pnginfo=None, **kwargs):
|
|
node_id = unique_id
|
|
|
|
signal_file = get_signal_file_path(node_id)
|
|
|
|
if signal_file.exists():
|
|
# Signal file exists - User clicked Continue
|
|
try:
|
|
signal_file.unlink() # Delete the signal file to reset for next time
|
|
except OSError as e:
|
|
print(f"Failed to delete signal file: {e}")
|
|
# Return the any data
|
|
return {"result": (any,)}
|
|
else:
|
|
# Send message to UI to enable the button
|
|
if hasattr(PromptServer, 'instance') and PromptServer.instance is not None:
|
|
PromptServer.instance.send_sync("minimal_pause_enable_button", { "node_id": node_id })
|
|
# Return ExecutionBlocker for the any output
|
|
return {"result": (ExecutionBlocker(None),)}
|