507 lines
15 KiB
Python
507 lines
15 KiB
Python
import random
|
|
from yors_pano_list_util import ListDelExclude,ListFillOne,ListToTupe,ListShuffle
|
|
|
|
# from .conf import CURRENT_CATEGORY,CURRENT_FUNCTION
|
|
# feat(core): use ymc suite/text/plain as category
|
|
CURRENT_CATEGORY="ymc suite/text/plain"
|
|
CURRENT_FUNCTION="exec"
|
|
|
|
|
|
def TextListRandom(text:str, seed,char='|'):
|
|
"""
|
|
item,seed = TextListRandom(text,seed,'|')
|
|
|
|
TextListRandom(text,seed,',')
|
|
"""
|
|
iteml = text.split(char)
|
|
random.seed(seed)
|
|
choice = random.choice(iteml)
|
|
return ListToTupe([choice,seed])
|
|
|
|
|
|
def range_safe(i:int,s:int,e:int):
|
|
'''
|
|
ensure i is in [s,e]
|
|
'''
|
|
res=i
|
|
if res <s:
|
|
res=s
|
|
if res >e:
|
|
res=e
|
|
return res
|
|
|
|
def range_safe_loop(i:int,s:int,e:int):
|
|
'''
|
|
ensure i is in [s,e] for loop
|
|
'''
|
|
res=i
|
|
if res <s:
|
|
res=s
|
|
if res >=e:
|
|
res = res % e
|
|
res = s + res
|
|
return res
|
|
|
|
def TextListLoop(text, seed,char='|'):
|
|
iteml = text.split(char)
|
|
# get loop index with de/cr seed
|
|
length=len(iteml)
|
|
index=range_safe_loop(seed-1,0,length)
|
|
choice = iteml[index]
|
|
# print(maxindex,seed,index,choice)
|
|
return ListToTupe([choice,seed,str(index+1),length])
|
|
|
|
|
|
|
|
def TextReplace(text, find, replace):
|
|
"""
|
|
text replace find with re.sub
|
|
"""
|
|
import re
|
|
result = re.sub(find, replace, text)
|
|
return result
|
|
|
|
|
|
|
|
TEXT_LIST_RETURN_NAMES=['a','b','c','d','e','f','g']
|
|
TEXT_LIST_COUNT=len(TEXT_LIST_RETURN_NAMES)
|
|
TEXT_LIST_ADV_RETURN_NAMES=TEXT_LIST_RETURN_NAMES.copy()
|
|
TEXT_LIST_ADV_RETURN_NAMES.insert(0,"prefix")
|
|
# feat(core): NodePlainTextList - input text preset
|
|
class NodePlainTextList:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"a": ("STRING",{"forceInput":False}),
|
|
"b": ("STRING",{"forceInput":False}),
|
|
"c": ("STRING",{"forceInput":False}),
|
|
"d": ("STRING",{"forceInput":False}),
|
|
"e": ("STRING",{"forceInput":False}),
|
|
"f": ("STRING",{"forceInput":False}),
|
|
"g": ("STRING",{"forceInput":False}),
|
|
}
|
|
}
|
|
RETURN_TYPES = ListToTupe(ListFillOne('STRING',TEXT_LIST_COUNT))
|
|
RETURN_NAMES = ListToTupe(TEXT_LIST_RETURN_NAMES)
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "input text preset"
|
|
OUTPUT_NODE = True
|
|
|
|
def exec(self, a,b,c,d,e,f,g):
|
|
return ListToTupe([a,b,c,d,e,f,g])
|
|
|
|
# feat(core): NodePlainTextListAdv - input text preset - adv
|
|
class NodePlainTextListAdv:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"prefix": ("STRING",{"forceInput":False}),
|
|
"a": ("STRING",{"forceInput":False}),
|
|
"b": ("STRING",{"forceInput":False}),
|
|
"c": ("STRING",{"forceInput":False}),
|
|
"d": ("STRING",{"forceInput":False}),
|
|
"e": ("STRING",{"forceInput":False}),
|
|
"f": ("STRING",{"forceInput":False}),
|
|
"g": ("STRING",{"forceInput":False}),
|
|
}
|
|
}
|
|
RETURN_TYPES = ListToTupe(ListFillOne('STRING',TEXT_LIST_COUNT+1))
|
|
RETURN_NAMES = ListToTupe(TEXT_LIST_ADV_RETURN_NAMES)
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "input text preset - adv"
|
|
OUTPUT_NODE = True
|
|
|
|
def exec(self,prefix, a,b,c,d,e,f,g):
|
|
joined = list(map(lambda x: prefix+x,[a,b,c,d,e,f,g]))
|
|
import datetime
|
|
# import time
|
|
joined.insert(0,prefix)
|
|
joined = list(map(lambda x: datetime.datetime.now().strftime(x),joined)) # replace time exp like %Y %M %D
|
|
return ListToTupe(joined)
|
|
|
|
# feat(core): NodePlainTextListJoinTextAdv - join text to text preset - adv
|
|
class NodePlainTextListJoinTextAdv:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
|
|
},
|
|
"optional": {
|
|
"text": ("STRING",{"forceInput": True}),
|
|
"a": ("STRING",{"forceInput":True}),
|
|
"b": ("STRING",{"forceInput":True}),
|
|
"c": ("STRING",{"forceInput":True}),
|
|
"d": ("STRING",{"forceInput":True}),
|
|
"e": ("STRING",{"forceInput":True}),
|
|
"f": ("STRING",{"forceInput":True}),
|
|
"g": ("STRING",{"forceInput":True}),
|
|
"action": (["none","text-as-head","text-as-tail"],),
|
|
}
|
|
}
|
|
RETURN_TYPES = ListToTupe(ListFillOne('STRING',TEXT_LIST_COUNT+1))
|
|
RETURN_NAMES = ListToTupe(['text','a','b','c','d','e','f','g'])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "join text to text preset - adv"
|
|
OUTPUT_NODE = True
|
|
|
|
def exec(self,text, a,b,c,d,e,f,g,action="none"):
|
|
joined=[]
|
|
if "none" in action:
|
|
joined = [a,b,c,d,e,f,g]
|
|
elif "text-as-head" in action:
|
|
joined = list(map(lambda x: text+x,[a,b,c,d,e,f,g]))
|
|
elif "text-as-tail" in action:
|
|
joined = list(map(lambda x: x+text,[a,b,c,d,e,f,g]))
|
|
import datetime
|
|
# import time
|
|
joined.insert(0,text)
|
|
joined = list(map(lambda x: datetime.datetime.now().strftime(x),joined)) # replace time exp like %Y %M %D
|
|
return ListToTupe(joined)
|
|
|
|
# feat(core): NodePlainTextJoin - join text
|
|
class NodePlainTextJoin:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"splitchar": ("STRING", {"default": "_", "multiline": False}),
|
|
"a": ("STRING",{"forceInput":False}),
|
|
"b": ("STRING",{"forceInput":False}),
|
|
"c": ("STRING",{"forceInput":False}),
|
|
"d": ("STRING",{"forceInput":False}),
|
|
"e": ("STRING",{"forceInput":False}),
|
|
"f": ("STRING",{"forceInput":False}),
|
|
"g": ("STRING",{"forceInput":False}),
|
|
}
|
|
}
|
|
RETURN_TYPES = ListToTupe(ListFillOne('STRING',1))
|
|
RETURN_NAMES = ListToTupe(['text'])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "join text"
|
|
|
|
|
|
OUTPUT_NODE = True
|
|
|
|
def exec(self, splitchar,a,b,c,d,e,f,g):
|
|
# args to list
|
|
ls=[a,b,c,d,e,f,g]
|
|
# ignore none
|
|
ls = list(filter(None, ls))
|
|
# join with splitChar
|
|
joinedtxt=splitchar.join(ls)
|
|
return ListToTupe([joinedtxt])
|
|
|
|
# feat(core): NodePlainTextRandom - random text in list
|
|
class NodePlainTextRandom:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"text": ("STRING", {"default": '', "multiline": False}),
|
|
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
|
"char": ("STRING", {"default": '|', "multiline": False}),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("STRING",'INT',)
|
|
RETURN_NAMES = ListToTupe(['text','seed'])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "random text in list"
|
|
def exec(self, text, seed,char='|'):
|
|
return TextListRandom(text,seed,char)
|
|
|
|
@classmethod
|
|
def IS_CHANGED(cls, **kwargs):
|
|
return float("NaN")
|
|
|
|
# feat(core): NodePlainTextLoop - get text in list (loop)
|
|
class NodePlainTextLoop:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"text": ("STRING", {"default": '', "multiline": False}),
|
|
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
|
"char": ("STRING", {"default": '|', "multiline": False}),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("STRING",'INT','STRING','INT')
|
|
RETURN_NAMES = ListToTupe(['text','seed','index','count'])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "get text in list (loop)"
|
|
|
|
def exec(self, text, seed,char='|'):
|
|
return TextListLoop(text, seed,char)
|
|
|
|
@classmethod
|
|
def IS_CHANGED(cls, **kwargs):
|
|
return float("NaN")
|
|
|
|
# feat(core): NodePlainTextReplace - replace text
|
|
class NodePlainTextReplace:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"text": ("STRING", {"default": '', "multiline": False}),
|
|
"find": ("STRING", {"default": '', "multiline": False}),
|
|
"replace": ("STRING", {"default": '', "multiline": False}),
|
|
"action": (["yes",'no'],),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("STRING",)
|
|
RETURN_NAMES = ListToTupe(['text'])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "replace"
|
|
|
|
|
|
def exec(self, text, find, replace,action='yes'):
|
|
# feat(core): do nothing when action no
|
|
if 'no' in action:
|
|
return ListToTupe([text])
|
|
# feat(core): replace text
|
|
return ListToTupe([TextReplace(text, find, replace)])
|
|
|
|
|
|
def NumStrToNumInt(str:str="1",roundit:bool=True):
|
|
"""
|
|
NumStrToNumInt(0.5)
|
|
NumStrToNumInt(float(str))
|
|
"""
|
|
if roundit == True:
|
|
return int(round(str))
|
|
return int(str)
|
|
|
|
def NumStrIsRoundToA(a='1', isRoundTo='1'):
|
|
"""
|
|
NumStrIsRoundToA("0.8","1")
|
|
NumStrIsRoundToA("0.4","1")
|
|
"""
|
|
if NumStrToNumInt(a) == NumStrToNumInt(isRoundTo):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def BoolStr2BoolNum(str:str="true"):
|
|
"""
|
|
BoolStr2BoolNum("TRUE")
|
|
BoolStr2BoolNum("false")
|
|
"""
|
|
# true,TRUE
|
|
if str=="true":
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
# feat(core): NodeNumStrToNum - text to number
|
|
class NodeNumStrToNum:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"text": ("STRING", {"default": '', "multiline": False}),
|
|
}
|
|
}
|
|
|
|
# RETURN_TYPES = ('NUMBER',)
|
|
RETURN_TYPES = ("NUMBER", "FLOAT", "INT")
|
|
RETURN_NAMES = ListToTupe(["number", "float", "roundInt"])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "to number"
|
|
|
|
def exec(self, text=''):
|
|
strInt = int(text)
|
|
strFlo = float(text)
|
|
strRoundInt = int(round(strFlo))
|
|
return ListToTupe([strInt,strFlo,strRoundInt])
|
|
|
|
# feat(core): NodeNumStrToBool - text to bool
|
|
class NodeNumStrToBool:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"text": ("STRING", {"default": '1', "multiline": False}),
|
|
"isRoundTo":("STRING", {"default": '1', "multiline": False}),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ('STRING',)
|
|
RETURN_NAMES = ListToTupe(["boolean"])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "is round to x"
|
|
|
|
def exec(self, a='1', isRoundTo='1'):
|
|
return ListToTupe([NumStrIsRoundToA(a,isRoundTo)])
|
|
|
|
# feat(core): NodePlainTextSwitchWithBool - text switch with bool
|
|
class NodePlainTextSwitchWithBool:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"a": ("STRING", {"default": '', "multiline": False}),
|
|
"b": ("STRING", {"default": '', "multiline": False}),
|
|
"boolean": ("BOOL",),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ('STRING',)
|
|
RETURN_NAMES = ListToTupe(["text"])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "switch a and b"
|
|
|
|
def exec(self, a='', b='', boolean:bool=True):
|
|
if boolean==True:
|
|
return (a, )
|
|
else:
|
|
return (b, )
|
|
|
|
# feat(core): NodePlainTextSwitchWithText - text switch with text
|
|
class NodePlainTextSwitchWithText:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"a": ("STRING", {"default": '', "multiline": False}),
|
|
"b": ("STRING", {"default": '', "multiline": False}),
|
|
"text": ("STRING", {"default": '1', "multiline": False}),
|
|
"isRoundTo":("STRING", {"default": '1', "multiline": False}),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ('STRING',)
|
|
RETURN_NAMES = ListToTupe(["text"])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "switch a and b (isRoundTo)"
|
|
def exec(self, a='', b='', text='1',isRoundTo='1'):
|
|
if NumStrIsRoundToA(text,isRoundTo):
|
|
return (a, )
|
|
else:
|
|
return (b, )
|
|
|
|
# class NodeTextShow:
|
|
# @classmethod
|
|
# def INPUT_TYPES(s):
|
|
# return {"required": {
|
|
# "text": ("STRING", {"forceInput": True}),
|
|
# }}
|
|
|
|
# # INPUT_IS_LIST = True
|
|
# FUNCTION = CURRENT_FUNCTION
|
|
# CATEGORY = CURRENT_CATEGORY
|
|
# NODE_DESC = "show text"
|
|
# OUTPUT_NODE = True
|
|
# RETURN_TYPES = ('STRING',)
|
|
# # OUTPUT_IS_LIST = (True,)
|
|
|
|
# def exec(self, text):
|
|
# return {"ui": {"text": text}, "result": (text,)}
|
|
# refer: pythongosssss /ComfyUI-Custom-Scripts/py/show_text.py
|
|
|
|
# feat(core): NodeTextShow - show text
|
|
class NodeTextShow:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"text": ("STRING", {"forceInput": True}),
|
|
},
|
|
"hidden": {
|
|
"unique_id": "UNIQUE_ID",
|
|
"extra_pnginfo": "EXTRA_PNGINFO",
|
|
},
|
|
}
|
|
|
|
INPUT_IS_LIST = True
|
|
RETURN_TYPES = ("STRING",)
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "show text"
|
|
OUTPUT_NODE = True
|
|
OUTPUT_IS_LIST = (True,)
|
|
def exec(self, text, unique_id = None, extra_pnginfo=None):
|
|
if unique_id and extra_pnginfo and "workflow" in extra_pnginfo[0]:
|
|
workflow = extra_pnginfo[0]["workflow"]
|
|
node = next((x for x in workflow["nodes"] if str(x["id"]) == unique_id[0]), None)
|
|
if node:
|
|
node["widgets_values"] = [text]
|
|
return {"ui": {"text": text}, "result": (text,)}
|
|
|
|
# feat(core): NodeTextCalcSize - cacluate width and height
|
|
class NodeTextCalcSize:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"w": ("INT", {"default":512, "max": 10000000, "min":0, "step":1}),
|
|
"h": ("INT", {"default":512, "max": 10000000, "min":0, "step":1}),
|
|
"lockoff": (["false", "w","h"],),
|
|
# "rate": (["1:1", "2:3","9:16"],),
|
|
"rate": ("STRING", {"default": "1:1", "multiline": False}),
|
|
"reverse": (["false", "true"],),
|
|
}
|
|
}
|
|
RETURN_TYPES = ListToTupe(ListFillOne('INT',2))
|
|
RETURN_NAMES = ListToTupe(['w','h'])
|
|
FUNCTION = CURRENT_FUNCTION
|
|
CATEGORY = CURRENT_CATEGORY
|
|
NODE_DESC = "cacluate width and height"
|
|
OUTPUT_NODE = True
|
|
|
|
def exec(self,w=512, h=512,lockoff='false',rate='1:1',reverse='false'):
|
|
rw=w
|
|
rh=h
|
|
# get h or w with lockoff
|
|
if lockoff != "false":
|
|
ratel=list(map(int,rate.split(":")))
|
|
raten=(ratel[0]/ratel[1])
|
|
if lockoff == "w":
|
|
rh=int(w/raten)
|
|
if lockoff == "h":
|
|
rw=int(h*raten)
|
|
|
|
floatl=[rw,rh]
|
|
# reverse result of w h
|
|
if reverse == "true":
|
|
floatl=[rh,rw]
|
|
intl=list(map(int,floatl))
|
|
return ListToTupe(intl) |