From 81e79107e14fc1ef9464a054d35194d77e143534 Mon Sep 17 00:00:00 2001 From: yoinked Date: Fri, 20 Jun 2025 04:44:23 +0000 Subject: [PATCH 1/3] add some more string nodes --- comfy_extras/nodes_string.py | 71 +++++++++++++++++++++++++++++++++++- folder_paths.py | 2 +- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/comfy_extras/nodes_string.py b/comfy_extras/nodes_string.py index b1a8ceef0..8f0b194b3 100644 --- a/comfy_extras/nodes_string.py +++ b/comfy_extras/nodes_string.py @@ -1,5 +1,7 @@ import re - +import os +import torch +import folder_paths from comfy.comfy_types.node_typing import IO class StringConcatenate(): @@ -331,6 +333,69 @@ class RegexReplace(): result = re.sub(regex_pattern, replace, string, count=count, flags=flags) return result, +class LoadText(): + DESCRIPTION = "Load a string from a file." + @classmethod + def INPUT_TYPES(s): + input_dir = folder_paths.get_input_directory() + files = [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f))] + files = folder_paths.filter_files_content_types(files, ["text"]) + return { + "required": {"file": (sorted(files), {"text_upload": True})}, + } + + RETURN_TYPES = (IO.STRING,) + FUNCTION = "execute" + CATEGORY = "utils/string" + + def execute(self, file): + text_path = folder_paths.get_annotated_filepath(file) + string = open(text_path, 'r', encoding='utf-8').read() #enforcing utf-8 is odd, good enough + return (string,) + + @classmethod + def IS_CHANGED(cls, file): + text_path = folder_paths.get_annotated_filepath(file) + mod_time = os.path.getmtime(text_path) + # use mod time (inspired by video nodes) + return mod_time + + @classmethod + def VALIDATE_INPUTS(cls, file): + if not folder_paths.exists_annotated_filepath(file): + return "Invalid text file: {}".format(file) + + return True + +class GetRandomLine(): + DESCRIPTION = "Obtain a random line from a multiline string." + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "text": (IO.STRING, {"multiline": True, "default": ""}), + "seed": (IO.INT, {"default": 0, + "min": 0, + "max": 2147483647, + "step": 1, + "control_after_generate": True, + "display": "number"},) + } + } + + RETURN_TYPES = (IO.STRING,) + FUNCTION = "execute" + CATEGORY = "utils/string" + + def execute(self, text, seed=0): + generator = torch.Generator() + generator.manual_seed(seed) + lines = text.splitlines() + max_lines = len(lines) + idx = torch.randint(0, max_lines, (1,), generator=generator).item() + return (lines[idx],) + + NODE_CLASS_MAPPINGS = { "StringConcatenate": StringConcatenate, "StringSubstring": StringSubstring, @@ -343,6 +408,8 @@ NODE_CLASS_MAPPINGS = { "RegexMatch": RegexMatch, "RegexExtract": RegexExtract, "RegexReplace": RegexReplace, + "LoadText": LoadText, + "GetRandomLine": GetRandomLine } NODE_DISPLAY_NAME_MAPPINGS = { @@ -357,4 +424,6 @@ NODE_DISPLAY_NAME_MAPPINGS = { "RegexMatch": "Regex Match", "RegexExtract": "Regex Extract", "RegexReplace": "Regex Replace", + "LoadText": "Load Text", + "GetRandomLine": "Get Random Line" } diff --git a/folder_paths.py b/folder_paths.py index 9ec952940..1665de586 100644 --- a/folder_paths.py +++ b/folder_paths.py @@ -141,7 +141,7 @@ def get_directory_by_type(type_name: str) -> str | None: return get_input_directory() return None -def filter_files_content_types(files: list[str], content_types: List[Literal["image", "video", "audio", "model"]]) -> list[str]: +def filter_files_content_types(files: list[str], content_types: List[Literal["image", "video", "audio", "model", "text"]]) -> list[str]: """ Example: files = os.listdir(folder_paths.get_input_directory()) From e877471dfd5046b410ad9f818bea97aef743e73f Mon Sep 17 00:00:00 2001 From: yoinked Date: Fri, 20 Jun 2025 04:58:21 +0000 Subject: [PATCH 2/3] fix linting --- comfy_extras/nodes_string.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/comfy_extras/nodes_string.py b/comfy_extras/nodes_string.py index 8f0b194b3..e3a916d70 100644 --- a/comfy_extras/nodes_string.py +++ b/comfy_extras/nodes_string.py @@ -377,8 +377,8 @@ class GetRandomLine(): "seed": (IO.INT, {"default": 0, "min": 0, "max": 2147483647, - "step": 1, - "control_after_generate": True, + "step": 1, + "control_after_generate": True, "display": "number"},) } } From 5162e9094816f6df23f27643c7a04a8494d38e8f Mon Sep 17 00:00:00 2001 From: yoinked Date: Fri, 20 Jun 2025 05:08:55 +0000 Subject: [PATCH 3/3] remove randline since PR exists --- comfy_extras/nodes_string.py | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/comfy_extras/nodes_string.py b/comfy_extras/nodes_string.py index e3a916d70..278d922de 100644 --- a/comfy_extras/nodes_string.py +++ b/comfy_extras/nodes_string.py @@ -1,6 +1,5 @@ import re import os -import torch import folder_paths from comfy.comfy_types.node_typing import IO @@ -367,35 +366,6 @@ class LoadText(): return True -class GetRandomLine(): - DESCRIPTION = "Obtain a random line from a multiline string." - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "text": (IO.STRING, {"multiline": True, "default": ""}), - "seed": (IO.INT, {"default": 0, - "min": 0, - "max": 2147483647, - "step": 1, - "control_after_generate": True, - "display": "number"},) - } - } - - RETURN_TYPES = (IO.STRING,) - FUNCTION = "execute" - CATEGORY = "utils/string" - - def execute(self, text, seed=0): - generator = torch.Generator() - generator.manual_seed(seed) - lines = text.splitlines() - max_lines = len(lines) - idx = torch.randint(0, max_lines, (1,), generator=generator).item() - return (lines[idx],) - - NODE_CLASS_MAPPINGS = { "StringConcatenate": StringConcatenate, "StringSubstring": StringSubstring, @@ -408,8 +378,7 @@ NODE_CLASS_MAPPINGS = { "RegexMatch": RegexMatch, "RegexExtract": RegexExtract, "RegexReplace": RegexReplace, - "LoadText": LoadText, - "GetRandomLine": GetRandomLine + "LoadText": LoadText } NODE_DISPLAY_NAME_MAPPINGS = { @@ -424,6 +393,5 @@ NODE_DISPLAY_NAME_MAPPINGS = { "RegexMatch": "Regex Match", "RegexExtract": "Regex Extract", "RegexReplace": "Regex Replace", - "LoadText": "Load Text", - "GetRandomLine": "Get Random Line" + "LoadText": "Load Text" }