diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a8719ae..e3c6dbf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,17 +8,19 @@ on: paths: - "pyproject.toml" +permissions: + issues: write + jobs: publish-node: name: Publish Custom Node to registry runs-on: ubuntu-latest - # if this is a forked repository. Skipping the workflow. - if: github.event.repository.fork == false + if: ${{ github.repository_owner == 'acorderob' }} steps: - name: Check out code uses: actions/checkout@v4 - name: Publish Custom Node - uses: Comfy-Org/publish-node-action@main + uses: Comfy-Org/publish-node-action@v1 with: ## Add your own personal access token to your Github Repository secrets and reference it here. personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} diff --git a/docs/CONFIG.md b/docs/CONFIG.md index b9e7eca..a358ea3 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -40,6 +40,7 @@ With this prompt: `__quality__, 1girl, ${head:__eyes__, __hair__, __expression__ The default value defines strings for *Pony* and *Illustrious* models. * **Apply in img2img**: check if you want to do the processing in img2img processes (*does not apply to the ComfyUI node*). +* **Add original prompts to metadata**: adds to original prompts to the metadata. ### Wildcard settings diff --git a/ppp.py b/ppp.py index 9224790..ac8ad7a 100644 --- a/ppp.py +++ b/ppp.py @@ -2,6 +2,7 @@ import logging import math import os import re +import sys import textwrap import time from collections import namedtuple @@ -9,11 +10,12 @@ from enum import Enum from typing import Any, Callable, Optional import lark -import lark.parsers import numpy as np -from ppp_logging import DEBUG_LEVEL -from ppp_wildcards import PPPWildcard, PPPWildcards +sys.path.append(os.path.dirname(os.path.realpath(__file__))) + +from ppp_logging import DEBUG_LEVEL # pylint: disable=import-error +from ppp_wildcards import PPPWildcard, PPPWildcards # pylint: disable=import-error class PromptPostProcessor: # pylint: disable=too-few-public-methods,too-many-instance-attributes @@ -220,6 +222,11 @@ class PromptPostProcessor: # pylint: disable=too-few-public-methods,too-many-in for model_name, model_type_and_substrings in self.variants_definitions.items() if model_name not in self.SUPPORTED_MODELS } + is_models_true = [k for k, v in is_models.items() if v] + if len(is_models_true) > 1: + self.logger.warning( + f"Multiple model variants detected at the same time in the filename!: {', '.join(is_models_true)}" + ) self.system_variables.update({"_is_" + x: y for x, y in is_models.items()}) for x in sdchecks.keys(): if x != "": diff --git a/ppp_cache.py b/ppp_cache.py index 44ec45f..ec9d6ce 100644 --- a/ppp_cache.py +++ b/ppp_cache.py @@ -2,7 +2,7 @@ from collections import OrderedDict from logging import Logger from typing import Tuple -from ppp_logging import DEBUG_LEVEL +from ppp_logging import DEBUG_LEVEL # pylint: disable=import-error class PPPLRUCache: diff --git a/ppp_wildcards.py b/ppp_wildcards.py index f462fb8..4263110 100644 --- a/ppp_wildcards.py +++ b/ppp_wildcards.py @@ -5,7 +5,7 @@ from typing import Optional import logging import yaml -from ppp_logging import DEBUG_LEVEL +from ppp_logging import DEBUG_LEVEL # pylint: disable=import-error def deep_freeze(obj): diff --git a/pyproject.toml b/pyproject.toml index 68bcd71..910868a 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.9.0" +version = "2.10.0" license = { file = "LICENSE.txt" } dependencies = ["lark", "numpy", "pyyaml"] diff --git a/scripts/ppp_script.py b/scripts/ppp_script.py index a1c3aab..a186f19 100644 --- a/scripts/ppp_script.py +++ b/scripts/ppp_script.py @@ -6,18 +6,17 @@ import os import time import numpy as np -sys.path.append(os.path.join(sys.path[0], "..")) +sys.path.append(os.path.join(os.path.realpath(__file__), "..")) # base path for the extension - -from modules import scripts, shared, script_callbacks -from modules.processing import StableDiffusionProcessing -from modules.shared import opts -from modules.paths import models_path -import gradio as gr -from ppp import PromptPostProcessor -from ppp_logging import DEBUG_LEVEL, PromptPostProcessorLogFactory -from ppp_cache import PPPLRUCache -from ppp_wildcards import PPPWildcards +from modules import scripts, shared, script_callbacks # pylint: disable=import-error +from modules.processing import StableDiffusionProcessing # pylint: disable=import-error +from modules.shared import opts # pylint: disable=import-error +from modules.paths import models_path # pylint: disable=import-error +import gradio as gr # pylint: disable=import-error +from ppp import PromptPostProcessor # pylint: disable=import-error +from ppp_logging import DEBUG_LEVEL, PromptPostProcessorLogFactory # pylint: disable=import-error +from ppp_cache import PPPLRUCache # pylint: disable=import-error +from ppp_wildcards import PPPWildcards # pylint: disable=import-error class PromptPostProcessorA1111Script(scripts.Script): @@ -82,7 +81,7 @@ class PromptPostProcessorA1111Script(scripts.Script): """ return PromptPostProcessor.NAME - def show(self, is_img2img): + def show(self, is_img2img): # pylint: disable=unused-argument """ Determines whether the script should be shown based on the kind of processing. @@ -94,7 +93,7 @@ class PromptPostProcessorA1111Script(scripts.Script): """ return scripts.AlwaysVisible - def ui(self, is_img2img): + def ui(self, is_img2img): # pylint: disable=unused-argument with gr.Accordion(PromptPostProcessor.NAME, open=False): force_equal_seeds = gr.Checkbox( label="Force equal seeds", @@ -171,6 +170,7 @@ class PromptPostProcessorA1111Script(scripts.Script): is_i2i = bool(init_images[0]) self.ppp_debug_level = DEBUG_LEVEL(getattr(opts, "ppp_gen_debug_level", DEBUG_LEVEL.none.value)) do_i2i = getattr(opts, "ppp_gen_doi2i", False) + add_prompts = getattr(opts, "ppp_gen_addpromptstometadata", True) if is_i2i and not do_i2i: if self.ppp_debug_level != DEBUG_LEVEL.none: self.ppp_logger.info("Not processing the prompt for i2i") @@ -349,12 +349,13 @@ class PromptPostProcessorA1111Script(scripts.Script): rpr: list[str] = getattr(p, "all_prompts", None) rnr: list[str] = getattr(p, "all_negative_prompts", None) if rpr is not None and rnr is not None: - extra_params.update( - { - "PPP original prompts": rpr.copy(), - "PPP original negative prompts": rnr.copy(), - } - ) + if add_prompts: + extra_params.update( + { + "PPP original prompts": rpr.copy(), + "PPP original negative prompts": rnr.copy(), + } + ) prompts_list += [ ("regular", seed, prompt, negative_prompt) for seed, prompt, negative_prompt in zip(calculated_seeds, rpr, rnr) @@ -364,12 +365,13 @@ class PromptPostProcessorA1111Script(scripts.Script): rph: list[str] = getattr(p, "all_hr_prompts", None) rnh: list[str] = getattr(p, "all_hr_negative_prompts", None) if rph is not None and rnh is not None: - extra_params.update( - { - "PPP original HR prompts": rph.copy(), - "PPP original HR negative prompts": rnh.copy(), - } - ) + if add_prompts: + extra_params.update( + { + "PPP original HR prompts": rph.copy(), + "PPP original HR negative prompts": rnh.copy(), + } + ) prompts_list += [ ("hiresfix", seed, prompt, negative_prompt) for seed, prompt, negative_prompt in zip(calculated_seeds, rph, rnh) @@ -500,6 +502,14 @@ def on_ui_settings(): section=section, ), ) + shared.opts.add_option( + key="ppp_gen_addpromptstometadata", + info=shared.OptionInfo( + True, + label="Add original prompts to metadata", + section=section, + ), + ) # wildcard settings shared.opts.add_option( diff --git a/tests/tests.py b/tests/tests.py index 7b85073..d48eef5 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -4,12 +4,11 @@ import unittest import sys import os -from ppp_wildcards import PPPWildcards +sys.path.append(os.path.join(os.path.realpath(__file__), "..")) # base path for the extension -sys.path.append(os.path.join(sys.path[0], "..")) - -from ppp import PromptPostProcessor -from ppp_logging import DEBUG_LEVEL, PromptPostProcessorLogFactory +from ppp_wildcards import PPPWildcards # pylint: disable=import-error +from ppp import PromptPostProcessor # pylint: disable=import-error +from ppp_logging import DEBUG_LEVEL, PromptPostProcessorLogFactory # pylint: disable=import-error PromptPair = namedtuple("PromptPair", ["prompt", "negative_prompt"], defaults=["", ""]) @@ -355,7 +354,8 @@ class TestPromptPostProcessor(unittest.TestCase): def test_cmd_if_nested(self): # nested if command self.__process( PromptPair( - "this is SD1PONYSD2NOPONYNOPONY", "" + "this is SD1PONYSD2NOPONYNOPONY", + "", ), PromptPair("this is PONY", ""), ppp=PromptPostProcessor( @@ -394,13 +394,19 @@ class TestPromptPostProcessor(unittest.TestCase): def test_cmd_set_if_complex_conditions_1(self): # complex conditions (or) self.__process( - PromptPair("truefalsethis test is OKnot OK", ""), + PromptPair( + "truefalsethis test is OKnot OK", + "", + ), PromptPair("this test is OK", ""), ) def test_cmd_set_if_complex_conditions_2(self): # complex conditions (and) self.__process( - PromptPair("truetruethis test is OKnot OK", ""), + PromptPair( + "truetruethis test is OKnot OK", + "", + ), PromptPair("this test is OK", ""), ) @@ -412,25 +418,37 @@ class TestPromptPostProcessor(unittest.TestCase): def test_cmd_set_if_complex_conditions_4(self): # complex conditions (not, precedence) self.__process( - PromptPair("truefalsethis test is OKnot OK", ""), + PromptPair( + "truefalsethis test is OKnot OK", + "", + ), PromptPair("this test is OK", ""), ) def test_cmd_set_if_complex_conditions_5(self): # complex conditions (not, precedence, comparison) self.__process( - PromptPair("1falsethis test is OKnot OK", ""), + PromptPair( + "1falsethis test is OKnot OK", + "", + ), PromptPair("this test is OK", ""), ) def test_cmd_set_if_complex_conditions_6(self): # complex conditions self.__process( - PromptPair("123this test is OKnot OK", ""), + PromptPair( + "123this test is OKnot OK", + "", + ), PromptPair("this test is OK", ""), ) def test_cmd_set_if_complex_conditions_7(self): # complex conditions self.__process( - PromptPair("123this test is OKnot OK", ""), + PromptPair( + "123this test is OKnot OK", + "", + ), PromptPair("this test is OK", ""), ) @@ -920,7 +938,10 @@ class TestPromptPostProcessor(unittest.TestCase): def test_variants(self): self.__process( - PromptPair("test1test2test3test4", ""), + PromptPair( + "test1test2test3test4", + "", + ), PromptPair("test1test2", ""), ppp=PromptPostProcessor( self.__ppp_logger, @@ -947,7 +968,6 @@ class TestPromptPostProcessor(unittest.TestCase): ppp=self.__comfyuippp, ) - # def test_mix(self): # self.__process( # PromptPair( @@ -961,19 +981,6 @@ class TestPromptPostProcessor(unittest.TestCase): # ppp=self.__nocupppp, # ) - # def test_real(self): - # self.__wildcards_obj.refresh_wildcards( - # DEBUG_LEVEL.full, - # ["D:\\AI\\SD\\_configuraciones\\acb-wildcards\\wildcards"], - # ) - # self.__process( - # PromptPair( - # "${separator=()}, __quality/high__ __misc/sep__, photograph of a __character__", - # "__negatives/ng_generic__", - # ), - # PromptPair("", ""), - # ) - if __name__ == "__main__": unittest.main()