From 2b70e75067dfd84169a596632c54ad8ad3e6ea5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E9=9B=AA=E5=B3=B0?= Date: Sun, 1 Dec 2024 21:58:48 +0800 Subject: [PATCH] add read and save text nodes --- README.md | 5 ++++ easyapi/ForEachNode.py | 5 +++- easyapi/UtilNode.py | 68 ++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- requirements.txt | 1 + 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index df6d5c5..9f7f2fd 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ Tips: base64格式字符串比较长,会导致界面卡顿,接口请求带 | × | SaveSingleImageWithoutOutput | 保存单个图像到指定目录,不是输出类型节点,可用于循环批量跑图和作为惰性求值的前置节点 | | × | CropTargetSizeImageByBbox | 以bbox区域中心向外裁剪指定宽高图片 | | × | ConvertToJsonStr | 序列化为json字符串 | +| × | SaveTextToLocalFile | 保存文本到本地文件 | +| × | ReadTextFromLocalFile | 从本地文件读取文本 | ### 示例 ![save api extended](docs/example_note.png) @@ -96,6 +98,9 @@ Tips: base64格式字符串比较长,会导致界面卡顿,接口请求带 ![批量裁剪打标](example/example_image_crop_tag.png) ## 更新记录 +### 2024-12-01 (v1.1.0) +- 新增节点:SaveTextToLocalFile、 ReadTextFromLocalFile + ### 2024-11-04 (v1.0.9) - 新增节点:SamAutoMaskSEGSAdvanced、 MaskToRle、 RleToMask、 ConvertToJsonStr diff --git a/easyapi/ForEachNode.py b/easyapi/ForEachNode.py index c37423c..a91f9dc 100644 --- a/easyapi/ForEachNode.py +++ b/easyapi/ForEachNode.py @@ -156,7 +156,7 @@ def while_loop_close(self, flow_control, condition, dynprompt=None, unique_id=No for i in range(NUM_FLOW_SOCKETS): key = "initial_value%d" % i new_open.set_input(key, kwargs.get(key, None)) - my_clone = graph.lookup_node("Recurse" ) + my_clone = graph.lookup_node("Recurse") result = map(lambda x: my_clone.out(x), range(NUM_FLOW_SOCKETS)) return { "result": tuple(result), @@ -204,6 +204,9 @@ def INPUT_TYPES(cls): CATEGORY = "EasyApi/Logic" def for_loop_open(self, total, **kwargs): + if total is None or total <= 0: + raise ValueError("Total must be greater than 0.") + graph = GraphBuilder() if "initial_value0" in kwargs: diff --git a/easyapi/UtilNode.py b/easyapi/UtilNode.py index 28771db..670f99c 100644 --- a/easyapi/UtilNode.py +++ b/easyapi/UtilNode.py @@ -899,6 +899,70 @@ def execute(self, image_path, text): return (txt_path,) +class SaveTextToLocalFile: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "text_path": ("STRING", {"forceInput": False, "tooltip": "保存的文件全路径,不会自动创建文件目录"}), + "text": ("STRING", {"forceInput": False, "dynamicPrompts": False, "multiline": True}), + } + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("text_path",) + FUNCTION = "execute" + CATEGORY = "EasyApi/Utils" + DESCRIPTION = "把文本内容保存指定文件中" + + def execute(self, text_path, text): + # 路径需要存在 + dir_name = os.path.dirname(text_path) + if not os.path.isdir(dir_name): + raise FileNotFoundError(f"dir not found: {dir_name}") + + # 写入文本内容到文件 + with open(text_path, 'w', encoding='utf-8') as file: + file.write(text) + + return (text_path,) + + +class ReadTextFromLocalFile: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "text_path": ("STRING", {"forceInput": False}), + } + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("text",) + FUNCTION = "execute" + CATEGORY = "EasyApi/Utils" + DESCRIPTION = "把文本内容保存到图片路径同名的txt文件中" + + def execute(self, text_path): + if not os.path.isfile(text_path): + raise FileNotFoundError(f"file not found: {text_path}") + + # 获取文件的 MIME 类型 + mime_type, _ = mimetypes.guess_type(text_path) + + if mime_type is None or (not mime_type.startswith('text/') and mime_type != 'application/json'): + raise ValueError(f"Unsupported file type: {mime_type}") + + # 读取文本内容 + try: + with open(text_path, 'r', encoding='utf-8') as file: + text = file.read() + except Exception as e: + raise ValueError(f"Error reading file: {e}") + + return (text,) + + class CopyAndRenameFiles: @classmethod def INPUT_TYPES(s): @@ -999,6 +1063,8 @@ def execute(self, directory, save_directory, prefix, name_to_num): "EmptyOutputNode": EmptyOutputNode, "SaveTextToFileByImagePath": SaveTextToFileByImagePath, "CopyAndRenameFiles": CopyAndRenameFiles, + "SaveTextToLocalFile": SaveTextToLocalFile, + "ReadTextFromLocalFile": ReadTextFromLocalFile, } # A dictionary that contains the friendly/humanly readable titles for the nodes @@ -1035,4 +1101,6 @@ def execute(self, directory, save_directory, prefix, name_to_num): "EmptyOutputNode": "EmptyOutputNode", "SaveTextToFileByImagePath": "SaveTextToFileByImagePath", "CopyAndRenameFiles": "CopyAndRenameFiles", + "SaveTextToLocalFile": "SaveTextToLocalFile", + "ReadTextFromLocalFile": "ReadTextFromLocalFile", } diff --git a/pyproject.toml b/pyproject.toml index 9516c88..271be6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-easyapi-nodes" description = "Provides some features and nodes related to API calls. 开发独立应用调用ComfyUI服务的一些补充节点。" -version = "1.0.9" +version = "1.1.0" license = { file = "LICENSE" } dependencies = ["segment_anything", "simple_lama_inpainting", "insightface", "simplejson"] diff --git a/requirements.txt b/requirements.txt index c22b7bb..68526b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ segment_anything simple_lama_inpainting insightface simplejson +pycocotools