88 lines
2.9 KiB
Python
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,)
|