增加String Translate节点,String List支持循环选取

This commit is contained in:
liuqianhonga
2025-01-02 15:22:47 +08:00
parent bfa6b7a403
commit 32794fa30f
3 changed files with 151 additions and 58 deletions
+68 -27
View File
@@ -73,56 +73,63 @@ arg1: "世界"
## StringList 节点使用说明
StringList 节点允许你灵活地选择和翻译字符串。你可以通过手动输入、随机选择或指定编号选择字符串,并可选地将其翻译为英文。
StringList 节点允许你灵活地选择和翻译字符串。你可以通过手动输入、随机选择、顺序循环或指定编号选择字符串,并可选地将其翻译为英文。
### 节点参数
- **random_select_count** (必需):随机选择字符串的数量。特殊值:
- **p1_select_by_numbers** (可选):最高优先级,通过输入序号(如 "1,3,5")选择指定位置的字符串
- **p2_select_sequential** (可选):第二优先级,布尔值,默认为 `False`。启用后,每次调用按顺序返回下一个字符串,到达列表末尾后自动从头开始
- **p3_select_random_count** (必需):最低优先级,随机选择字符串的数量。特殊值:
- `-1`:返回所有输入字符串
- `0`:返回空列表
- `1-10`:随机选择指定数量的字符串
- **selected_numbers** (可选):指定要选择的字符串编号,多个编号用逗号分隔,如"1,3,5"。当此字段有值时,`random_select_count` 失效
- **translate_output** (可选):布尔值,默认为 `False`。启用后,将选定的字符串从自动检测的语言翻译为英文
- **string1** - **string10** (必需):多行字符串输入字段,用于手动输入字符串
- **string_list** (可选):额外的字符串列表输入,用于合并外部字符串列表
### 使用示例
1. 随机选择字符串:
1. 按序号选择字符串(最高优先级):
```python
random_select_count: 3
translate_output: False
p1_select_by_numbers: "1,3,5"
string1: "你好"
string2: "世界"
string3: "欢迎"
string4: "使用"
string5: "ComfyUI"
输出: ["你好", "欢迎", "ComfyUI"]
```
2. 顺序循环选择(第二优先级):
```python
p2_select_sequential: True
string1: "第一个"
string2: "第二个"
string3: "第三个"
第一次输出: ["第一个"]
第二次输出: ["第二个"]
第三次输出: ["第三个"]
第四次输出: ["第一个"] # 自动从头开始
```
3. 随机选择字符串(最低优先级):
```python
p3_select_random_count: 3
string1: "你好"
string2: "世界"
string3: "欢迎"
string4: "使用"
string5: "ComfyUI"
输出: 随机选择3个字符串
```
2. 指定编号选择字符串:
4. 启用翻译:
```python
selected_numbers: "1,3"
p1_select_by_numbers: "1,2"
translate_output: True
string1: "你好"
string2: "世界"
string3: "欢迎"
输出: ["Hello", "Welcome"]
```
2. 指定编号选择字符串:
```python
selected_numbers: "1,3"
translate_output: False
string1: "你好"
string2: "世界"
string3: "欢迎"
输出: ["你好", "欢迎"]
```
3. 使用外部字符串列表:
```python
random_select_count: 2
string_list: ["额外1", "额外2"]
输出: 随机选择2个字符串并合并外部列表
输出: ["hello", "world"]
```
## StringListFromCSV 节点使用说明
@@ -410,3 +417,37 @@ target_type: "DICT"
- 不会返回默认值,确保数据的准确性
- 对于LIST类型,空字符串会返回空列表
- 对于DICT类型,输入必须是有效的JSON格式字符串
## String Translate 节点使用说明
String Translate 节点提供单独的字符串翻译功能,可以将输入的字符串翻译为英文。
### 节点参数
- **string** (必需):要翻译的字符串
- **translate_output** (必需):布尔值,默认为 `False`。控制是否执行翻译:
- `False`:直接返回原字符串
- `True`:将字符串翻译为英文
### 使用示例
1. 基础翻译:
```python
string: "你好,世界"
translate_output: True
输出: "Hello, world"
```
2. 不执行翻译:
```python
string: "你好,世界"
translate_output: False
输出: "你好,世界"
```
### 特点
- 支持自动语言检测
- 使用必应翻译服务
- 适合单个字符串的快速翻译
- 与 StringList/StringListFromCSV 节点的翻译功能相同
+3 -1
View File
@@ -1,5 +1,5 @@
from .nodes.string_formatter import StringFormatter
from .nodes.string_list import StringList, StringListFromCSV, StringListToCSV, JsonToCSV
from .nodes.string_list import StringTranslate, StringList, StringListFromCSV, StringListToCSV, JsonToCSV
from .nodes.show_translate_string import ShowTranslateString
from .nodes.string_matcher import StringMatcher
from .nodes.time_formatter import TimeFormatter
@@ -7,6 +7,7 @@ from .nodes.string_converter import StringConverter
NODE_CLASS_MAPPINGS = {
"StringFormatter": StringFormatter,
"StringTranslate": StringTranslate,
"StringList": StringList,
"StringListFromCSV": StringListFromCSV,
"StringListToCSV": StringListToCSV,
@@ -19,6 +20,7 @@ NODE_CLASS_MAPPINGS = {
NODE_DISPLAY_NAME_MAPPINGS = {
"StringFormatter": "🐟String Formatter",
"StringTranslate": "🐟String Translate",
"StringList": "🐟String List",
"StringListFromCSV": "🐟String List From CSV",
"StringListToCSV": "🐟String List To CSV",
+80 -30
View File
@@ -6,11 +6,9 @@ from ..translation_utils import TranslationUtils
class BaseStringList:
"""Base class for string list operations"""
RETURN_TYPES = ("LIST", "STRING",)
RETURN_NAMES = ("string_list", "strings",)
FUNCTION = "process"
CATEGORY = "String Helper"
def __init__(self):
self.current_index = 0
@staticmethod
def get_encoding(csv_path):
@@ -53,7 +51,7 @@ class BaseStringList:
Args:
csv_file: Path to the CSV file
rows_to_write: List of dictionaries with keys 'string', 'zh'/'translate_string', and 'tags'
rows_to_write: List of dictionaries with keys 'string', 'zh', and 'tags'
append_mode: Whether to append to existing file
check_duplicates: Whether to check and skip duplicate strings
@@ -127,27 +125,44 @@ class BaseStringList:
print("Invalid number format. Please use comma-separated numbers (e.g., '1,3,5')")
return []
def process_string_selection(self, input_strings, random_select_count, selected_numbers, translate_output, string_list=None):
"""Process string selection with common logic"""
def process_string_selection(self, input_strings, p3_select_random_count, p1_select_by_numbers, translate_output, p2_select_sequential=False, string_list=None):
"""Process string selection with common logic
Args:
input_strings: List of input strings to select from
p1_select_by_numbers: Priority 1 - Select strings by their numbers (comma-separated)
p2_select_sequential: Priority 2 - Select strings sequentially
p3_select_random_count: Priority 3 - Number of strings to select randomly
translate_output: Whether to translate the selected strings
string_list: Optional additional strings to append
"""
# Early return if no input strings
if not input_strings:
return ([], [])
# Process string selection
if selected_numbers.strip():
# Use selected numbers if provided
selected_input_strings = self.get_selected_strings(input_strings, selected_numbers)
if p1_select_by_numbers.strip():
# Use selected numbers if provided (highest priority)
selected_input_strings = self.get_selected_strings(input_strings, p1_select_by_numbers)
elif p2_select_sequential:
# Use sequential selection if enabled (second priority)
if not input_strings:
selected_input_strings = []
else:
selected_input_strings = [input_strings[self.current_index]]
# Update index for next selection
self.current_index = (self.current_index + 1) % len(input_strings)
else:
# Otherwise use random selection
if random_select_count == -1:
# Otherwise use random selection (lowest priority)
if p3_select_random_count == -1:
# Use all input strings
selected_input_strings = input_strings
elif random_select_count == 0:
elif p3_select_random_count == 0:
# Select none
selected_input_strings = []
else:
# Randomly select specified number of strings
count = min(random_select_count, len(input_strings))
count = min(p3_select_random_count, len(input_strings))
selected_input_strings = random.sample(input_strings, count)
# Combine with optional string_list if provided
@@ -164,23 +179,46 @@ class BaseStringList:
# Return the same list for both outputs
return (final_strings, final_strings)
class StringTranslate(BaseStringList):
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"translate_output": ("BOOLEAN", {"default": False}),
"string": ("STRING", {"multiline": True}),
}
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("string",)
FUNCTION = "process_string"
CATEGORY = "String Helper"
def process_string(self, string, translate_output):
if translate_output:
final_strings = self.translate_strings(string)
return (final_strings,)
return (string,)
class StringList(BaseStringList):
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"random_select_count": ("INT", {
"p1_select_by_numbers": ("STRING", {
"default": "",
"placeholder": "Priority 1: Comma-separated numbers (e.g. 1,3,5)"
}),
"p2_select_sequential": ("BOOLEAN", {
"default": False,
}),
"p3_select_random_count": ("INT", {
"default": -1,
"min": -1,
"max": 10,
"step": 1,
"display": "number"
}),
"selected_numbers": ("STRING", {
"default": "",
"placeholder": "e.g. 1,3,5 (leave empty to use random_select_count)"
}),
"translate_output": ("BOOLEAN", {
"default": False,
}),
@@ -240,15 +278,17 @@ class StringList(BaseStringList):
}
}
RETURN_TYPES = ("LIST", "STRING",)
RETURN_NAMES = ("string_list", "strings",)
OUTPUT_IS_LIST = (False, True)
FUNCTION = "process"
CATEGORY = "String Helper"
IS_CHANGED = True
def process(self, random_select_count, selected_numbers, translate_output, string1, string2, string3, string4, string5, string6, string7, string8, string9, string10, string_list=None):
def process(self, p1_select_by_numbers, p2_select_sequential, p3_select_random_count, translate_output, string1, string2, string3, string4, string5, string6, string7, string8, string9, string10, string_list=None):
# Create a list of all strings from inputs, including empty ones
input_strings = [string1, string2, string3, string4, string5, string6, string7, string8, string9, string10]
return self.process_string_selection(input_strings, random_select_count, selected_numbers, translate_output, string_list)
return self.process_string_selection(input_strings, p3_select_random_count, p1_select_by_numbers, translate_output, p2_select_sequential, string_list)
class StringListFromCSV(BaseStringList):
@@ -268,18 +308,21 @@ class StringListFromCSV(BaseStringList):
"multiline": False,
"placeholder": "Filter by tags (comma-separated)"
}),
"random_select_count": ("INT", {
"p1_select_by_numbers": ("STRING", {
"default": "",
"multiline": False,
"placeholder": "Priority 1: Comma-separated numbers (e.g. 1,3,5)"
}),
"p2_select_sequential": ("BOOLEAN", {
"default": False,
}),
"p3_select_random_count": ("INT", {
"default": -1,
"min": -1,
"max": 999999,
"step": 1,
"display": "number"
}),
"selected_numbers": ("STRING", {
"default": "",
"multiline": False,
"placeholder": "Comma-separated numbers (e.g., 1,3,5)"
}),
"translate_output": ("BOOLEAN", {
"default": False,
}),
@@ -331,14 +374,21 @@ class StringListFromCSV(BaseStringList):
return filtered_rows
def read_strings_from_csv(self, csv_file, use_translated, filter_tags, random_select_count, selected_numbers, translate_output, reuse_last_result, string_list=None):
def read_strings_from_csv(self, csv_file, use_translated, filter_tags, p1_select_by_numbers, p2_select_sequential, p3_select_random_count, translate_output, reuse_last_result, string_list=None):
# If reusing last result and it exists, return it directly
if reuse_last_result and self.last_result is not None:
return self.last_result
# Read and process strings
input_strings = self.read_csv_file(csv_file, filter_tags, use_translated)
result = self.process_string_selection(input_strings, random_select_count, selected_numbers, translate_output, string_list)
result = self.process_string_selection(
input_strings,
p3_select_random_count,
p1_select_by_numbers,
translate_output,
p2_select_sequential,
string_list
)
# Save result for future reuse
self.last_result = result