Files
2026-03-30 06:19:17 +00:00

88 lines
2.9 KiB
Python

from comfy.comfy_types import IO, ComfyNodeABC, InputTypeDict
import json
class ExtractMetadataText(ComfyNodeABC):
DESCRIPTION = """Extract text from supported text nodes in workflow metadata.
Pass the workflow metadata string from LoadImageWithMetadata node
and optionally specify the node ID.
Supported text nodes include CLIP Text Encode (Prompt), Display Any (rgthree),
and Show Any (comfyui-easy-use).
"""
CATEGORY = "image/text"
@classmethod
def INPUT_TYPES(s) -> InputTypeDict:
return {
"required": {
"workflow_metadata": (IO.STRING, {"tooltip": "ComfyUI workflow metadata string from LoadImageWithMetadata node"}),
},
"optional": {
"node_id": (IO.INT, {"default": 0, "tooltip": "Node ID of the text node (0 for auto-detect)"}),
}
}
RETURN_TYPES = (IO.STRING,)
RETURN_NAMES = ("extracted_text",)
FUNCTION = "extract"
def extract(self, workflow_metadata, node_id=0):
"""Extract text from supported text nodes in workflow metadata."""
# Parse workflow JSON
try:
workflow = json.loads(workflow_metadata)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON in workflow metadata: {e}")
# Find supported nodes
if node_id <= 0:
# Auto-detect single supported node
display_nodes = []
for node in workflow.get("nodes", []):
if node.get("type") in (
"CLIPTextEncode",
"Display Any (rgthree)",
"easy showAnything",
):
display_nodes.append(node["id"])
if len(display_nodes) != 1:
raise ValueError(
f"Found {len(display_nodes)} compatible nodes: {display_nodes}. "
"Specify node_id to choose one."
)
node_id = display_nodes[0]
# Get node data
node = None
nodes = workflow.get("nodes", {})
for n in nodes:
if n.get("id") == node_id:
node = n
break
if node is None:
raise ValueError(f"Node {node_id} not found in workflow")
# Extract widgets_values
widgets_values = node.get("widgets_values", [])
if len(widgets_values) != 1:
raise ValueError(
f"Node {node_id} has {len(widgets_values)} widget values. "
"Expected exactly one text field."
)
ret = widgets_values[0]
# Show Any (comfyui-easy-use) node stores the text inside an extra
# layer of list (Display Any (rgthree) does not do this). Unpack it if
# it is the only entry - anything more complex we will leave to the
# user to deal with:
if isinstance(ret, list) and len(ret) == 1:
ret = ret[0]
return (ret,)