diff --git a/CHANGELOG.md b/CHANGELOG.md index 981da9e..c2521cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2023-07-05 + +- v23.7.3 +- 버그 수정 + - `object()`가 json 직렬화 안되는 문제 + - `process`를 호출함에 따라 배치 카운트가 2이상일 때, all_prompts가 고정되는 문제 + - `ad-before`와 `ad-preview` 이미지 파일명이 실제 파일명과 다른 문제 + - pydantic 2.0 호환성 문제 + ## 2023-07-04 - v23.7.2 diff --git a/adetailer/__version__.py b/adetailer/__version__.py index 2a0050e..3f3f8f0 100644 --- a/adetailer/__version__.py +++ b/adetailer/__version__.py @@ -1 +1 @@ -__version__ = "23.7.2" +__version__ = "23.7.3" diff --git a/adetailer/args.py b/adetailer/args.py index ef5fcd3..e7d4178 100644 --- a/adetailer/args.py +++ b/adetailer/args.py @@ -67,7 +67,7 @@ class ADetailerArgs(BaseModel, extra=Extra.forbid): ad_controlnet_guidance_end: confloat(ge=0.0, le=1.0) = 1.0 is_api: bool = True - @root_validator + @root_validator(skip_on_failure=True) def ad_controlnt_module_validator(cls, values): # noqa: N805 cn_model = values.get("ad_controlnet_model", "None") cn_module = values.get("ad_controlnet_module", None) @@ -76,8 +76,9 @@ class ADetailerArgs(BaseModel, extra=Extra.forbid): return values @validator("is_api", pre=True) - def is_api_validator(cls, v): # noqa: N805 - return type(v) is not object + def is_api_validator(cls, v: Any): # noqa: N805 + "tuple is json serializable but cannot be made with json deserialize." + return type(v) is not tuple @staticmethod def ppop( diff --git a/adetailer/mediapipe.py b/adetailer/mediapipe.py index 194496c..17fb2cc 100644 --- a/adetailer/mediapipe.py +++ b/adetailer/mediapipe.py @@ -172,8 +172,8 @@ def mediapipe_face_mesh_eyes_only( def draw_preview( preview: Image.Image, bboxes: list[list[int]], masks: list[Image.Image] ) -> Image.Image: + red = Image.new("RGB", preview.size, "red") for mask in masks: - red = Image.new("RGB", preview.size, "red") masked = Image.composite(red, preview, mask) preview = Image.blend(preview, masked, 0.25) diff --git a/adetailer/traceback.py b/adetailer/traceback.py index a12de26..03e9afe 100644 --- a/adetailer/traceback.py +++ b/adetailer/traceback.py @@ -74,13 +74,14 @@ def ad_args(*args: Any) -> dict[str, Any]: return {} arg0 = ad_args[0] + is_api = arg0.get("is_api", True) return { "version": __version__, "ad_model": arg0["ad_model"], "ad_prompt": arg0.get("ad_prompt", ""), "ad_negative_prompt": arg0.get("ad_negative_prompt", ""), "ad_controlnet_model": arg0.get("ad_controlnet_model", "None"), - "is_api": "is_api" not in arg0 or type(arg0["is_api"]) is not object, + "is_api": type(is_api) is not tuple, } diff --git a/adetailer/ui.py b/adetailer/ui.py index af3d880..876a910 100644 --- a/adetailer/ui.py +++ b/adetailer/ui.py @@ -43,7 +43,7 @@ def on_widget_change(state: dict, value: Any, *, attr: str): def on_generate_click(state: dict, *values: Any): for attr, value in zip(ALL_ARGS.attrs, values): state[attr] = value - state["is_api"] = object() + state["is_api"] = () return state diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index 2ea1ff6..d0adf22 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -84,6 +84,17 @@ def pause_total_tqdm(): opts.data["multiple_tqdm"] = orig +@contextmanager +def preseve_prompts(p): + all_pt = copy(p.all_prompts) + all_ng = copy(p.all_negative_prompts) + try: + yield + finally: + p.all_prompts = all_pt + p.all_negative_prompts = all_ng + + class AfterDetailerScript(scripts.Script): def __init__(self): super().__init__() @@ -403,7 +414,12 @@ class AfterDetailerScript(scripts.Script): return i2i def save_image(self, p, image, *, condition: str, suffix: str) -> None: - i = p._ad_idx + i = p._ad_idx_all + if p.all_prompts: + i %= len(p.all_prompts) + save_prompt = p.all_prompts[i] + else: + save_prompt = p.prompt seed, _ = self.get_seed(p) if opts.data.get(condition, False): @@ -412,7 +428,7 @@ class AfterDetailerScript(scripts.Script): path=p.outpath_samples, basename="", seed=seed, - prompt=p.all_prompts[i] if i < len(p.all_prompts) else p.prompt, + prompt=save_prompt, extension=opts.samples_format, info=self.infotext(p), p=p, @@ -587,7 +603,8 @@ class AfterDetailerScript(scripts.Script): if p.scripts is not None and self.need_call_postprocess(p): dummy = Processed(p, [], p.seed, "") - p.scripts.postprocess(p, dummy) + with preseve_prompts(p): + p.scripts.postprocess(p, dummy) is_processed = False with CNHijackRestore(), pause_total_tqdm(), cn_allow_script_control(): @@ -602,7 +619,8 @@ class AfterDetailerScript(scripts.Script): ) if p.scripts is not None and self.need_call_process(p): - p.scripts.process(p) + with preseve_prompts(p): + p.scripts.process(p) try: ia = p._ad_idx_all