# pyright: reportArgumentType=false import os import json from server import PromptServer from aiohttp import web # --- Constants --- NODE_DIR = os.path.dirname(os.path.abspath(__file__)) LABELS_FILE = os.path.join(NODE_DIR, "switch_any_labels.json") MAX_INPUTS = 10 # 允许的标签最大绝对数量 # --- Helper Functions for File I/O --- def read_labels_from_file(): """从JSON文件中读取标签列表。""" if not os.path.exists(LABELS_FILE): return [] try: with open(LABELS_FILE, "r", encoding="utf-8") as f: labels = json.load(f) return labels if isinstance(labels, list) else [] except (IOError, json.JSONDecodeError): return [] def write_labels_to_file(labels): """将给定的标签列表保存到JSON文件中。""" try: # 过滤空字符串和空白字符串,保持原始顺序和重复项 filtered_labels = [label for label in labels if label and str(label).strip()] existing_labels = read_labels_from_file() if filtered_labels != existing_labels: with open(LABELS_FILE, "w", encoding="utf-8") as f: json.dump(filtered_labels, f, indent=2) except IOError as e: print(f"[Switch Any] ERROR: Could not write labels to file: {e}") # --- Custom Node Definition --- class SwitchAny: """ 一个用于定义和选择标签以进行路由的节点。 输入字段的数量会随着您添加更多标签而增加。 使用 'Save & Refresh UI' 按钮来保存更改并更新界面。 """ @classmethod def INPUT_TYPES(cls): saved_labels = read_labels_from_file() dropdown_labels = saved_labels if saved_labels else [""] inputs = { "required": { "select_label": (dropdown_labels, ), }, "optional": {} } # 总是显示MAX_INPUTS个输入框,确保工作流迁移时状态完整 for i in range(1, MAX_INPUTS + 1): default_value = saved_labels[i-1] if i <= len(saved_labels) else "" inputs["optional"][f"label_{i}"] = ("STRING", { "default": default_value, "multiline": False, "placeholder": f"Label for index {i}" }) return inputs RETURN_TYPES = ("INT", "STRING") RETURN_NAMES = ("index", "label") FUNCTION = "execute" CATEGORY = "ComfyUI_Switch" def execute(self, select_label, **kwargs): # 此方法在工作流运行时触发,确保标签也被保存 current_labels_from_inputs = [] for i in range(1, MAX_INPUTS + 1): label = kwargs.get(f"label_{i}", "").strip() if label: current_labels_from_inputs.append(label) write_labels_to_file(current_labels_from_inputs) # 确定输出 final_labels = read_labels_from_file() output_index = 0 output_label = "" if select_label in final_labels: output_index = final_labels.index(select_label) + 1 output_label = select_label return (output_index, output_label) # --- API Route for Saving Labels --- @PromptServer.instance.routes.post("/switch_any/save_labels") async def save_labels_route(request): data = await request.json() labels = data.get("labels", []) if isinstance(labels, list): try: write_labels_to_file(labels) return web.json_response({"status": "ok", "message": "Labels saved."}) except Exception as e: return web.json_response({"status": "error", "message": str(e)}, status=500) return web.json_response({"status": "error", "message": "Invalid data format, 'labels' must be a list."}, status=400) # --- Node Registration --- NODE_CLASS_MAPPINGS = { "SwitchAny": SwitchAny } NODE_DISPLAY_NAME_MAPPINGS = { "SwitchAny": "Switch Any" } # --- Web Directory Setup for JS file --- WEB_DIRECTORY = "js"