From 2d1555d0a6341d45178223f630bc2e7a44fd1e67 Mon Sep 17 00:00:00 2001 From: saschafuchs Date: Sat, 17 Aug 2024 15:41:46 +0200 Subject: [PATCH] refactor: apply consistent formatting across multiple files - Improve indentation and spacing - Normalize string quotes - Simplify return statements - Clean up optional arguments handling --- .cursorrules | 1 + .editorconfig | 22 ++ py/latent_helper.py | 133 +++---- py/loader_helper.py | 38 +- py/logic_helper.py | 659 ++++++++++++++++++----------------- py/prompter.py | 169 +++++---- py/smart_checkpoint_setup.py | 388 +++++++++++---------- py/upscale_helper.py | 239 +++++++------ ruff.toml | 77 ++++ 9 files changed, 949 insertions(+), 777 deletions(-) create mode 100644 .cursorrules create mode 100644 .editorconfig create mode 100644 ruff.toml diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 0000000..5ff21db --- /dev/null +++ b/.cursorrules @@ -0,0 +1 @@ +We are building nodes for comfyui with python 3.1x. Using underscore notation for variables, use double quotes, 2 spaces spacing \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..97dd07e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[*.{py,java,r,R}] +indent_style = space +indent_size = 2 + +# 2 space indentation +[*.{js,json,y{a,}ml,html,cwl}] +indent_style = space +indent_size = 2 + +[*.{md,Rmd,rst}] +trim_trailing_whitespace = false +indent_style = space +indent_size = 2 diff --git a/py/latent_helper.py b/py/latent_helper.py index 00ac54f..d183251 100644 --- a/py/latent_helper.py +++ b/py/latent_helper.py @@ -1,77 +1,82 @@ import torch from nodes import EmptyLatentImage + class UniversalLatentHelper: - def __init__(self): - pass + def __init__(self): + pass - @classmethod - def INPUT_TYPES(s): - aspect_ratios = [ - "custom", - "1:1", - "3:2", - "4:3", - "5:8", - "16:9", - "1.85:1", - "2:1", - "2.39:1", - "21:9", - ] - - return { - "required": { - "version": ("STRING", { - "default": "xl", - "forceInput": True, - }), - "width": ("INT", {"default": 1024, "min": 64, "max": 8192}), - "height": ("INT", {"default": 1024, "min": 64, "max": 8192}), - "aspect_ratio": (aspect_ratios,), - "format": (["landscape", "portrait"],), - "batch_size": ("INT", {"default": 1, "min": 1, "max": 64}) - } - } - - RETURN_TYPES = ("INT", "INT", "INT", "LATENT") - RETURN_NAMES = ("width", "height", "batch_size", "empty_latent") + @classmethod + def INPUT_TYPES(s): + aspect_ratios = [ + "custom", + "1:1", + "3:2", + "4:3", + "5:8", + "16:9", + "1.85:1", + "2:1", + "2.39:1", + "21:9", + ] - FUNCTION = "Latent_Size" - - CATEGORY = "Foxpack/Latent Helper" - - def Latent_Size(self, version, width, height, aspect_ratio, format, batch_size): - ratios = { - "custom": [[width, height],[width, height]], - "1:1": [[512,512],[1024,1024]], - "3:2": [[768,512],[1216,832]], - "4:3": [[682,512],[1152,896]], - "5:8": [[748,512],[1216,832]], - "16:9": [[910,512],[1322,768]], - "1.85:1": [[952,512],[1264,680]], - "2:1": [[1024,512],[2048,1024]], - "2.39:1": [[1224,512],[1587,664]], - "21:9": [[1229,512],[1536,640]] + return { + "required": { + "version": ( + "STRING", + { + "default": "xl", + "forceInput": True, + }, + ), + "width": ("INT", {"default": 1024, "min": 64, "max": 8192}), + "height": ("INT", {"default": 1024, "min": 64, "max": 8192}), + "aspect_ratio": (aspect_ratios,), + "format": (["landscape", "portrait"],), + "batch_size": ("INT", {"default": 1, "min": 1, "max": 64}), } + } - pick_ratio = ratios[aspect_ratio] - pick_ration_for_version = pick_ratio[0] if version == "15" else pick_ratio[1] + RETURN_TYPES = ("INT", "INT", "INT", "LATENT") + RETURN_NAMES = ("width", "height", "batch_size", "empty_latent") - width, height = pick_ration_for_version[0], pick_ration_for_version[1] + FUNCTION = "Latent_Size" - if (format == "portrait"): - width, height = height, width + CATEGORY = "Foxpack/Latent Helper" - height == height // 8 - width == width // 8 + def Latent_Size(self, version, width, height, aspect_ratio, format, batch_size): + ratios = { + "custom": [[width, height], [width, height]], + "1:1": [[512, 512], [1024, 1024]], + "3:2": [[768, 512], [1216, 832]], + "4:3": [[682, 512], [1152, 896]], + "5:8": [[748, 512], [1216, 832]], + "16:9": [[910, 512], [1322, 768]], + "1.85:1": [[952, 512], [1264, 680]], + "2:1": [[1024, 512], [2048, 1024]], + "2.39:1": [[1224, 512], [1587, 664]], + "21:9": [[1229, 512], [1536, 640]], + } - print(f"Width: {width}, Height: {height}") + pick_ratio = ratios[aspect_ratio] + pick_ration_for_version = pick_ratio[0] if version == "15" else pick_ratio[1] - latent = torch.zeros([batch_size, 4, height // 8, width // 8]) - - return ( - int(width), - int(height), - int(batch_size), - {"samples": latent},) \ No newline at end of file + width, height = pick_ration_for_version[0], pick_ration_for_version[1] + + if format == "portrait": + width, height = height, width + + height == height // 8 + width == width // 8 + + print(f"Width: {width}, Height: {height}") + + latent = torch.zeros([batch_size, 4, height // 8, width // 8]) + + return ( + int(width), + int(height), + int(batch_size), + {"samples": latent}, + ) diff --git a/py/loader_helper.py b/py/loader_helper.py index b128919..1d810a1 100644 --- a/py/loader_helper.py +++ b/py/loader_helper.py @@ -29,7 +29,6 @@ class Universal_VAE_Loader: } # version 1: baked, 2: sdxl, 3: sd15 - RETURN_TYPES = ("VAE",) RETURN_NAMES = ("vae",) @@ -38,26 +37,6 @@ class Universal_VAE_Loader: CATEGORY = "Foxpack/Loader" def main(self, checkpoint_vae, vae_type, vae_sdxl, vae_sd15, vae_sd3, vae_flux, vae_type_select): - if (vae_type_select != "base"): - if (vae_type_select == "baked"): - return ( - checkpoint_vae, - ) - - vae_path = folder_paths.get_full_path("vae", vae_name) - sd = comfy.utils.load_torch_file(vae_path) - vae = comfy.sd.VAE(sd=sd) - - return ( - vae, - ) - - - if (vae_type == 0): - return ( - checkpoint_vae, - ) - vae_name = { 1: vae_sdxl, 2: vae_sd15, @@ -65,10 +44,25 @@ class Universal_VAE_Loader: 4: vae_flux, }.get(vae_type, checkpoint_vae) + if (vae_type_select != "base"): + if (vae_type_select == "baked"): + return ( + checkpoint_vae, + ) + + vae_path = folder_paths.get_full_path("vae", vae_name) + sd = comfy.utils.load_torch_file(vae_path) + vae = comfy.sd.VAE(sd=sd) + + return ( vae, ) + + if (vae_type == 0): + return ( checkpoint_vae, ) + vae_path = folder_paths.get_full_path("vae", vae_name) sd = comfy.utils.load_torch_file(vae_path) vae = comfy.sd.VAE(sd=sd) return ( vae, - ) \ No newline at end of file + ) diff --git a/py/logic_helper.py b/py/logic_helper.py index 89df947..ed7abd6 100644 --- a/py/logic_helper.py +++ b/py/logic_helper.py @@ -1,25 +1,31 @@ import ast import re + + class AnyType(str): - def __ne__(self, __value: object) -> bool: - return False + def __ne__(self, __value: object) -> bool: + return False + any_type = AnyType("*") + class DynamicInputType(dict): def __init__(self, type): self.type = type def __getitem__(self, key): - return (self.type, ) + return (self.type,) def __contains__(self, key): return True + class TautologyStr(str): def __ne__(self, other): return False + class AlwaysEqualProxy(str): def __eq__(self, _): return True @@ -27,45 +33,50 @@ class AlwaysEqualProxy(str): def __ne__(self, _): return False + class ByPassTypeTuple(tuple): def __getitem__(self, index): - if index>0: - index=0 + if index > 0: + index = 0 item = super().__getitem__(index) if isinstance(item, str): return TautologyStr(item) return item + def is_context_empty(ctx): return not ctx or all(v is None for v in ctx.values()) + def is_none(value): if value is not None: - if isinstance(value, dict) and 'model' in value and 'clip' in value: + if isinstance(value, dict) and "model" in value and "clip" in value: return is_context_empty(value) return value is None + def variable_output_arr(separator, options, output_type, max_length: int = 2): - if (type(options) == str): - arr = [x.strip() for x in options.split(separator)] - else: - arr = options - - type_conversions = { - "int": int, - "float": float, - "boolean": bool, - "list": list, - } + if type(options) == str: + arr = [x.strip() for x in options.split(separator)] + else: + arr = options - if output_type in type_conversions: - arr = [type_conversions[output_type](x) for x in arr] + type_conversions = { + "int": int, + "float": float, + "boolean": bool, + "list": list, + } - arr.extend([""] * (max_length - len(arr))) + if output_type in type_conversions: + arr = [type_conversions[output_type](x) for x in arr] - output = tuple(arr[:max_length]) + arr.extend([""] * (max_length - len(arr))) + + output = tuple(arr[:max_length]) + + return output - return output class Remap_Values: def __init__(self): @@ -75,15 +86,21 @@ class Remap_Values: def INPUT_TYPES(s): return { "required": { - "search_string": ("STRING", { - "forceInput": True, - "default": "", - "multiline": False, - }), - "map": ("STRING", { - "default": "", - "multiline": False, - }), + "search_string": ( + "STRING", + { + "forceInput": True, + "default": "", + "multiline": False, + }, + ), + "map": ( + "STRING", + { + "default": "", + "multiline": False, + }, + ), } } @@ -103,11 +120,9 @@ class Remap_Values: print("entry:", entry) show_help = "show me some help" - - return ( - str(entry), - show_help - ) + + return (str(entry), show_help) + class Negate_Boolean: def __init__(self): @@ -117,9 +132,7 @@ class Negate_Boolean: def INPUT_TYPES(s): return { "required": { - "value": ("BOOLEAN", { - "forceInput": True - }), + "value": ("BOOLEAN", {"forceInput": True}), } } @@ -133,6 +146,7 @@ class Negate_Boolean: def main(self, value): return (not value,) + class Select_String_By_Index: def __init__(self): pass @@ -141,12 +155,13 @@ class Select_String_By_Index: def INPUT_TYPES(s): return { "required": { - "index": ("INT", { - "default": 0, - }), - "options": ("STRING", { - "forceInput": True - }), + "index": ( + "INT", + { + "default": 0, + }, + ), + "options": ("STRING", {"forceInput": True}), } } @@ -156,16 +171,15 @@ class Select_String_By_Index: FUNCTION = "main" CATEGORY = "Foxpack/Logic" - + def main(self, index, options): stringArray = options.split(",") length = len(stringArray) index = index if index < length else length - 1 selected_option = stringArray[index] - - return ( - str(selected_option), - ) + + return (str(selected_option),) + class Select_By_Index: def __init__(self): @@ -175,19 +189,23 @@ class Select_By_Index: def INPUT_TYPES(s): return { "required": { - "index": ("INT", { - "default": 0, - }), - "options": (any_type, { - "forceInput": True - }), - "seperator": ("STRING", { - "default": ",", - }), - "output_type": (["input","string", "int", "float", "boolean", "list"], - { - "default": "string" - }), + "index": ( + "INT", + { + "default": 0, + }, + ), + "options": (any_type, {"forceInput": True}), + "seperator": ( + "STRING", + { + "default": ",", + }, + ), + "output_type": ( + ["input", "string", "int", "float", "boolean", "list"], + {"default": "string"}, + ), } } @@ -212,14 +230,13 @@ class Select_By_Index: "int": int, "float": float, "boolean": bool, - "list": lambda x: [x] - } + "list": lambda x: [x], + } param = conversion_map.get(output_type, lambda x: x)(entry) - - return ( - param, - ) + + return (param,) + class Split_Entry_In_2Chunks: def __init__(self): @@ -229,23 +246,24 @@ class Split_Entry_In_2Chunks: def INPUT_TYPES(s): return { "required": { - "seperator": ("STRING", { - "default": ",", - }), - "options": (any_type, { - "forceInput": True - }) + "seperator": ( + "STRING", + { + "default": ",", + }, + ), + "options": (any_type, {"forceInput": True}), }, "optional": { - "output_type": (["string", "int", "float", "boolean", "list"], - { - "default": "string" - }), - } + "output_type": ( + ["string", "int", "float", "boolean", "list"], + {"default": "string"}, + ), + }, } - RETURN_TYPES = (any_type,any_type) - RETURN_NAMES = ("value1","value2") + RETURN_TYPES = (any_type, any_type) + RETURN_NAMES = ("value1", "value2") OUTPUT_NODE = True FUNCTION = "main" @@ -253,9 +271,8 @@ class Split_Entry_In_2Chunks: CATEGORY = "Foxpack/Logic" def main(self, seperator, options, output_type): - return ( - variable_output_arr(seperator, options, output_type, 2) - ) + return variable_output_arr(seperator, options, output_type, 2) + class Split_Entry_In_4Chunks: def __init__(self): @@ -265,23 +282,24 @@ class Split_Entry_In_4Chunks: def INPUT_TYPES(s): return { "required": { - "seperator": ("STRING", { - "default": ",", - }), - "options": (any_type, { - "forceInput": True - }) + "seperator": ( + "STRING", + { + "default": ",", + }, + ), + "options": (any_type, {"forceInput": True}), }, "optional": { - "output_type": (["string", "int", "float", "boolean", "list"], - { - "default": "string" - }), - } + "output_type": ( + ["string", "int", "float", "boolean", "list"], + {"default": "string"}, + ), + }, } - RETURN_TYPES = (any_type,any_type,any_type,any_type) - RETURN_NAMES = ("value1","value2","value3","value4") + RETURN_TYPES = (any_type, any_type, any_type, any_type) + RETURN_NAMES = ("value1", "value2", "value3", "value4") OUTPUT_NODE = True FUNCTION = "main" @@ -289,9 +307,8 @@ class Split_Entry_In_4Chunks: CATEGORY = "Foxpack/Logic" def main(self, seperator, options, output_type): - return ( - variable_output_arr(seperator, options, output_type, 4) - ) + return variable_output_arr(seperator, options, output_type, 4) + class Split_Entry_In_6Chunks: def __init__(self): @@ -301,23 +318,24 @@ class Split_Entry_In_6Chunks: def INPUT_TYPES(s): return { "required": { - "seperator": ("STRING", { - "default": ",", - }), - "options": (any_type, { - "forceInput": True - }) + "seperator": ( + "STRING", + { + "default": ",", + }, + ), + "options": (any_type, {"forceInput": True}), }, "optional": { - "output_type": (["string", "int", "float", "boolean", "list"], - { - "default": "string" - }), - } + "output_type": ( + ["string", "int", "float", "boolean", "list"], + {"default": "string"}, + ), + }, } - RETURN_TYPES = (any_type,any_type,any_type,any_type,any_type,any_type) - RETURN_NAMES = ("value1","value2","value3","value4","value5","value6") + RETURN_TYPES = (any_type, any_type, any_type, any_type, any_type, any_type) + RETURN_NAMES = ("value1", "value2", "value3", "value4", "value5", "value6") OUTPUT_NODE = True FUNCTION = "main" @@ -325,9 +343,8 @@ class Split_Entry_In_6Chunks: CATEGORY = "Foxpack/Logic" def main(self, seperator, options, output_type): - return ( - variable_output_arr(seperator, options, output_type, 6) - ) + return variable_output_arr(seperator, options, output_type, 6) + class Split_Entry_In_8Chunks: def __init__(self): @@ -337,23 +354,42 @@ class Split_Entry_In_8Chunks: def INPUT_TYPES(s): return { "required": { - "seperator": ("STRING", { - "default": ",", - }), - "options": (any_type, { - "forceInput": True - }) + "seperator": ( + "STRING", + { + "default": ",", + }, + ), + "options": (any_type, {"forceInput": True}), }, "optional": { - "output_type": (["string", "int", "float", "boolean", "list"], - { - "default": "string" - }), - } + "output_type": ( + ["string", "int", "float", "boolean", "list"], + {"default": "string"}, + ), + }, } - RETURN_TYPES = (any_type,any_type,any_type,any_type,any_type,any_type,any_type,any_type) - RETURN_NAMES = ("value1","value2","value3","value4","value5","value6","value7","value8") + RETURN_TYPES = ( + any_type, + any_type, + any_type, + any_type, + any_type, + any_type, + any_type, + any_type, + ) + RETURN_NAMES = ( + "value1", + "value2", + "value3", + "value4", + "value5", + "value6", + "value7", + "value8", + ) OUTPUT_NODE = True FUNCTION = "main" @@ -361,9 +397,8 @@ class Split_Entry_In_8Chunks: CATEGORY = "Foxpack/Logic" def main(self, seperator, options, output_type): - return ( - variable_output_arr(seperator, options, output_type, 8) - ) + return variable_output_arr(seperator, options, output_type, 8) + class Change_Entry_From_List: def __init__(self): @@ -373,15 +408,14 @@ class Change_Entry_From_List: def INPUT_TYPES(s): return { "required": { - "index": ("INT", { - "default": 0, - }), - "options": ("LIST", { - "forceInput": True - }), - "change_value": (any_type, { - "forceInput": True - }) + "index": ( + "INT", + { + "default": 0, + }, + ), + "options": ("LIST", {"forceInput": True}), + "change_value": (any_type, {"forceInput": True}), } } @@ -394,10 +428,9 @@ class Change_Entry_From_List: def main(self, index, options, change_value): options[index] = change_value - - return ( - options, - ) + + return (options,) + class Change_Entries_In_A_List: def __init__(self): @@ -407,15 +440,14 @@ class Change_Entries_In_A_List: def INPUT_TYPES(s): return { "required": { - "indexes": ("STRING", { - "default": "", - }), - "options": ("LIST", { - "forceInput": True - }), - "change_values": ("LIST", { - "forceInput": True - }) + "indexes": ( + "STRING", + { + "default": "", + }, + ), + "options": ("LIST", {"forceInput": True}), + "change_values": ("LIST", {"forceInput": True}), } } @@ -430,10 +462,9 @@ class Change_Entries_In_A_List: indexes = [int(x) for x in indexes.split(",")] for i, index in enumerate(indexes): options[index] = change_values[i] - - return ( - options, - ) + + return (options,) + class Pick_Values_From_List: def __init__(self): @@ -443,12 +474,13 @@ class Pick_Values_From_List: def INPUT_TYPES(s): return { "required": { - "options": ("LIST", { - "forceInput": True - }), - "indexes": ("STRING", { - "default": "", - }) + "options": ("LIST", {"forceInput": True}), + "indexes": ( + "STRING", + { + "default": "", + }, + ), } } @@ -462,9 +494,8 @@ class Pick_Values_From_List: def main(self, indexes, options): indexes = [int(x) for x in indexes.split(",")] options = [options[x] for x in indexes] - return ( - options, - ) + return (options,) + class Remove_Values_From_List: def __init__(self): @@ -474,12 +505,13 @@ class Remove_Values_From_List: def INPUT_TYPES(s): return { "required": { - "options": ("LIST", { - "forceInput": True - }), - "indexes": ("STRING", { - "default": "", - }) + "options": ("LIST", {"forceInput": True}), + "indexes": ( + "STRING", + { + "default": "", + }, + ), } } @@ -493,11 +525,10 @@ class Remove_Values_From_List: def main(self, indexes, options): indexes = [int(x) for x in indexes.split(",")] options = [options[x] for x in range(len(options)) if x not in indexes] - - return ( - options, - ) - + + return (options,) + + class Show_Type: def __init__(self): pass @@ -506,9 +537,7 @@ class Show_Type: def INPUT_TYPES(s): return { "required": { - "value": (any_type, { - "forceInput": True - }), + "value": (any_type, {"forceInput": True}), } } @@ -523,6 +552,7 @@ class Show_Type: print("Show_Type", value, type(value)) return () + class Select_Line_By_Index: def __init__(self): pass @@ -531,19 +561,28 @@ class Select_Line_By_Index: def INPUT_TYPES(s): return { "required": { - "options": ("STRING", { - "default": "", - "multiline": True, - }), + "options": ( + "STRING", + { + "default": "", + "multiline": True, + }, + ), }, "optional": { - "index": ("INT", { - "default": 0, - }), - "search_word": ("STRING", { - "default": "", - }), - } + "index": ( + "INT", + { + "default": 0, + }, + ), + "search_word": ( + "STRING", + { + "default": "", + }, + ), + }, } RETURN_TYPES = ("STRING",) @@ -567,12 +606,14 @@ class Select_Line_By_Index: selected_option = line break - selected_option = selected_option.replace(search_word, "").replace("=", "").replace('"', "").strip() - - - return ( - str(selected_option), - ) + selected_option = ( + selected_option.replace(search_word, "") + .replace("=", "") + .replace('"', "") + .strip() + ) + + return (str(selected_option),) class Convert_Into: @@ -583,19 +624,23 @@ class Convert_Into: def INPUT_TYPES(s): return { "required": { - "value": (any_type, { - "forceInput": True - }), - "seperator": ("STRING", { - "default": ",", - }), - "reverse": ("BOOLEAN", { - "default": False, - }), - "output_type": (["string", "int", "float", "boolean", "list"], - { - "default": "string" - }), + "value": (any_type, {"forceInput": True}), + "seperator": ( + "STRING", + { + "default": ",", + }, + ), + "reverse": ( + "BOOLEAN", + { + "default": False, + }, + ), + "output_type": ( + ["string", "int", "float", "boolean", "list"], + {"default": "string"}, + ), } } @@ -610,7 +655,7 @@ class Convert_Into: output = None if output_type == "string": - if (type(value) == list): + if isinstance(value, list): value = [str(x) for x in value] value = seperator.join(value) output = str(value) @@ -619,30 +664,29 @@ class Convert_Into: elif output_type == "float": output = float(value) elif output_type == "boolean": - if type(value) == int: - output = bool(False) if value == 0 else bool(True) - if type(value) == float: - value = int(value) - output = bool(False) if value == 0 else bool(True) - elif type(value) == str: - output = bool(False) if len(value) > 0 else bool(True) - elif type(value) == bool: + if isinstance(value, (int, float)): + output = bool(value != 0) + elif isinstance(value, str): + output = bool(value) + elif isinstance(value, bool): output = not value if reverse else value else: output = bool(value) output = not output if reverse else output elif output_type == "list": - if (type(value) == str): + if isinstance(value, str): value = value.split(seperator) - value = [int(x) if x.isdigit() else float(x) if x.replace(".", "", 1).isdigit() else x for x in value] + value = [ + int(x) if x.isdigit() else float(x) if x.replace(".", "", 1).isdigit() else x + for x in value + ] output = value else: output = [value] - return ( - output, - ) + return (output,) + class Add_To_List: @classmethod @@ -650,40 +694,18 @@ class Add_To_List: return { "required": {}, "optional": { - "list": ("LIST", { - "forceInput": True - }), - "item1": (any_type, { - "forceInput": True - }), - "item2": (any_type, { - "forceInput": True - }), - "item3": (any_type, { - "forceInput": True - }), - "item4": (any_type, { - "forceInput": True - }), - "item5": (any_type, { - "forceInput": True - }), - "item6": (any_type, { - "forceInput": True - }), - "item7": (any_type, { - "forceInput": True - }), - "item8": (any_type, { - "forceInput": True - }), - "item9": (any_type, { - "forceInput": True - }), - "item10": (any_type, { - "forceInput": True - }), - } + "list": ("LIST", {"forceInput": True}), + "item1": (any_type, {"forceInput": True}), + "item2": (any_type, {"forceInput": True}), + "item3": (any_type, {"forceInput": True}), + "item4": (any_type, {"forceInput": True}), + "item5": (any_type, {"forceInput": True}), + "item6": (any_type, {"forceInput": True}), + "item7": (any_type, {"forceInput": True}), + "item8": (any_type, {"forceInput": True}), + "item9": (any_type, {"forceInput": True}), + "item10": (any_type, {"forceInput": True}), + }, } RETURN_TYPES = ("LIST",) @@ -696,14 +718,13 @@ class Add_To_List: def main(self, **kwargs): new_list = kwargs.get("list", []) new_list = [x for x in new_list if x is not None] - + for key, value in kwargs.items(): - if key.startswith('item') and value is not None: + if key.startswith("item") and value is not None: new_list.append(value) - - return ( - new_list, - ) + + return (new_list,) + class Override_Value_If_Unset: def __init__(self): @@ -713,20 +734,24 @@ class Override_Value_If_Unset: def INPUT_TYPES(s): return { "required": { - "replace_value": ("STRING", { - "default": "0", - "forceInput": True, - }), - "replace_type": (["string", "int", "float", "boolean", "list"], { - "default": "string", - "forceInput": True, - }), + "replace_value": ( + "STRING", + { + "default": "0", + "forceInput": True, + }, + ), + "replace_type": ( + ["string", "int", "float", "boolean", "list"], + { + "default": "string", + "forceInput": True, + }, + ), }, "optional": { - "value": (any_type, { - "forceInput": True - }), - } + "value": (any_type, {"forceInput": True}), + }, } RETURN_TYPES = (any_type,) @@ -737,7 +762,7 @@ class Override_Value_If_Unset: CATEGORY = "Foxpack/Logic" def main(self, replaced_value, replace_type, value): - if value: + if value: return (value,) if replace_type == "string": return (replaced_value,) @@ -750,6 +775,7 @@ class Override_Value_If_Unset: elif replace_type == "list": return ([replaced_value],) + class Pick_Value_From_Dict: def __init__(self): pass @@ -758,19 +784,23 @@ class Pick_Value_From_Dict: def INPUT_TYPES(s): return { "required": { - "values": ("STRING", { - "forceInput": True - }), - "key": ("STRING", { - "default": "", - }), - "default_return": ("STRING", { - "default": "", - }), - "return_type": (["string", "int", "float", "boolean", "list"], - { - "default": "string" - }), + "values": ("STRING", {"forceInput": True}), + "key": ( + "STRING", + { + "default": "", + }, + ), + "default_return": ( + "STRING", + { + "default": "", + }, + ), + "return_type": ( + ["string", "int", "float", "boolean", "list"], + {"default": "string"}, + ), } } @@ -786,9 +816,9 @@ class Pick_Value_From_Dict: dict_str = "{" + values + "}" else: dict_str = values - + dictionary = ast.literal_eval(dict_str) - + value = dictionary.get(key) if value is None: if return_type == "string": @@ -804,23 +834,28 @@ class Pick_Value_From_Dict: return ([default_return],) return (value,) + class Optional_Value_Override: def __init__(self): pass - + @classmethod def INPUT_TYPES(s): return { "required": { - "value": (any_type, { - "forceInput": True - }), - "override_value": ("STRING", { - "default": "", - }), - "override_active": ("BOOLEAN", { - "default": False, - }), + "value": (any_type, {"forceInput": True}), + "override_value": ( + "STRING", + { + "default": "", + }, + ), + "override_active": ( + "BOOLEAN", + { + "default": False, + }, + ), } } @@ -829,22 +864,22 @@ class Optional_Value_Override: CATEGORY = "Foxpack/Logic" FUNCTION = "main" - def main(self, value, override_active, override_value = None): + def main(self, value, override_active, override_value=None): if override_value == None: return (value,) - + return_value = value - if (type(value) == bool): + if isinstance(value, bool): override_value = override_value.lower() == "true" if override_active else value - + return_value = bool(override_value) if override_active else value - elif (type(value) == int): + elif isinstance(value, int): return_value = int(override_value) if override_active else value - elif (type(value) == float): + elif isinstance(value, float): return_value = float(override_value) if override_active else value - elif (type(value) == str): + elif isinstance(value, str): return_value = override_value if override_active else value - elif (type(value) == list): + elif isinstance(value, list): return_value = [override_value] if override_active else value return (return_value,) diff --git a/py/prompter.py b/py/prompter.py index 3b63b6c..34b5314 100644 --- a/py/prompter.py +++ b/py/prompter.py @@ -1,5 +1,6 @@ import re + class Big_Prompter: def __init__(self): pass @@ -8,64 +9,47 @@ class Big_Prompter: def INPUT_TYPES(s): return { "required": { - "is_pony": ("BOOLEAN", { - "default": False, - "forceInput": True, - }), - "char_collection": ("STRING", { - "forceInput": True, - "multiline": True, - "default": "" - }), - "positive_prompt": ("STRING", { - "multiline": True, - "default": "" - }), - "negative_prompt": ("STRING", { - "multiline": True, - "default": "" - }), - "base_pos_prompt": ("STRING", { - "multiline": True, - "default": "cinematic, colorful background, concept art, 8k, dramatic lighting, high detail, highly detailed, hyper realistic, intricate, intricate sharp details, octane render, smooth, studio lighting, trending on artstation, best quality" - }), - "base_neg_prompt": ("STRING", { - "multiline": True, - "default": "worst quality, low quality, text, censored, deformed, bad hand, blurry, (watermark),extra hands, extra dicks, extra fingers , deformed fingers" - }), - "full_wildcard": ("STRING", { - "default": "__a-pure-wc__" - }), - "technical_wildcard": ("STRING", { - "default": "__a-technical-wc__" - }), - "artist_wildcard": ("STRING", { - "default": "__a-artist-wc__" - }), - "use_pos_base": ("BOOLEAN", { - "default": True - }), - "use_neg_base": ("BOOLEAN", { - "default": True - }), - "use_full_wildcard": ("BOOLEAN", { - "default": False - }), - "use_technical_wildcard": ("BOOLEAN", { - "default": False - }), - "use_artist_wildcard": ("BOOLEAN", { - "default": False - }), - "select_character": ("STRING", { - "default": "" - }), - "rating": (["explicit", "questionable", "save", "none"],{ - "default": "save" - }), - "pony_quality": ([0,1,2,3,4], { - "default": 4 - }), + "is_pony": ( + "BOOLEAN", + { + "default": False, + "forceInput": True, + }, + ), + "char_collection": ( + "STRING", + {"forceInput": True, "multiline": True, "default": ""}, + ), + "positive_prompt": ("STRING", {"multiline": True, "default": ""}), + "negative_prompt": ("STRING", {"multiline": True, "default": ""}), + "base_pos_prompt": ( + "STRING", + { + "multiline": True, + "default": "cinematic, colorful background, concept art, 8k, dramatic lighting, high detail, highly detailed, hyper realistic, intricate, intricate sharp details, octane render, smooth, studio lighting, trending on artstation, best quality", + }, + ), + "base_neg_prompt": ( + "STRING", + { + "multiline": True, + "default": "worst quality, low quality, text, censored, deformed, bad hand, blurry, (watermark),extra hands, extra dicks, extra fingers , deformed fingers", + }, + ), + "full_wildcard": ("STRING", {"default": "__a-pure-wc__"}), + "technical_wildcard": ("STRING", {"default": "__a-technical-wc__"}), + "artist_wildcard": ("STRING", {"default": "__a-artist-wc__"}), + "use_pos_base": ("BOOLEAN", {"default": True}), + "use_neg_base": ("BOOLEAN", {"default": True}), + "use_full_wildcard": ("BOOLEAN", {"default": False}), + "use_technical_wildcard": ("BOOLEAN", {"default": False}), + "use_artist_wildcard": ("BOOLEAN", {"default": False}), + "select_character": ("STRING", {"default": ""}), + "rating": ( + ["explicit", "questionable", "save", "none"], + {"default": "save"}, + ), + "pony_quality": ([0, 1, 2, 3, 4], {"default": 4}), } } @@ -78,56 +62,68 @@ class Big_Prompter: return { 4: { "positive": "score_9,score_8_up,score_7_up,score_6_up,score_5_up,score_4_up", - "negative": "score_4" + "negative": "score_4", }, 3: { "positive": "score_8_up,score_7_up,score_6_up,score_5_up,score_4_up", - "negative": "score_4" + "negative": "score_4", }, 2: { "positive": "score_8,score_7_up,score_6_up", - "negative": "score_6,score_5,score_4" + "negative": "score_6,score_5,score_4", }, - 1: { - "positive": "score_9", - "negative": "score_4" - }, - 0: { - "positive": "", - "negative": "" - } + 1: {"positive": "score_9", "negative": "score_4"}, + 0: {"positive": "", "negative": ""}, }.get(pony_quality, 4) - def main(self, is_pony, char_collection, positive_prompt, negative_prompt, base_pos_prompt, base_neg_prompt, full_wildcard, technical_wildcard, artist_wildcard, select_character, rating, pony_quality, use_full_wildcard, use_technical_wildcard, use_artist_wildcard, use_pos_base, use_neg_base): + def main( + self, + is_pony, + char_collection, + positive_prompt, + negative_prompt, + base_pos_prompt, + base_neg_prompt, + full_wildcard, + technical_wildcard, + artist_wildcard, + select_character, + rating, + pony_quality, + use_full_wildcard, + use_technical_wildcard, + use_artist_wildcard, + use_pos_base, + use_neg_base, + ): pony_pos_quality = "" pony_neg_quality = "" - if (is_pony): - pony_pos_quality, pony_neg_quality = self.pony_quality_matrix(pony_quality).values() + if is_pony: + pony_pos_quality, pony_neg_quality = self.pony_quality_matrix( + pony_quality + ).values() - if (use_full_wildcard): + if use_full_wildcard: set_neg_base = base_neg_prompt if use_neg_base else "" pos_prompt = f"{pony_pos_quality},{full_wildcard}" neg_prompt = f"{pony_neg_quality},{base_neg_prompt}" - pos_prompt = re.sub(r',+', ',', pos_prompt).strip(",") - neg_prompt = re.sub(r',+', ',', neg_prompt).strip(",") + pos_prompt = re.sub(r",+", ",", pos_prompt).strip(",") + neg_prompt = re.sub(r",+", ",", neg_prompt).strip(",") - return ( - pos_prompt, - neg_prompt - ) + return (pos_prompt, neg_prompt) set_rating = { "explicit": "rating_explicit", "questionable": "rating_questionable", "save": "rating_safe", - "none": "" + "none": "", }.get(rating, "none") character_details = "" - if (select_character): + if select_character: pattern = rf'!{select_character}="([^"]+)"' match = re.search(pattern, char_collection) @@ -139,15 +135,12 @@ class Big_Prompter: set_pos_base = base_pos_prompt if use_pos_base else "" set_neg_base = base_neg_prompt if use_neg_base else "" - + pos_prompt = f"{pony_pos_quality},{set_rating},{set_pos_base},{set_technical_wildcard},{character_details},{positive_prompt},{set_artist_wildcard}" neg_prompt = f"{pony_neg_quality},{set_neg_base},{negative_prompt}" - pos_prompt = re.sub(r',+', ',', pos_prompt).strip(",") - neg_prompt = re.sub(r',+', ',', neg_prompt).strip(",") + pos_prompt = re.sub(r",+", ",", pos_prompt).strip(",") + neg_prompt = re.sub(r",+", ",", neg_prompt).strip(",") - return ( - pos_prompt, - neg_prompt - ) \ No newline at end of file + return (pos_prompt, neg_prompt) diff --git a/py/smart_checkpoint_setup.py b/py/smart_checkpoint_setup.py index 927743b..9f2a10f 100644 --- a/py/smart_checkpoint_setup.py +++ b/py/smart_checkpoint_setup.py @@ -3,30 +3,34 @@ import folder_paths import os import re + def clamp(value, min_value, max_value): return max(min_value, min(value, max_value)) + def numeric_range(value): if "-" in value: parts = value.split("-") return (float(parts[0]), float(parts[1])) return (float(value), float(value)) + def clamp_in_list(value, lst): if value in list(lst): return value return lst[0] -def extract_setup(checkpoint_setups, cleanup_name, default_setup, delmiter = "/"): + +def extract_setup(checkpoint_setups, cleanup_name, default_setup, delmiter="/"): index = checkpoint_setups.find(cleanup_name) return_string = "" if index == -1: return default_setup - substring = checkpoint_setups[index + len(cleanup_name):] + substring = checkpoint_setups[index + len(cleanup_name) :] - if substring.startswith('='): + if substring.startswith("="): substring = substring[1:] if substring.startswith('"'): @@ -48,6 +52,7 @@ def extract_setup(checkpoint_setups, cleanup_name, default_setup, delmiter = "/" return settings + class CheckpointSelector: @classmethod def INPUT_TYPES(cls): @@ -65,10 +70,7 @@ class CheckpointSelector: def main(self, checkpoint_name): cleanup_name = os.path.splitext(os.path.basename(checkpoint_name))[0] - return ( - checkpoint_name, - str(cleanup_name) - ) + return (checkpoint_name, str(cleanup_name)) class SetupSelector: @@ -78,50 +80,51 @@ class SetupSelector: @classmethod def INPUT_TYPES(cls): return { - "required": { - "checkpoint_name": ("STRING", { - "forceInput": True, - "multiline": False - }), - "checkpoint_setups": ("STRING", { - "forceInput": True, - "multiline": True - }), - "setup_prefix": ("STRING", { - "default": "!", - "multiline": False - }), - "delmiter": ("STRING", { - "default": "/", - "multiline": False - }), - "default_setup": ("STRING", { - "default": "5/20/karras/dpmpp_2m", - "multiline": False - }), - "default_meta": ("STRING", { - "default": "0,-2,0", - "multiline": False - }) - } + "required": { + "checkpoint_name": ("STRING", {"forceInput": True, "multiline": False}), + "checkpoint_setups": ("STRING", {"forceInput": True, "multiline": True}), + "setup_prefix": ("STRING", {"default": "!", "multiline": False}), + "delmiter": ("STRING", {"default": "/", "multiline": False}), + "default_setup": ( + "STRING", + {"default": "5/20/karras/dpmpp_2m", "multiline": False}, + ), + "default_meta": ("STRING", {"default": "0,-2,0", "multiline": False}), + } } - RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING","STRING", "LIST", "STRING") - RETURN_NAMES = ("set_cfg", "set_steps", "set_scheduler", "set_sampler", "setup_text", "setup", "meta") + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", "LIST", "STRING") + RETURN_NAMES = ( + "set_cfg", + "set_steps", + "set_scheduler", + "set_sampler", + "setup_text", + "setup", + "meta", + ) FUNCTION = "main" # OUTPUT_NODE = True CATEGORY = "Foxpack/Smart Sampler Setup" - def main(self, checkpoint_name, checkpoint_setups, setup_prefix, delmiter, default_setup, default_meta): + def main( + self, + checkpoint_name, + checkpoint_setups, + setup_prefix, + delmiter, + default_setup, + default_meta, + ): return_string = "" prefixed_name = str(setup_prefix) + str(checkpoint_name) index = checkpoint_setups.find(prefixed_name) if index != -1: - if checkpoint_setups[index + len(prefixed_name)] == '=': + if checkpoint_setups[index + len(prefixed_name)] == "=": if checkpoint_setups[index + len(prefixed_name) + 1] == '"': start_quote = index + len(prefixed_name) + 2 end_quote = checkpoint_setups.find('"', start_quote + 1) @@ -131,9 +134,9 @@ class SetupSelector: else: space_index = checkpoint_setups.find(" ", index + len(prefixed_name)) if space_index != -1: - return_string = checkpoint_setups[index + len(prefixed_name):space_index] + return_string = checkpoint_setups[index + len(prefixed_name) : space_index] else: - return_string = checkpoint_setups[index + len(prefixed_name):] + return_string = checkpoint_setups[index + len(prefixed_name) :] else: return_string = prefixed_name[1:] @@ -145,11 +148,11 @@ class SetupSelector: settings = return_string.split(delmiter) - if (len(settings) < 5): - # meta infos: version (0:sdxl, 1:sd15), clip, vae (0: baked, 1: sdxl load vae, 2: sd15 load vae) - meta = default_meta + if len(settings) < 5: + # meta infos: version (0:sdxl, 1:sd15), clip, vae (0: baked, 1: sdxl load vae, 2: sd15 load vae) + meta = default_meta else: - meta = settings[4] + meta = settings[4] setup = list(settings) setup_text = f"cfg: {settings[0]} | steps: {settings[1]} | scheduler: {settings[2]} | sampler: {settings[3]}" @@ -161,8 +164,10 @@ class SetupSelector: str(settings[3]), str(setup_text), list(setup), - str(meta) + str(meta), ) + + class CheckpointMetaExtractor: def __init__(self): pass @@ -171,10 +176,7 @@ class CheckpointMetaExtractor: def INPUT_TYPES(cls): return { "required": { - "meta": ("STRING", { - "forceInput": True, - "multiline": False - }), + "meta": ("STRING", {"forceInput": True, "multiline": False}), } } @@ -191,49 +193,43 @@ class CheckpointMetaExtractor: clip = int(meta[1]) vae = meta[2] - return ( - int(version), - int(-abs(clip)), - int(vae) - ) + return (int(version), int(-abs(clip)), int(vae)) + class BaseSamplerSetup: def __init__(self): pass @classmethod - def INPUT_TYPES(s): return { "required": { - "setup": ("LIST", { - "forceInput": True - }), - "cfg": ("FLOAT", { - "default": 1.0, - "min": 0.0, - "max": 16.0, - "step": 0.1, - "display": "number" - }), - "steps": ("INT", { - "default": 5, - "min": 1, - "max": 100, - "step": 1, - "display": "number" - }), + "setup": ("LIST", {"forceInput": True}), + "cfg": ( + "FLOAT", + {"default": 1.0, "min": 0.0, "max": 16.0, "step": 0.1, "display": "number"}, + ), + "steps": ( + "INT", + {"default": 5, "min": 1, "max": 100, "step": 1, "display": "number"}, + ), "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), "sampler": (comfy.samplers.KSampler.SAMPLERS,), } } RETURN_TYPES = ("FLOAT", "INT", "STRING", "STRING", "STRING", "LIST") - RETURN_NAMES = ("cfg", "steps", "scheduler", "sampler", "setup_text", "selected_setup") + RETURN_NAMES = ( + "cfg", + "steps", + "scheduler", + "sampler", + "setup_text", + "selected_setup", + ) FUNCTION = "main" def main(self, setup, cfg, steps, scheduler, sampler): - cfg_range = numeric_range(setup[0]) clamp_cfg = clamp(cfg, cfg_range[0], cfg_range[1]) @@ -252,149 +248,164 @@ class BaseSamplerSetup: str(clamp_scheduler), str(clamp_sampler), str(setup_text), - list(selected_setup) + list(selected_setup), ) CATEGORY = "Foxpack/Smart Sampler Setup" class OverrideSamplerSetup: - def __init__(self): - pass + def __init__(self): + pass - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "setup": ("LIST", { - "forceInput": True - }), - "override": ("BOOLEAN", {"default": False}), - "cfg": ("FLOAT", { - "default": 1.0, - "min": 0.0, - "max": 16.0, - "step": 0.1, - "display": "number" - }), - "steps": ("INT", { - "default": 5, - "min": 1, - "max": 100, - "step": 1, - "display": "number" - }), - "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), - "sampler": (comfy.samplers.KSampler.SAMPLERS,), - }, - } + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "setup": ("LIST", {"forceInput": True}), + "override": ("BOOLEAN", {"default": False}), + "cfg": ( + "FLOAT", + {"default": 1.0, "min": 0.0, "max": 16.0, "step": 0.1, "display": "number"}, + ), + "steps": ( + "INT", + {"default": 5, "min": 1, "max": 100, "step": 1, "display": "number"}, + ), + "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), + "sampler": (comfy.samplers.KSampler.SAMPLERS,), + }, + } - RETURN_TYPES = ("FLOAT","INT", comfy.samplers.KSampler.SAMPLERS, - comfy.samplers.KSampler.SCHEDULERS, "STRING") - RETURN_NAMES = ("cfg", "steps", "sampler", "scheduler", "setup_text") - FUNCTION = "main" + RETURN_TYPES = ( + "FLOAT", + "INT", + comfy.samplers.KSampler.SAMPLERS, + comfy.samplers.KSampler.SCHEDULERS, + "STRING", + ) + RETURN_NAMES = ("cfg", "steps", "sampler", "scheduler", "setup_text") + FUNCTION = "main" - def main(self, override, setup, steps, cfg, sampler, scheduler): - cfg_output = cfg if override else setup[0] - steps_output = steps if override else setup[1] - scheduler_output = scheduler if override else setup[2] - sampler_output = sampler if override else setup[3] + def main(self, override, setup, steps, cfg, sampler, scheduler): + cfg_output = cfg if override else setup[0] + steps_output = steps if override else setup[1] + scheduler_output = scheduler if override else setup[2] + sampler_output = sampler if override else setup[3] - setup_text = f"cfg: {cfg_output} | steps: {steps_output} | scheduler: {scheduler_output} | sampler: {sampler_output}" + setup_text = f"cfg: {cfg_output} | steps: {steps_output} | scheduler: {scheduler_output} | sampler: {sampler_output}" - return ( - float(cfg_output), - int(steps_output), - sampler_output, - scheduler_output, - str(setup_text) - ) + return ( + float(cfg_output), + int(steps_output), + sampler_output, + scheduler_output, + str(setup_text), + ) + + CATEGORY = "Foxpack/Smart Sampler Setup" - CATEGORY = "Foxpack/Smart Sampler Setup" class Complete_Setup: @classmethod def INPUT_TYPES(cls): return { "required": { - "checkpoint_setups": ("STRING", { - "forceInput": True, - "multiline": True - }), + "checkpoint_setups": ("STRING", {"forceInput": True, "multiline": True}), "checkpoint_name": (folder_paths.get_filename_list("checkpoints"),), - "cfg": ("FLOAT", { - "default": 5.0, - "min": 0.0, - "max": 16.0, - "step": 0.1, - "display": "number" - }), - "steps": ("INT", { - "default": 20, - "min": 1, - "max": 100, - "step": 1, - "display": "number" - }), - "scheduler": (comfy.samplers.KSampler.SCHEDULERS, { - "default": "karras" - }), - "sampler": (comfy.samplers.KSampler.SAMPLERS, { - "default": "dpmpp_2m" - }), + "cfg": ( + "FLOAT", + {"default": 5.0, "min": 0.0, "max": 16.0, "step": 0.1, "display": "number"}, + ), + "steps": ( + "INT", + {"default": 20, "min": 1, "max": 100, "step": 1, "display": "number"}, + ), + "scheduler": (comfy.samplers.KSampler.SCHEDULERS, {"default": "karras"}), + "sampler": (comfy.samplers.KSampler.SAMPLERS, {"default": "dpmpp_2m"}), "override": ("BOOLEAN", {"default": False}), - "cfg_override": ("FLOAT", { - "default": 5.0, - "min": 0.0, - "max": 16.0, - "step": 0.1, - "display": "number" - }), - "steps_override": ("INT", { - "default": 20, - "min": 1, - "max": 100, - "step": 1, - "display": "number" - }), - "scheduler_override": (comfy.samplers.KSampler.SCHEDULERS, { - "default": "karras" - }), - "sampler_override": (comfy.samplers.KSampler.SAMPLERS, { - "default": "dpmpp_2m" - }), + "cfg_override": ( + "FLOAT", + {"default": 5.0, "min": 0.0, "max": 16.0, "step": 0.1, "display": "number"}, + ), + "steps_override": ( + "INT", + {"default": 20, "min": 1, "max": 100, "step": 1, "display": "number"}, + ), + "scheduler_override": ( + comfy.samplers.KSampler.SCHEDULERS, + {"default": "karras"}, + ), + "sampler_override": (comfy.samplers.KSampler.SAMPLERS, {"default": "dpmpp_2m"}), }, - "optional": { - "optional_setups": ("STRING", { - "default": "", - "multiline": True - }) - } + "optional": {"optional_setups": ("STRING", {"default": "", "multiline": True})}, } - RETURN_TYPES = (folder_paths.get_filename_list("checkpoints"),"STRING", "STRING", "INT", "INT", "INT", "FLOAT","INT", comfy.samplers.KSampler.SAMPLERS, comfy.samplers.KSampler.SCHEDULERS, "LIST", "STRING", "STRING") - RETURN_NAMES = ("ckpt_name", "recommended_setup_str", "used_setup_str", "version", "clip", "vae_variant", "cfg", "steps", "sampler", "scheduler", "meta_list", "opt_setup_dict", "comb_sampler_settings") + RETURN_TYPES = ( + folder_paths.get_filename_list("checkpoints"), + "STRING", + "STRING", + "INT", + "INT", + "INT", + "FLOAT", + "INT", + comfy.samplers.KSampler.SAMPLERS, + comfy.samplers.KSampler.SCHEDULERS, + "LIST", + "STRING", + "STRING", + ) + RETURN_NAMES = ( + "ckpt_name", + "recommended_setup_str", + "used_setup_str", + "version", + "clip", + "vae_variant", + "cfg", + "steps", + "sampler", + "scheduler", + "meta_list", + "opt_setup_dict", + "comb_sampler_settings", + ) FUNCTION = "main" CATEGORY = "Foxpack/Smart Sampler Setup" - def main(self, checkpoint_setups, checkpoint_name, cfg, steps, scheduler, sampler, override, cfg_override, steps_override, scheduler_override, sampler_override, optional_setups): + def main( + self, + checkpoint_setups, + checkpoint_name, + cfg, + steps, + scheduler, + sampler, + override, + cfg_override, + steps_override, + scheduler_override, + sampler_override, + optional_setups, + ): cleanup_name = os.path.splitext(os.path.basename(checkpoint_name))[0] settings = "" selected_optional_setup = "{}" used_default_setup = False - - if (cleanup_name): - pattern = rf'!{cleanup_name}:(.+)' - pattern_optional = rf'!{cleanup_name}:(.+)' - + + if cleanup_name: + pattern = rf"!{cleanup_name}:(.+)" + pattern_optional = rf"!{cleanup_name}:(.+)" + match = re.search(pattern, checkpoint_setups) match_optional = re.search(pattern_optional, optional_setups) - + if match: settings = match.group(1).split("/") else: - pattern = rf'!DEFAULT:(.+)' + pattern = rf"!DEFAULT:(.+)" match = re.search(pattern, checkpoint_setups) used_default_setup = True if match: @@ -415,15 +426,11 @@ class Complete_Setup: vae_variant = settings[6] vae_string = "baked" if vae_variant == 0 else "external" - versionname = { - "0": "sdxl", - "1": "sd15", - "2": "flux" - }.get(version, "sdxl") + versionname = {"0": "sdxl", "1": "sd15", "2": "flux"}.get(version, "sdxl") used_default_setup_str = " (used default setup)" if used_default_setup else "" recommended_setup_str = f"Checkpoint ({versionname}): {cleanup_name}{used_default_setup_str}\ncfg: {settings[0]}, steps: {settings[1]}, scheduler: {settings[2]}, sampler: {settings[3]}\nvae: {vae_string}, clip: {clip}, version: {version}" - + cfg_range = numeric_range(settings[0]) clamp_cfg = clamp(cfg, cfg_range[0], cfg_range[1]) steps_range = numeric_range(settings[1]) @@ -440,10 +447,11 @@ class Complete_Setup: used_setup_str = f"Checkpoint ({versionname}): {cleanup_name}{is_override}\ncfg: {cfg_output}, steps: {int(steps_output)}, scheduler: {scheduler_output}, sampler: {sampler_output}" - filename = f"%date_%seed_%counter_{versionname}" - sampler_settings = f"{cfg_output},{int(steps_output)},{sampler_output},{scheduler_output}" + sampler_settings = ( + f"{cfg_output},{int(steps_output)},{sampler_output},{scheduler_output}" + ) meta_list = [ checkpoint_name, @@ -451,7 +459,7 @@ class Complete_Setup: float(cfg_output), int(steps_output), sampler_output, - scheduler_output + scheduler_output, ] return ( @@ -467,5 +475,5 @@ class Complete_Setup: scheduler_output, meta_list, selected_optional_setup, - sampler_settings + sampler_settings, ) diff --git a/py/upscale_helper.py b/py/upscale_helper.py index d63717c..61c0c2d 100644 --- a/py/upscale_helper.py +++ b/py/upscale_helper.py @@ -4,11 +4,14 @@ import re import numpy as np import ast + class AnyType(str): - def __ne__(self, __value: object) -> bool: - return False + def __ne__(self, __value: object) -> bool: + return False + any_type = AnyType("*") + class Step_Denoise: def __init__(self): pass @@ -17,42 +20,58 @@ class Step_Denoise: def INPUT_TYPES(s): return { "required": { - "image_type": (["Abstract", "Landscapes", "People","Free1","Free2","Free3"], + "image_type": ( + ["Abstract", "Landscapes", "People", "Free1", "Free2", "Free3"], { "default": "Landscapes", - } + }, + ), + "max_steps": ( + "INT", + {"default": 4, "min": 1, "max": 10, "step": 1, "display": "number"}, + ), + "abstract_rules": ( + "STRING", + { + "default": "0.60,0.55,0.45,0.40", + "multiline": False, + }, + ), + "landscape_rules": ( + "STRING", + { + "default": "0.50,0.45,0.40,0.35", + "multiline": False, + }, + ), + "people_rules": ( + "STRING", + { + "default": "0.35,0.30,0.25,0.20", + "multiline": False, + }, + ), + "free_rules1": ( + "STRING", + { + "default": "0.7", + "multiline": False, + }, + ), + "free_rules2": ( + "STRING", + { + "default": "0.6-0.2", + "multiline": False, + }, + ), + "free_rules3": ( + "STRING", + { + "default": "0.33-0.25", + "multiline": False, + }, ), - "max_steps": ("INT", { - "default": 4, - "min": 1, - "max": 10, - "step": 1, - "display": "number" - }), - "abstract_rules": ("STRING", { - "default": "0.60,0.55,0.45,0.40", - "multiline": False, - }), - "landscape_rules": ("STRING", { - "default": "0.50,0.45,0.40,0.35", - "multiline": False, - }), - "people_rules": ("STRING", { - "default": "0.35,0.30,0.25,0.20", - "multiline": False, - }), - "free_rules1": ("STRING", { - "default": "0.7", - "multiline": False, - }), - "free_rules2": ("STRING", { - "default": "0.6-0.2", - "multiline": False, - }), - "free_rules3": ("STRING", { - "default": "0.33-0.25", - "multiline": False, - }), } } @@ -62,14 +81,24 @@ class Step_Denoise: FUNCTION = "main" CATEGORY = "Foxpack/Upscale" - def main(self, image_type, free_rules1, free_rules2, free_rules3, max_steps, abstract_rules, landscape_rules, people_rules): + def main( + self, + image_type, + free_rules1, + free_rules2, + free_rules3, + max_steps, + abstract_rules, + landscape_rules, + people_rules, + ): rules_dict = { "Free1": free_rules1, "Free2": free_rules2, "Free3": free_rules3, "Abstract": abstract_rules, "Landscapes": landscape_rules, - "People": people_rules + "People": people_rules, } rules = rules_dict.get(image_type, "").split(",") @@ -83,9 +112,8 @@ class Step_Denoise: rules_str = ",".join(rules) - return ( - rules_str, - ) + return (rules_str,) + class Refine_Setup: def __init__(self): @@ -95,49 +123,67 @@ class Refine_Setup: def INPUT_TYPES(s): return { "required": { - "sampler_setup": ("STRING", { - "forceInput": True, - }), - "disable_override": ("BOOLEAN", { - "default": True, - }), - "select_scheduler": (["internal"] + comfy.samplers.KSampler.SCHEDULERS, { - "default": "internal", - }), - "select_sampler": (["internal"] + comfy.samplers.KSampler.SAMPLERS, { - "default": "internal", - }), - "select_cfg": ("FLOAT", { - "default": 0.0, - "min": 0.0, - "max": 16.0, - "step": 0.1, - "display": "number" - }), - "select_steps": ("INT", { - "default": 0, - "min": 0, - "max": 100, - "step": 1, - "display": "number" - }) + "sampler_setup": ( + "STRING", + { + "forceInput": True, + }, + ), + "disable_override": ( + "BOOLEAN", + { + "default": True, + }, + ), + "select_scheduler": ( + ["internal"] + comfy.samplers.KSampler.SCHEDULERS, + { + "default": "internal", + }, + ), + "select_sampler": ( + ["internal"] + comfy.samplers.KSampler.SAMPLERS, + { + "default": "internal", + }, + ), + "select_cfg": ( + "FLOAT", + {"default": 0.0, "min": 0.0, "max": 16.0, "step": 0.1, "display": "number"}, + ), + "select_steps": ( + "INT", + {"default": 0, "min": 0, "max": 100, "step": 1, "display": "number"}, + ), }, "optional": { - "refine_setup": ("STRING", { - "default": "{}" - }), - } + "refine_setup": ("STRING", {"default": "{}"}), + }, } - RETURN_TYPES = ("FLOAT", "INT", comfy.samplers.KSampler.SAMPLERS, comfy.samplers.KSampler.SCHEDULERS) + RETURN_TYPES = ( + "FLOAT", + "INT", + comfy.samplers.KSampler.SAMPLERS, + comfy.samplers.KSampler.SCHEDULERS, + ) RETURN_NAMES = ("cfg", "steps", "sampler", "scheduler") FUNCTION = "main" CATEGORY = "Foxpack/Upscale" - def main(self,sampler_setup, select_scheduler, select_sampler, select_cfg, select_steps, disable_override, refine_setup): + def main( + self, + sampler_setup, + select_scheduler, + select_sampler, + select_cfg, + select_steps, + disable_override, + refine_setup, + ): used = sampler_setup.split(",") - + if disable_override: return ( float(used[0]), @@ -145,12 +191,12 @@ class Refine_Setup: used[2], used[3], ) - + return_cfg = float(used[0]) if select_cfg == 0.0 else select_cfg return_steps = int(used[1]) if select_steps == 0 else select_steps return_sampler = used[2] if select_sampler == "internal" else select_sampler return_scheduler = used[3] if select_scheduler == "internal" else select_scheduler - + if refine_setup and not re.search(r"\{.*\}", refine_setup): refine_setup = "{" + refine_setup + "}" @@ -167,13 +213,8 @@ class Refine_Setup: if "steps" in dictionary: return_steps = dictionary["steps"] + return (float(return_cfg), int(return_steps), return_sampler, return_scheduler) - return ( - float(return_cfg), - int(return_steps), - return_sampler, - return_scheduler - ) class Refine_Prompt: def __init__(self): @@ -184,25 +225,25 @@ class Refine_Prompt: return { "required": { "clip": ("CLIP",), - "pos_prompt": ("CONDITIONING", { - "forceInput": True, - }), - "neg_prompt": ("CONDITIONING", { - "forceInput": True, - }), - "refine_prompt_pos": ("STRING", { - "multiline": True, - "default": "" - }), - "refine_prompt_neg": ("STRING", { - "multiline": True, - "default": "" - }), + "pos_prompt": ( + "CONDITIONING", + { + "forceInput": True, + }, + ), + "neg_prompt": ( + "CONDITIONING", + { + "forceInput": True, + }, + ), + "refine_prompt_pos": ("STRING", {"multiline": True, "default": ""}), + "refine_prompt_neg": ("STRING", {"multiline": True, "default": ""}), } } RETURN_TYPES = ("CONDITIONING", "CONDITIONING") - RETURN_NAMES = ("pos_prompt","neg_prompt") + RETURN_NAMES = ("pos_prompt", "neg_prompt") FUNCTION = "main" CATEGORY = "Foxpack/Upscale" @@ -213,8 +254,4 @@ class Refine_Prompt: combined_pos_cond = pos_prompt + additional_pos_cond[0] combined_neg_cond = neg_prompt + additional_neg_cond[0] - - return ( - combined_pos_cond, - combined_neg_cond - ) + return (combined_pos_cond, combined_neg_cond) diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..43ab96e --- /dev/null +++ b/ruff.toml @@ -0,0 +1,77 @@ +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] + +# Same as Black. +line-length = 88 +indent-width = 2 + +# Assume Python 3.8 +target-version = "py38" + +[lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or +# McCabe complexity (`C901`) by default. +select = ["E4", "E7", "E9", "F"] +ignore = [] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" + +# Enable auto-formatting of code examples in docstrings. Markdown, +# reStructuredText code/literal blocks and doctests are all supported. +# +# This is currently disabled by default, but it is planned for this +# to be opt-out in the future. +docstring-code-format = false + +# Set the line length limit used when formatting code snippets in +# docstrings. +# +# This only has an effect when the `docstring-code-format` setting is +# enabled. +docstring-code-line-length = "dynamic"