161 lines
5.3 KiB
Python
161 lines
5.3 KiB
Python
import os
|
|
import re
|
|
import json
|
|
|
|
# カテゴリー名を定数として定義
|
|
CATEGORY_TEXT = "Prompt String Selector"
|
|
|
|
|
|
class BasePromptSelector:
|
|
@classmethod
|
|
def get_base_data_path(cls):
|
|
current_dir = os.path.dirname(os.path.realpath(__file__))
|
|
base_data_path = os.path.join(current_dir, "data")
|
|
config_path = os.path.join(current_dir, "config.json")
|
|
if os.path.exists(config_path):
|
|
try:
|
|
with open(config_path, "r", encoding="utf-8") as f:
|
|
config = json.load(f)
|
|
custom_path = config.get("data_path", "").strip()
|
|
if custom_path:
|
|
base_data_path = custom_path if os.path.isabs(custom_path) else os.path.abspath(os.path.join(current_dir, custom_path))
|
|
except: pass
|
|
return base_data_path
|
|
|
|
@classmethod
|
|
def get_file_list(cls, subfolder):
|
|
base_path = cls.get_base_data_path()
|
|
folder_path = os.path.join(base_path, subfolder)
|
|
os.makedirs(folder_path, exist_ok=True)
|
|
files = [f for f in os.listdir(folder_path) if f.endswith(".txt")]
|
|
if not files: return ["custom_input"]
|
|
def extract_sort_key(filename):
|
|
match = re.match(r'(\d+)_', filename)
|
|
return int(match.group(1)) if match else 999999
|
|
files.sort(key=extract_sort_key)
|
|
return [os.path.splitext(f)[0] for f in files] + ["custom_input"]
|
|
|
|
RETURN_TYPES = ("STRING", "INT")
|
|
RETURN_NAMES = ("text", "id")
|
|
FUNCTION = "execute"
|
|
CATEGORY = CATEGORY_TEXT
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {"required": {
|
|
cls.L_SELECT: (cls.get_file_list(cls.FOLDER_NAME),),
|
|
cls.L_CUSTOM: ("STRING", {"default": "", "multiline": True})
|
|
}}
|
|
|
|
def clean_comment(self, text):
|
|
text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
|
|
text = re.sub(r'//.*', '', text)
|
|
lines = [l.strip() for l in text.splitlines() if l.strip()]
|
|
return " ".join(lines).strip().rstrip(",")
|
|
|
|
def execute(self, **kwargs):
|
|
selection = kwargs.get(self.L_SELECT)
|
|
custom_text = kwargs.get(self.L_CUSTOM)
|
|
txt, idx = self.execute_logic(selection, custom_text, self.FOLDER_NAME)
|
|
if txt: txt += ",\n"
|
|
return (txt, idx)
|
|
|
|
def execute_logic(self, selection, custom_text, subfolder):
|
|
match = re.match(r'(\d+)_', selection)
|
|
selected_id = int(match.group(1)) if match else 0
|
|
raw_text = ""
|
|
if selection == "custom_input":
|
|
raw_text = custom_text
|
|
else:
|
|
path = os.path.join(self.get_base_data_path(), subfolder, f"{selection}.txt")
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
raw_text = f.read()
|
|
except: pass
|
|
return (self.clean_comment(raw_text), selected_id)
|
|
|
|
|
|
class BaseBasePromptSwitch:
|
|
RETURN_TYPES = ("STRING",)
|
|
RETURN_NAMES = ("selected_text",)
|
|
FUNCTION = "execute"
|
|
CATEGORY = CATEGORY_TEXT
|
|
|
|
@classmethod
|
|
def create_input_types(cls, count):
|
|
optional_inputs = {}
|
|
for i in range(1, count + 1):
|
|
name = f"text_{i:02d}"
|
|
optional_inputs[name] = ("STRING", {"forceInput": True})
|
|
|
|
return {
|
|
"required": {
|
|
"id": ("INT", {"default": 1, "min": 1, "max": count}),
|
|
},
|
|
"optional": optional_inputs
|
|
}
|
|
|
|
def execute(self, id, **kwargs):
|
|
target_name = f"text_{id:02d}"
|
|
val = kwargs.get(target_name)
|
|
|
|
selected_text = ""
|
|
if val is not None and isinstance(val, str) and val.strip():
|
|
selected_text = val.strip()
|
|
if not selected_text.endswith(","):
|
|
selected_text += ",\n"
|
|
else:
|
|
selected_text += "\n"
|
|
|
|
return (selected_text,)
|
|
|
|
|
|
class BasePromptAggregator:
|
|
RETURN_TYPES = ("STRING",)
|
|
RETURN_NAMES = ("combined_prompt",)
|
|
FUNCTION = "aggregate"
|
|
CATEGORY = CATEGORY_TEXT
|
|
|
|
@classmethod
|
|
def create_input_types(cls, count):
|
|
optional_inputs = {}
|
|
for i in range(1, count + 1):
|
|
name = f"text_{i:02d}"
|
|
optional_inputs[name] = ("STRING", {"forceInput": True, "default": ""})
|
|
return {"required": {}, "optional": optional_inputs}
|
|
|
|
def aggregate(self, **kwargs):
|
|
active_prompts = []
|
|
# kwargsに入っているすべての text_XX を順番に処理
|
|
sorted_keys = sorted([k for k in kwargs.keys() if k.startswith("text_")])
|
|
for name in sorted_keys:
|
|
val = kwargs.get(name)
|
|
if val is not None and isinstance(val, str) and val.strip():
|
|
cleaned = val.strip()
|
|
if not cleaned.endswith(","):
|
|
cleaned += ","
|
|
active_prompts.append(cleaned)
|
|
|
|
return ("\n".join(active_prompts),)
|
|
|
|
|
|
class BaseIdSelector:
|
|
RETURN_TYPES = ("INT",)
|
|
RETURN_NAMES = ("id",)
|
|
FUNCTION = "execute"
|
|
CATEGORY = CATEGORY_TEXT
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"id": ("INT", {"default": 1, "min": 1, "max": 999999}),
|
|
"memo": ("STRING", {"default": "", "multiline": True}),
|
|
}
|
|
}
|
|
|
|
def execute(self, id, memo):
|
|
return (id,)
|
|
|
|
|