diff --git a/__init__.py b/__init__.py index 0218b25..5be8c60 100644 --- a/__init__.py +++ b/__init__.py @@ -10,14 +10,29 @@ import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) -from .ppp_comfyui import PromptPostProcessorComfyUINode, PromptPostProcessorSelectVariableComfyUINode +from .ppp_comfyui import ( + PromptPostProcessorComfyUINode, + PromptPostProcessorWildcardOptionsComfyUINode, + PromptPostProcessorENMappingOptionsComfyUINode, + PromptPostProcessorSTNOptionsComfyUINode, + PromptPostProcessorCleanupOptionsComfyUINode, + PromptPostProcessorSelectVariableComfyUINode, +) NODE_CLASS_MAPPINGS = { "ACBPromptPostProcessor": PromptPostProcessorComfyUINode, + "ACBPPPWildcardOptions": PromptPostProcessorWildcardOptionsComfyUINode, + "ACBPPPENMappingOptions": PromptPostProcessorENMappingOptionsComfyUINode, + "ACBPPPSendToNegativeOptions": PromptPostProcessorSTNOptionsComfyUINode, + "ACBPPPCleanupOptions": PromptPostProcessorCleanupOptionsComfyUINode, "ACBPPPSelectVariable": PromptPostProcessorSelectVariableComfyUINode, } NODE_DISPLAY_NAME_MAPPINGS = { "ACBPromptPostProcessor": "ACB Prompt Post Processor", + "ACBPPPWildcardOptions": "ACB PPP Wildcard Options", + "ACBPPPENMappingOptions": "ACB PPP ExtraNetwork Mapping Options", + "ACBPPPSendToNegativeOptions": "ACB PPP Send-To-Negative Options", + "ACBPPPCleanupOptions": "ACB PPP Cleanup Options", "ACBPPPSelectVariable": "ACB PPP Select Variable", } diff --git a/ppp.py b/ppp.py index 80d8558..a0c0acb 100644 --- a/ppp.py +++ b/ppp.py @@ -68,9 +68,28 @@ class PromptPostProcessor: # pylint: disable=too-few-public-methods,too-many-in warn = "warn" stop = "stop" + DEFAULT_DEBUG_LEVEL = DEBUG_LEVEL.minimal.value + DEFAULT_ONWARNING = ONWARNING_CHOICES.warn.value DEFAULT_STN_SEPARATOR = ", " + DEFAULT_STN_IGNORE_REPEATS = True DEFAULT_VARIANTS_DEFINITIONS = "pony(sdxl)=pony,pny,pdxl\nillustrious(sdxl)=illustrious,illust,ilxl" + DEFAULT_WC_PROCESS = True + DEFAULT_IF_WILDCARDS = IFWILDCARDS_CHOICES.stop.value DEFAULT_CHOICE_SEPARATOR = ", " + DEFAULT_KEEP_CHOICES_ORDER = True + DEFAULT_DO_CLEANUP = (True,) + DEFAULT_CUP_EXTRA_SPACES = True + DEFAULT_CUP_EMPTY_CONSTRUCTS = True + DEFAULT_CUP_EXTRA_SEPARATORS = True + DEFAULT_CUP_EXTRA_SEPARATORS2 = True + DEFAULT_CUP_EXTRA_SEPARATORS_INCLUDE_EOL = False + DEFAULT_CUP_BREAKS = False + DEFAULT_CUP_BREAKS_EOL = False + DEFAULT_CUP_ANDS = False + DEFAULT_CUP_ANDS_EOL = False + DEFAULT_CUP_EXTRANETWORK_TAGS = False + DEFAULT_CUP_MERGE_ATTENTION = True + DEFAULT_CUP_REMOVE_EXTRANETWORK_TAGS = False WILDCARD_WARNING = '(WARNING TEXT "INVALID WILDCARD" IN BRIGHT RED:1.5)\nBREAK ' WILDCARD_STOP = "INVALID WILDCARD! {0}\nBREAK " UNPROCESSED_STOP = "UNPROCESSED CONSTRUCTS!\nBREAK " @@ -116,8 +135,8 @@ class PromptPostProcessor: # pylint: disable=too-few-public-methods,too-many-in self.extranetwork_mappings_obj = extranetwork_mappings_obj # General options - self.debug_level = DEBUG_LEVEL(options.get("debug_level", DEBUG_LEVEL.none.value)) - self.gen_onwarning = self.ONWARNING_CHOICES(options.get("on_warning", self.ONWARNING_CHOICES.warn.value)) + self.debug_level = DEBUG_LEVEL(options.get("debug_level", self.DEFAULT_DEBUG_LEVEL)) + self.gen_onwarning = self.ONWARNING_CHOICES(options.get("on_warning", self.DEFAULT_ONWARNING)) variants_definitions_option = str(options.get("variants_definitions", self.DEFAULT_VARIANTS_DEFINITIONS)) self.variants_definitions = {} if variants_definitions_option: @@ -138,29 +157,43 @@ class PromptPostProcessor: # pylint: disable=too-few-public-methods,too-many-in [element.strip() for element in elements.split(",")], ) # Wildcards options - self.wil_process_wildcards = options.get("process_wildcards", True) - self.wil_keep_choices_order = options.get("keep_choices_order", False) + self.wil_process_wildcards = options.get("process_wildcards", self.DEFAULT_WC_PROCESS) + self.wil_keep_choices_order = options.get("keep_choices_order", self.DEFAULT_KEEP_CHOICES_ORDER) self.wil_choice_separator = options.get("choice_separator", self.DEFAULT_CHOICE_SEPARATOR) - self.wil_ifwildcards = self.IFWILDCARDS_CHOICES( - options.get("if_wildcards", self.IFWILDCARDS_CHOICES.stop.value) - ) + self.wil_ifwildcards = self.IFWILDCARDS_CHOICES(options.get("if_wildcards", self.DEFAULT_IF_WILDCARDS)) # Send to negative options - self.stn_ignore_repeats = options.get("stn_ignore_repeats", True) + self.stn_ignore_repeats = options.get("stn_ignore_repeats", self.DEFAULT_STN_IGNORE_REPEATS) self.stn_separator = options.get("stn_separator", self.DEFAULT_STN_SEPARATOR) - # Cleanup options - self.cup_extraspaces = options.get("cleanup_extra_spaces", True) - self.cup_emptyconstructs = options.get("cleanup_empty_constructs", True) - self.cup_extraseparators = options.get("cleanup_extra_separators", True) - self.cup_extraseparators2 = options.get("cleanup_extra_separators2", True) - self.cup_extraseparators_include_eol = options.get("cleanup_extra_separators_include_eol", False) - self.cup_breaks = options.get("cleanup_breaks", True) - self.cup_breaks_eol = options.get("cleanup_breaks_eol", False) - self.cup_ands = options.get("cleanup_ands", True) - self.cup_ands_eol = options.get("cleanup_ands_eol", False) - self.cup_extranetworktags = options.get("cleanup_extranetwork_tags", False) - self.cup_mergeattention = options.get("cleanup_merge_attention", True) - # Remove options - self.rem_removeextranetworktags = options.get("remove_extranetwork_tags", False) + # Cleanup and remove options + self.cup_do_cleanup = options.get("do_cleanup", self.DEFAULT_DO_CLEANUP) + self.cup_extraspaces = self.cup_do_cleanup and options.get( + "cleanup_extra_spaces", self.DEFAULT_CUP_EXTRA_SPACES + ) + self.cup_emptyconstructs = self.cup_do_cleanup and options.get( + "cleanup_empty_constructs", self.DEFAULT_CUP_EMPTY_CONSTRUCTS + ) + self.cup_extraseparators = self.cup_do_cleanup and options.get( + "cleanup_extra_separators", self.DEFAULT_CUP_EXTRA_SEPARATORS + ) + self.cup_extraseparators2 = self.cup_do_cleanup and options.get( + "cleanup_extra_separators2", self.DEFAULT_CUP_EXTRA_SEPARATORS2 + ) + self.cup_extraseparators_include_eol = self.cup_do_cleanup and options.get( + "cleanup_extra_separators_include_eol", self.DEFAULT_CUP_EXTRA_SEPARATORS_INCLUDE_EOL + ) + self.cup_breaks = self.cup_do_cleanup and options.get("cleanup_breaks", self.DEFAULT_CUP_BREAKS) + self.cup_breaks_eol = self.cup_do_cleanup and options.get("cleanup_breaks_eol", self.DEFAULT_CUP_BREAKS_EOL) + self.cup_ands = self.cup_do_cleanup and options.get("cleanup_ands", self.DEFAULT_CUP_ANDS) + self.cup_ands_eol = self.cup_do_cleanup and options.get("cleanup_ands_eol", self.DEFAULT_CUP_ANDS_EOL) + self.cup_extranetworktags = self.cup_do_cleanup and options.get( + "cleanup_extranetwork_tags", self.DEFAULT_CUP_EXTRANETWORK_TAGS + ) + self.cup_mergeattention = self.cup_do_cleanup and options.get( + "cleanup_merge_attention", self.DEFAULT_CUP_MERGE_ATTENTION + ) + self.rem_removeextranetworktags = self.cup_do_cleanup and options.get( + "remove_extranetwork_tags", self.DEFAULT_CUP_REMOVE_EXTRANETWORK_TAGS + ) # if self.debug_level != DEBUG_LEVEL.none: # self.logger.info(f"Detected environment info: {env_info}") @@ -1381,7 +1414,9 @@ class PromptPostProcessor: # pylint: disable=too-few-public-methods,too-many-in self.result += starttag self.__visit(current_tree) endtag = f":{weight_str})" - if self.__ppp.cup_emptyconstructs and re.fullmatch(re.escape(start_result + starttag) + r"\s*", self.result): + if self.__ppp.cup_emptyconstructs and re.fullmatch( + re.escape(start_result + starttag) + r"\s*", self.result + ): self.result = start_result else: self.result += endtag diff --git a/ppp_comfyui.py b/ppp_comfyui.py index 669504b..6794c81 100644 --- a/ppp_comfyui.py +++ b/ppp_comfyui.py @@ -80,22 +80,41 @@ class PromptPostProcessorComfyUINode: "INT", { "default": -1, + "tooltip": "Seed value for the prompt processing (use -1 for random)", }, ), "debug_level": ( [e.value for e in DEBUG_LEVEL], { - "default": DEBUG_LEVEL.minimal.value, + "default": PromptPostProcessor.DEFAULT_DEBUG_LEVEL, "tooltip": "Debug level", }, ), "on_warnings": ( [e.value for e in PromptPostProcessor.ONWARNING_CHOICES], { - "default": PromptPostProcessor.ONWARNING_CHOICES.warn.value, + "default": PromptPostProcessor.DEFAULT_ONWARNING, "tooltip": "How to handle invalid content warnings", }, ), + "process_wildcards": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_WC_PROCESS, + "tooltip": "Process wildcards in the prompt", + "label_on": "Yes", + "label_off": "No", + }, + ), + "do_cleanup": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_DO_CLEANUP, + "tooltip": "Do a cleanup of the prompt", + "label_on": "Yes", + "label_off": "No", + }, + ), "variants_definitions": ( "STRING", { @@ -106,198 +125,32 @@ class PromptPostProcessorComfyUINode: "dynamicPrompts": False, }, ), - "wc_process_wildcards": ( - "BOOLEAN", + "wc_options": ( + "PPP_OPTIONS_WC", { - "default": True, - "tooltip": "Process wildcards in the prompt", - "label_on": "Yes", - "label_off": "No", + "forceInput": True, + "tooltip": "Wildcard processing options", }, ), - "wc_wildcards_folders": ( - "STRING", + "stn_options": ( + "PPP_OPTIONS_STN", { - "default": "", - "tooltip": "Comma separated list of wildcards folders", - "dynamicPrompts": False, + "forceInput": True, + "tooltip": "Send-To-Negative options", }, ), - "wc_wildcards_input": ( - "STRING", + "cup_options": ( + "PPP_OPTIONS_CUP", { - "default": "", - "multiline": True, - "placeholder": "wildcards definitions", - "tooltip": "Wildcards definitions in yaml/json format", - "dynamicPrompts": False, + "forceInput": True, + "tooltip": "Cleanup options", }, ), - "wc_if_wildcards": ( - [e.value for e in PromptPostProcessor.IFWILDCARDS_CHOICES], + "en_options": ( + "PPP_OPTIONS_EN", { - "default": PromptPostProcessor.IFWILDCARDS_CHOICES.stop.value, - "tooltip": "How to handle invalid wildcards in the prompt", - }, - ), - "wc_choice_separator": ( - "STRING", - { - "default": PromptPostProcessor.DEFAULT_CHOICE_SEPARATOR, - "tooltip": "Default separator for selected choices", - "dynamicPrompts": False, - }, - ), - "wc_keep_choices_order": ( - "BOOLEAN", - { - "default": True, - "tooltip": "Keep the order of the choices in the prompt", - "label_on": "Yes", - "label_off": "No", - }, - ), - "stn_separator": ( - "STRING", - { - "default": PromptPostProcessor.DEFAULT_STN_SEPARATOR, - "tooltip": "Separator for the content added to the negative prompt", - "dynamicPrompts": False, - }, - ), - "stn_ignore_repeats": ( - "BOOLEAN", - { - "default": True, - "tooltip": "Ignore repeated content added to the negative prompt", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_extra_spaces": ( - "BOOLEAN", - { - "default": True, - "tooltip": "Remove extra spaces", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_empty_constructs": ( - "BOOLEAN", - { - "default": True, - "tooltip": "Remove empty constructs", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_extra_separators": ( - "BOOLEAN", - { - "default": True, - "tooltip": "Remove extra separators", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_extra_separators2": ( - "BOOLEAN", - { - "default": True, - "tooltip": "Remove extra separators (additional cases)", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_extra_separators_include_eol": ( - "BOOLEAN", - { - "default": False, - "tooltip": "Extra separators options also remove EOLs", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_breaks": ( - "BOOLEAN", - { - "default": False, - "tooltip": "Cleanup around BREAKs", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_breaks_eol": ( - "BOOLEAN", - { - "default": False, - "tooltip": "Set BREAKs in their own line", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_ands": ( - "BOOLEAN", - { - "default": False, - "tooltip": "Cleanup around ANDs", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_ands_eol": ( - "BOOLEAN", - { - "default": False, - "tooltip": "Set ANDs in their own line", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_extranetwork_tags": ( - "BOOLEAN", - { - "default": False, - "tooltip": "Clean up around extra network tags", - "label_on": "Yes", - "label_off": "No", - }, - ), - "cleanup_merge_attention": ( - "BOOLEAN", - { - "default": True, - "tooltip": "Merge nested attention constructs", - "label_on": "Yes", - "label_off": "No", - }, - ), - "remove_extranetwork_tags": ( - "BOOLEAN", - { - "default": False, - "tooltip": "Remove extra network tags", - "label_on": "Yes", - "label_off": "No", - }, - ), - "en_mappings_folders": ( - "STRING", - { - "default": "", - "tooltip": "Comma separated list of extranetwork mappings folders", - "dynamicPrompts": False, - }, - ), - "en_mappings_input": ( - "STRING", - { - "default": "", - "multiline": True, - "placeholder": "extranetwork mappings definitions", - "tooltip": "Extranetwork mappings definitions in yaml format", - "dynamicPrompts": False, + "forceInput": True, + "tooltip": "ExtraNetworks mapping options", }, ), }, @@ -341,31 +194,15 @@ class PromptPostProcessorComfyUINode: seed, debug_level, # pylint: disable=unused-argument on_warnings, + process_wildcards, + do_cleanup, variants_definitions, - wc_process_wildcards, - wc_wildcards_folders, - wc_wildcards_input, - wc_if_wildcards, - wc_choice_separator, - wc_keep_choices_order, - stn_separator, - stn_ignore_repeats, - cleanup_extra_spaces, - cleanup_empty_constructs, - cleanup_extra_separators, - cleanup_extra_separators2, - cleanup_extra_separators_include_eol, - cleanup_breaks, - cleanup_breaks_eol, - cleanup_ands, - cleanup_ands_eol, - cleanup_extranetwork_tags, - cleanup_merge_attention, - remove_extranetwork_tags, - en_mappings_folders, - en_mappings_input, + wc_options, + stn_options, + cup_options, + en_options, ): - if wc_process_wildcards: + if process_wildcards: return float( "NaN" ) # since we can't detect changes in wildcards we assume they are always changed when enabled @@ -376,29 +213,13 @@ class PromptPostProcessorComfyUINode: "neg_prompt": neg_prompt, "seed": seed, "on_warnings": on_warnings, + "process_wildcards": process_wildcards, + "do_cleanup": do_cleanup, "variants_definitions": variants_definitions, - "process_wildcards": wc_process_wildcards, - "wildcards_folders": wc_wildcards_folders, - "wildcards_input": wc_wildcards_input, - "if_wildcards": wc_if_wildcards, - "choice_separator": wc_choice_separator, - "keep_choices_order": wc_keep_choices_order, - "stn_separator": stn_separator, - "stn_ignore_repeats": stn_ignore_repeats, - "cleanup_extra_spaces": cleanup_extra_spaces, - "cleanup_empty_constructs": cleanup_empty_constructs, - "cleanup_extra_separators": cleanup_extra_separators, - "cleanup_extra_separators2": cleanup_extra_separators2, - "cleanup_extra_separators_include_eol": cleanup_extra_separators_include_eol, - "cleanup_breaks": cleanup_breaks, - "cleanup_breaks_eol": cleanup_breaks_eol, - "cleanup_ands": cleanup_ands, - "cleanup_ands_eol": cleanup_ands_eol, - "cleanup_extranetwork_tags": cleanup_extranetwork_tags, - "cleanup_merge_attention": cleanup_merge_attention, - "remove_extranetwork_tags": remove_extranetwork_tags, - "en_mappings_folders": en_mappings_folders, - "en_mappings_input": en_mappings_input, + "wc_options": wc_options, + "stn_options": stn_options, + "cup_options": cup_options, + "en_options": en_options, } return new_run.__hash__ # return float("NaN") @@ -412,29 +233,13 @@ class PromptPostProcessorComfyUINode: seed, debug_level, on_warnings, + process_wildcards, + do_cleanup, variants_definitions, - wc_process_wildcards, - wc_wildcards_folders, - wc_wildcards_input, - wc_if_wildcards, - wc_choice_separator, - wc_keep_choices_order, - stn_separator, - stn_ignore_repeats, - cleanup_extra_spaces, - cleanup_empty_constructs, - cleanup_extra_separators, - cleanup_extra_separators2, - cleanup_extra_separators_include_eol, - cleanup_breaks, - cleanup_breaks_eol, - cleanup_ands, - cleanup_ands_eol, - cleanup_extranetwork_tags, - cleanup_merge_attention, - remove_extranetwork_tags, - en_mappings_folders, - en_mappings_input, + wc_options, + stn_options, + cup_options, + en_options, ): modelclass = ( model.model.model_config.__class__.__name__ if model is not None and not isinstance(model, str) else model @@ -471,6 +276,7 @@ class PromptPostProcessorComfyUINode: } # Also supported: SVD_img2vid, SVD3D_u, SVD3_p, Stable_Zero123, SD_X4Upscaler, Stable_Cascade_C, Stable_Cascade_B, StableAudio + wc_wildcards_folders = wc_options["wc_wildcards_folders"] if wc_options else "" if wc_wildcards_folders == "": try: fp1 = folder_paths.get_folder_paths("ppp_wildcards") @@ -488,6 +294,7 @@ class PromptPostProcessorComfyUINode: for f in wc_wildcards_folders.split(",") if f.strip() != "" ] + en_mappings_folders = en_options["en_mappings_folders"] if en_options else "" if en_mappings_folders == "": try: fp3 = folder_paths.get_folder_paths("ppp_extranetworkmappings") @@ -510,34 +317,71 @@ class PromptPostProcessorComfyUINode: "debug_level": debug_level, "on_warnings": on_warnings, "variants_definitions": variants_definitions, - "process_wildcards": wc_process_wildcards, - "if_wildcards": wc_if_wildcards, - "choice_separator": wc_choice_separator, - "keep_choices_order": wc_keep_choices_order, - "stn_separator": stn_separator, - "stn_ignore_repeats": stn_ignore_repeats, - "cleanup_extra_spaces": cleanup_extra_spaces, - "cleanup_empty_constructs": cleanup_empty_constructs, - "cleanup_extra_separators": cleanup_extra_separators, - "cleanup_extra_separators2": cleanup_extra_separators2, - "cleanup_extra_separators_include_eol": cleanup_extra_separators_include_eol, - "cleanup_breaks": cleanup_breaks, - "cleanup_breaks_eol": cleanup_breaks_eol, - "cleanup_ands": cleanup_ands, - "cleanup_ands_eol": cleanup_ands_eol, - "cleanup_extranetwork_tags": cleanup_extranetwork_tags, - "cleanup_merge_attention": cleanup_merge_attention, - "remove_extranetwork_tags": remove_extranetwork_tags, + "process_wildcards": process_wildcards, + "if_wildcards": ( + wc_options["wc_if_wildcards"] if wc_options else PromptPostProcessor.IFWILDCARDS_CHOICES.stop.value + ), + "choice_separator": ( + wc_options["wc_choice_separator"] if wc_options else PromptPostProcessor.DEFAULT_CHOICE_SEPARATOR + ), + "keep_choices_order": ( + wc_options["wc_keep_choices_order"] if wc_options else PromptPostProcessor.DEFAULT_KEEP_CHOICES_ORDER + ), + "stn_separator": stn_options["stn_separator"] if stn_options else PromptPostProcessor.DEFAULT_STN_SEPARATOR, + "stn_ignore_repeats": ( + stn_options["stn_ignore_repeats"] if stn_options else PromptPostProcessor.DEFAULT_STN_IGNORE_REPEATS + ), + "do_cleanup": do_cleanup, + "cleanup_extra_spaces": ( + cup_options["cup_extra_spaces"] if cup_options else PromptPostProcessor.DEFAULT_CUP_EXTRA_SPACES + ), + "cleanup_empty_constructs": ( + cup_options["cup_empty_constructs"] if cup_options else PromptPostProcessor.DEFAULT_CUP_EMPTY_CONSTRUCTS + ), + "cleanup_extra_separators": ( + cup_options["cup_extra_separators"] if cup_options else PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS + ), + "cleanup_extra_separators2": ( + cup_options["cup_extra_separators2"] + if cup_options + else PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS2 + ), + "cleanup_extra_separators_include_eol": ( + cup_options["cup_extra_separators_include_eol"] + if cup_options + else PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS_INCLUDE_EOL + ), + "cleanup_breaks": cup_options["cup_breaks"] if cup_options else PromptPostProcessor.DEFAULT_CUP_BREAKS, + "cleanup_breaks_eol": ( + cup_options["cup_breaks_eol"] if cup_options else PromptPostProcessor.DEFAULT_CUP_BREAKS_EOL + ), + "cleanup_ands": cup_options["cup_ands"] if cup_options else PromptPostProcessor.DEFAULT_CUP_ANDS, + "cleanup_ands_eol": ( + cup_options["cup_ands_eol"] if cup_options else PromptPostProcessor.DEFAULT_CUP_ANDS_EOL + ), + "cleanup_extranetwork_tags": ( + cup_options["cup_extranetwork_tags"] + if cup_options + else PromptPostProcessor.DEFAULT_CUP_EXTRANETWORK_TAGS + ), + "cleanup_merge_attention": ( + cup_options["cup_merge_attention"] if cup_options else PromptPostProcessor.DEFAULT_CUP_MERGE_ATTENTION + ), + "remove_extranetwork_tags": ( + cup_options["cup_remove_extranetwork_tags"] + if cup_options + else PromptPostProcessor.DEFAULT_CUP_REMOVE_EXTRANETWORK_TAGS + ), } self.wildcards_obj.refresh_wildcards( debug_level, wildcards_folders if options["process_wildcards"] else None, - wc_wildcards_input, + wc_options["wc_wildcards_input"] if wc_options else "", ) self.extranetwork_mappings_obj.refresh_extranetwork_mappings( debug_level, enmappings_folders, - en_mappings_input, + en_options["en_mappings_input"] if en_options else "", ) ppp = PromptPostProcessor( self.logger, @@ -559,6 +403,353 @@ class PromptPostProcessorComfyUINode: nodes.interrupt_processing(True) +class PromptPostProcessorWildcardOptionsComfyUINode: + """ + Node for wildcard options. + """ + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(cls): + return { + "optional": { + "folders": ( + "STRING", + { + "default": "", + "tooltip": "Comma separated list of wildcards folders", + "dynamicPrompts": False, + }, + ), + "definitions": ( + "STRING", + { + "default": "", + "multiline": True, + "placeholder": "wildcards definitions", + "tooltip": "Wildcards definitions in yaml/json format", + "dynamicPrompts": False, + }, + ), + "if_wildcards": ( + [e.value for e in PromptPostProcessor.IFWILDCARDS_CHOICES], + { + "default": PromptPostProcessor.IFWILDCARDS_CHOICES.stop.value, + "tooltip": "How to handle invalid wildcards in the prompt", + }, + ), + "choice_separator": ( + "STRING", + { + "default": PromptPostProcessor.DEFAULT_CHOICE_SEPARATOR, + "tooltip": "Default separator for selected choices", + "dynamicPrompts": False, + }, + ), + "keep_choices_order": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_KEEP_CHOICES_ORDER, + "tooltip": "Keep the order of the choices in the prompt", + "label_on": "Yes", + "label_off": "No", + }, + ), + }, + } + + RETURN_TYPES = ("PPP_OPTIONS_WC",) + RETURN_NAMES = ("options",) + + FUNCTION = "process" + + CATEGORY = "ACB" + + def process( + self, + folders: str, + definitions: str, + if_wildcards, + choice_separator: str, + keep_choices_order: bool, + ): + options = { + "wc_wildcards_folders": folders, + "wc_wildcards_input": definitions, + "wc_if_wildcards": if_wildcards, + "wc_choice_separator": choice_separator, + "wc_keep_choices_order": keep_choices_order, + } + return (options,) + + +class PromptPostProcessorSTNOptionsComfyUINode: + """ + Node for Send-To-Negative options. + """ + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(cls): + return { + "optional": { + "separator": ( + "STRING", + { + "default": PromptPostProcessor.DEFAULT_STN_SEPARATOR, + "tooltip": "Separator for the content added to the negative prompt", + "dynamicPrompts": False, + }, + ), + "ignore_repeats": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_STN_IGNORE_REPEATS, + "tooltip": "Ignore repeated content added to the negative prompt", + "label_on": "Yes", + "label_off": "No", + }, + ), + }, + } + + RETURN_TYPES = ("PPP_OPTIONS_STN",) + RETURN_NAMES = ("options",) + + FUNCTION = "process" + + CATEGORY = "ACB" + + def process( + self, + separator: str, + ignore_repeats: bool, + ): + options = { + "stn_separator": separator, + "stn_ignore_repeats": ignore_repeats, + } + return (options,) + + +class PromptPostProcessorCleanupOptionsComfyUINode: + """ + Node for Cleanup options. + """ + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(cls): + return { + "optional": { + "extra_spaces": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_EXTRA_SPACES, + "tooltip": "Remove extra spaces", + "label_on": "Yes", + "label_off": "No", + }, + ), + "empty_constructs": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_EMPTY_CONSTRUCTS, + "tooltip": "Remove empty constructs", + "label_on": "Yes", + "label_off": "No", + }, + ), + "extra_separators": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS, + "tooltip": "Remove extra separators", + "label_on": "Yes", + "label_off": "No", + }, + ), + "extra_separators_additional": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS2, + "tooltip": "Remove extra separators (additional cases)", + "label_on": "Yes", + "label_off": "No", + }, + ), + "extra_separators_include_eol": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS_INCLUDE_EOL, + "tooltip": "Extra separators options also remove EOLs", + "label_on": "Yes", + "label_off": "No", + }, + ), + "around_breaks": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_BREAKS, + "tooltip": "Cleanup around BREAKs", + "label_on": "Yes", + "label_off": "No", + }, + ), + "breaks_with_eol": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_BREAKS_EOL, + "tooltip": "Set BREAKs in their own line", + "label_on": "Yes", + "label_off": "No", + }, + ), + "around_ands": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_ANDS, + "tooltip": "Cleanup around ANDs", + "label_on": "Yes", + "label_off": "No", + }, + ), + "ands_with_eol": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_ANDS_EOL, + "tooltip": "Set ANDs in their own line", + "label_on": "Yes", + "label_off": "No", + }, + ), + "around_extranetwork_tags": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_EXTRANETWORK_TAGS, + "tooltip": "Clean up around extra network tags", + "label_on": "Yes", + "label_off": "No", + }, + ), + "merge_attention": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_MERGE_ATTENTION, + "tooltip": "Merge nested attention constructs", + "label_on": "Yes", + "label_off": "No", + }, + ), + "remove_extranetwork_tags": ( + "BOOLEAN", + { + "default": PromptPostProcessor.DEFAULT_CUP_REMOVE_EXTRANETWORK_TAGS, + "tooltip": "Remove extra network tags", + "label_on": "Yes", + "label_off": "No", + }, + ), + }, + } + + RETURN_TYPES = ("PPP_OPTIONS_CUP",) + RETURN_NAMES = ("options",) + + FUNCTION = "process" + + CATEGORY = "ACB" + + def process( + self, + extra_spaces: bool, + empty_constructs: bool, + extra_separators: bool, + extra_separators_additional: bool, + extra_separators_include_eol: bool, + around_breaks: bool, + breaks_with_eol: bool, + around_ands: bool, + ands_with_eol: bool, + around_extranetwork_tags: bool, + merge_attention: bool, + remove_extranetwork_tags: bool, + ): + options = { + "cup_extra_spaces": extra_spaces, + "cup_empty_constructs": empty_constructs, + "cup_extra_separators": extra_separators, + "cup_extra_separators2": extra_separators_additional, + "cup_extra_separators_include_eol": extra_separators_include_eol, + "cup_breaks": around_breaks, + "cup_breaks_eol": breaks_with_eol, + "cup_ands": around_ands, + "cup_ands_eol": ands_with_eol, + "cup_extranetwork_tags": around_extranetwork_tags, + "cup_merge_attention": merge_attention, + "cup_remove_extranetwork_tags": remove_extranetwork_tags, + } + return (options,) + + +class PromptPostProcessorENMappingOptionsComfyUINode: + """ + Node for ExtraNetworks mapping options. + """ + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(cls): + return { + "optional": { + "folders": ( + "STRING", + { + "default": "", + "tooltip": "Comma separated list of extranetwork mappings folders", + "dynamicPrompts": False, + }, + ), + "definitions": ( + "STRING", + { + "default": "", + "multiline": True, + "placeholder": "extranetwork mappings definitions", + "tooltip": "Extranetwork mappings definitions in yaml format", + "dynamicPrompts": False, + }, + ), + }, + } + + RETURN_TYPES = ("PPP_OPTIONS_EN",) + RETURN_NAMES = ("options",) + + FUNCTION = "process" + + CATEGORY = "ACB" + + def process( + self, + folders: str, + definitions: str, + ): + options = { + "en_mappings_folders": folders, + "en_mappings_input": definitions, + } + return (options,) + + class PromptPostProcessorSelectVariableComfyUINode: """ Node for selecting a variable from a dictionary. diff --git a/pyproject.toml b/pyproject.toml index e307b31..85ea09d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "sd-webui-prompt-postprocessor" description = "Stable Diffusion WebUI & ComfyUI extension to post-process the prompt, including sending content from the prompt to the negative prompt and wildcards." -version = "2.13.2" +version = "3.0.0" license = { file = "LICENSE.txt" } dependencies = ["lark", "numpy", "pyyaml"] diff --git a/scripts/ppp_script.py b/scripts/ppp_script.py index c0f086b..27cab55 100644 --- a/scripts/ppp_script.py +++ b/scripts/ppp_script.py @@ -307,29 +307,50 @@ class PromptPostProcessorA1111Script(scripts.Script): if f.strip() != "" ] options = { - "debug_level": getattr(opts, "ppp_gen_debug_level", DEBUG_LEVEL.none.value), - "on_warning": getattr(opts, "ppp_gen_onwarning", PromptPostProcessor.ONWARNING_CHOICES.warn.value), + "debug_level": getattr(opts, "ppp_gen_debug_level", PromptPostProcessor.DEFAULT_DEBUG_LEVEL), + "on_warning": getattr(opts, "ppp_gen_onwarning", PromptPostProcessor.DEFAULT_ONWARNING), "variants_definitions": getattr( opts, "ppp_gen_variantsdefinitions", PromptPostProcessor.DEFAULT_VARIANTS_DEFINITIONS ), - "process_wildcards": getattr(opts, "ppp_wil_processwildcards", True), - "if_wildcards": getattr(opts, "ppp_wil_ifwildcards", PromptPostProcessor.IFWILDCARDS_CHOICES.stop.value), + "process_wildcards": getattr(opts, "ppp_wil_processwildcards", PromptPostProcessor.DEFAULT_WC_PROCESS), + "if_wildcards": getattr(opts, "ppp_wil_ifwildcards", PromptPostProcessor.DEFAULT_IF_WILDCARDS), "choice_separator": getattr(opts, "ppp_wil_choice_separator", PromptPostProcessor.DEFAULT_CHOICE_SEPARATOR), - "keep_choices_order": getattr(opts, "ppp_wil_keep_choices_order", False), + "keep_choices_order": getattr( + opts, "ppp_wil_keep_choices_order", PromptPostProcessor.DEFAULT_KEEP_CHOICES_ORDER + ), "stn_separator": getattr(opts, "ppp_stn_separator", PromptPostProcessor.DEFAULT_STN_SEPARATOR), - "stn_ignore_repeats": getattr(opts, "ppp_stn_ignorerepeats", True), - "cleanup_extra_spaces": getattr(opts, "ppp_cup_extraspaces", True), - "cleanup_empty_constructs": getattr(opts, "ppp_cup_emptyconstructs", True), - "cleanup_extra_separators": getattr(opts, "ppp_cup_extraseparators", True), - "cleanup_extra_separators2": getattr(opts, "ppp_cup_extraseparators2", True), - "cleanup_extra_separators_include_eol": getattr(opts, "ppp_cup_extraseparators_include_eol", True), - "cleanup_breaks": getattr(opts, "ppp_cup_breaks", True), - "cleanup_breaks_eol": getattr(opts, "ppp_cup_breaks_eol", False), - "cleanup_ands": getattr(opts, "ppp_cup_ands", True), - "cleanup_ands_eol": getattr(opts, "ppp_cup_ands_eol", False), - "cleanup_extranetwork_tags": getattr(opts, "ppp_cup_extranetworktags", False), - "cleanup_merge_attention": getattr(opts, "ppp_cup_mergeattention", True), - "remove_extranetwork_tags": getattr(opts, "ppp_rem_removeextranetworktags", False), + "stn_ignore_repeats": getattr( + opts, "ppp_stn_ignorerepeats", PromptPostProcessor.DEFAULT_STN_IGNORE_REPEATS + ), + "do_cleanup": True, + "cleanup_extra_spaces": getattr(opts, "ppp_cup_extraspaces", PromptPostProcessor.DEFAULT_CUP_EXTRA_SPACES), + "cleanup_empty_constructs": getattr( + opts, "ppp_cup_emptyconstructs", PromptPostProcessor.DEFAULT_CUP_EMPTY_CONSTRUCTS + ), + "cleanup_extra_separators": getattr( + opts, "ppp_cup_extraseparators", PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS + ), + "cleanup_extra_separators2": getattr( + opts, "ppp_cup_extraseparators2", PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS2 + ), + "cleanup_extra_separators_include_eol": getattr( + opts, + "ppp_cup_extraseparators_include_eol", + PromptPostProcessor.DEFAULT_CUP_EXTRA_SEPARATORS_INCLUDE_EOL, + ), + "cleanup_breaks": getattr(opts, "ppp_cup_breaks", PromptPostProcessor.DEFAULT_CUP_BREAKS), + "cleanup_breaks_eol": getattr(opts, "ppp_cup_breaks_eol", PromptPostProcessor.DEFAULT_CUP_BREAKS_EOL), + "cleanup_ands": getattr(opts, "ppp_cup_ands", PromptPostProcessor.DEFAULT_CUP_ANDS), + "cleanup_ands_eol": getattr(opts, "ppp_cup_ands_eol", PromptPostProcessor.DEFAULT_CUP_ANDS_EOL), + "cleanup_extranetwork_tags": getattr( + opts, "ppp_cup_extranetworktags", PromptPostProcessor.DEFAULT_CUP_EXTRANETWORK_TAGS + ), + "cleanup_merge_attention": getattr( + opts, "ppp_cup_mergeattention", PromptPostProcessor.DEFAULT_CUP_MERGE_ATTENTION + ), + "remove_extranetwork_tags": getattr( + opts, "ppp_rem_removeextranetworktags", PromptPostProcessor.DEFAULT_CUP_REMOVE_EXTRANETWORK_TAGS + ), } hash_options = hash(tuple(sorted(options.items()))) self.wildcards_obj.refresh_wildcards(