From 2d4a184597791875054bfc4fa65def296e789c9b Mon Sep 17 00:00:00 2001 From: ThereforeGames <95403634+ThereforeGames@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:07:12 -0500 Subject: [PATCH] v10.6.0 --- config.json | 3 + docs/CHANGELOG.md | 20 ++++- docs/MANUAL.md | 8 ++ lib_unprompted/shared.py | 2 +- scripts/unprompted.py | 98 +++++++++++++------------ shortcodes/basic/get.py | 19 ++++- shortcodes/basic/max.py | 22 +++++- shortcodes/basic/min.py | 22 +++++- shortcodes/basic/set.py | 30 ++++---- shortcodes/stable_diffusion/faceswap.py | 2 +- 10 files changed, 153 insertions(+), 73 deletions(-) diff --git a/config.json b/config.json index e504bff..2ad384c 100644 --- a/config.json +++ b/config.json @@ -106,6 +106,9 @@ "enabled":true, "open":false, "wizard_enabled":true, + "wizard_shortcodes":true, + "wizard_templates":true, + "wizard_capture":true, "wizard_open":false, "wizard_default_shortcode":"txt2mask", "dry_run_open":false, diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6543fd1..3bae6a4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -3,7 +3,25 @@ All notable changes to this project will be documented in this file. For more details on new features, please check the [Manual](./MANUAL.md). -
10.5.0 - 25 November 2023 +
10.6.0 - 1 December 2023 + +### Added +- New settings `Config.ui.wizard_shortcodes`, `Config.ui.wizard_templates`, `Config.ui.wizard_capture`: Allows you to disable certain Wizard tabs in order to improve WebUI performance +- `[max]` and `[min]`: Supports the `_key` parg to return the key of the max/min value instead of the value itself +- `[max]` and `[min]`: Can now parse values given as a list separated by `Config.syntax.delimiter` +- `[get]`: Supports the `_key` kwarg to return the names of requested variables instead of their values +- `[get]`: Supports the `_regex` kwarg to return the values of matching variables + +### Changed +- `[set]`: Now parses the value of the first parg, allowing you to use shortcodes in evaluating the variable name +- `[get]`: The default value of `_sep` is now `Config.syntax.delimiter` instead of space + +### Fixed +- `[faceswap]`: Fixed `embedding_path` processing + +
+ +
10.5.0 - 25 November 2023 ### About This update introduces global variables, several image processing shortcodes and improvements to some included templates and presets. The image features were motivated by Unprompted's integration with [BooruDatasetTagManager](https://github.com/starik222/BooruDatasetTagManager/pull/89) (my own PR.) For example, you can use `[image_info]` to assess image quality and influence the results of the Autotagger. Enjoy! diff --git a/docs/MANUAL.md b/docs/MANUAL.md index 9a2464d..0ae6cb3 100644 --- a/docs/MANUAL.md +++ b/docs/MANUAL.md @@ -6,6 +6,14 @@ If you encounter any confusing, incomplete, or out-of-date information here, ple ## ❔ Known Issues +
WebUI slowdowns + +Due to the nature of Gradio, creating many UI elements leads to performance issues in the WebUI. This may be resolved in Gradio 4, as [suggested here](https://github.com/gradio-app/gradio/issues/4841#issuecomment-1632141732). + +In the meantime, you can improve performance by disabling Wizard tabs you do not use. For example, you can disable the Shortcodes tab by setting `ui.wizard_shortcodes` to false in `config_user.json`. + +
+
Compatibility with ControlNet To achieve compatibility between Unprompted and ControlNet, you must manually rename the `unprompted` extension folder to `_unprompted`. This is due to [a limitation in the Automatic1111 extension framework](https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/8011) whereby priority is determined alphabetically. diff --git a/lib_unprompted/shared.py b/lib_unprompted/shared.py index f8bbe9e..656be4b 100644 --- a/lib_unprompted/shared.py +++ b/lib_unprompted/shared.py @@ -107,7 +107,7 @@ def handler(keyword, pargs, kwargs, context, content): self.log.info(f"Finished loading in {time.time()-start_time} seconds.") def __init__(self, base_dir="."): - self.VERSION = "10.5.0" + self.VERSION = "10.6.0" self.shortcode_modules = {} self.shortcode_objects = {} diff --git a/scripts/unprompted.py b/scripts/unprompted.py index 7df7d38..b3f856a 100644 --- a/scripts/unprompted.py +++ b/scripts/unprompted.py @@ -116,10 +116,11 @@ def parse_children(obj, result): # Skip special fields if block_name == "file": this_val = f"{Unprompted.Config.syntax.delimiter}".join([str(e.name) for e in gr_obj.value]) - else: this_val = gr_obj.value + else: + this_val = gr_obj.value if (arg_name == "prompt"): continue - this_val = Unprompted.make_alt_tags(html.escape(str(helpers.autocast(this_val)).replace("\"","\'"),quote = False)) + this_val = Unprompted.make_alt_tags(html.escape(str(helpers.autocast(this_val)).replace("\"", "\'"), quote=False)) if " " in this_val: this_val = f"\"{this_val}\"" # Enclose in quotes if necessary result += f" {arg_name}={this_val}" @@ -299,7 +300,7 @@ def show(self, is_img2img): def ui(self, is_img2img): mode_string = "img2img" if is_img2img else "txt2img" with gr.Group(): - with gr.Accordion("Unprompted", open=Unprompted.Config.ui.open, elem_classes=["unprompted-accordion",mode_string]): + with gr.Accordion("Unprompted", open=Unprompted.Config.ui.open, elem_classes=["unprompted-accordion", mode_string]): with gr.Row(equal_height=True): is_enabled = gr.Checkbox(label="Enabled", value=gradio_enabled_checkbox_workaround) @@ -364,7 +365,7 @@ def handler(keyword, pargs, kwargs, context, content): obj = gr.Image(label=this_label, value=content, type="filepath", interactive=True, info=_info, show_label=_show_label) elif (block_name == "file"): if len(content) < 1: content = None - file_types = helpers.ensure(kwargs["_file_types"].split(Unprompted.Config.syntax.delimiter),list) if "_file_types" in kwargs else None + file_types = helpers.ensure(kwargs["_file_types"].split(Unprompted.Config.syntax.delimiter), list) if "_file_types" in kwargs else None obj = gr.File(label=this_label, value=content, interactive=True, info=_info, show_label=_show_label, file_count=kwargs["_file_count"] if "_file_count" in kwargs else "single", file_types=file_types) @@ -390,7 +391,7 @@ def handler(keyword, pargs, kwargs, context, content): elif pargs[0] == "row": block = gr.Row(equal_height=pargs["_equal_height"] if "_equal_height" in pargs else False) elif pargs[0] == "column": - block = gr.Column(scale=int(pargs["_scale"]) if "_scale" in pargs else 1) + block = gr.Column(scale=int(pargs["_scale"]) if "_scale" in pargs else 1) with block: # Unprompted.parse_alt_tags(content, None, wizard_shortcode_parser) @@ -411,7 +412,7 @@ def handler(keyword, pargs, kwargs, context): wizard_shortcode_parser.register(handler, "base_dir") with gr.Tabs(): - + self.filtered_templates = Unprompted.wizard_groups[WizardModes.TEMPLATES][int(is_img2img)] self.filtered_shortcodes = Unprompted.wizard_groups[WizardModes.SHORTCODES][int(is_img2img)] @@ -426,7 +427,7 @@ def wizard_add_template(show_me=False): # Render the text file's UI with special parser object wizard_shortcode_parser.parse(file.read()) # Auto-include is always the last element - gr.Checkbox(label=f"🪄 Auto-include {self.dropdown_item_name} in prompt", value=False, elem_classes=["wizard-autoinclude",mode_string]) + gr.Checkbox(label=f"🪄 Auto-include {self.dropdown_item_name} in prompt", value=False, elem_classes=["wizard-autoinclude", mode_string]) # Add event listeners wizard_prep_event_listeners(self.filtered_templates[filename]) Unprompted.log.debug(f"Added {'img2img' if is_img2img else 'txt2img'} Wizard Template: {self.dropdown_item_name}") @@ -460,7 +461,7 @@ def wizard_add_template(show_me=False): def wizard_populate_shortcodes(region, first_load=False): if not first_load: Unprompted.load_shortcodes() - Unprompted.log.warning("Sorry, Gradio is presently incapable of dynamically creating UI elements. You must restart the WebUI to see new shortcodes in the Wizard. This is expected to change in a future release: https://github.com/gradio-app/gradio/issues/4689") + Unprompted.log.warning("Sorry, Gradio is presently incapable of dynamically creating UI elements. You must restart the WebUI to see new shortcodes in the Wizard. This is expected to change in a future release: https://github.com/gradio-app/gradio/issues/4689") return "" with region: @@ -472,7 +473,7 @@ def wizard_populate_shortcodes(region, first_load=False): # Run the shortcode's UI template to populate Unprompted.shortcode_objects[key].ui(gr) # Auto-include is always the last element - gr.Checkbox(label=f"🪄 Auto-include [{key}] in prompt", value=False, elem_classes=["wizard-autoinclude",mode_string]) + gr.Checkbox(label=f"🪄 Auto-include [{key}] in prompt", value=False, elem_classes=["wizard-autoinclude", mode_string]) # Add event listeners wizard_prep_event_listeners(self.filtered_shortcodes[key]) @@ -484,54 +485,59 @@ def wizard_refresh_templates(): Unprompted.log.debug("Refreshing the Wizard Templates...") Unprompted.log.warning("Sorry, Gradio is presently incapable of dynamically creating UI elements. You must restart the WebUI to update Wizard templates. This is expected to change in a future release: https://github.com/gradio-app/gradio/issues/4689") return "" - Unprompted.wizard_template_names.clear() - Unprompted.wizard_template_files.clear() - Unprompted.wizard_template_kwargs.clear() - return wizard_populate_templates(self.templates_region[int(is_img2img)]) + if Unprompted.Config.ui.wizard_templates: + Unprompted.wizard_template_names.clear() + Unprompted.wizard_template_files.clear() + Unprompted.wizard_template_kwargs.clear() + return wizard_populate_templates(self.templates_region[int(is_img2img)]) + return "" def wizard_refresh_shortcodes(): Unprompted.log.debug("Refreshing the Wizard Shortcodes...") return wizard_populate_shortcodes(self.shortcodes_region[int(is_img2img)]) - with gr.Tab("Templates"): - with gr.Row(): - self.templates_dropdown[int(is_img2img)] = gr.Dropdown(choices=[], label="Select template:", type="index", info="These are your GUI templates - you can think of them like custom scripts, except you can run an unlimited number of them at the same time.") - templates_refresh = ToolButton(value='\U0001f504', elem_id=f"templates-refresh") - templates_refresh.click(fn=wizard_refresh_templates) # , outputs=self.templates_dropdown[int(is_img2img)] + if Unprompted.Config.ui.wizard_templates: + with gr.Tab("Templates"): + with gr.Row(): + self.templates_dropdown[int(is_img2img)] = gr.Dropdown(choices=[], label="Select template:", type="index", info="These are your GUI templates - you can think of them like custom scripts, except you can run an unlimited number of them at the same time.") + templates_refresh = ToolButton(value='\U0001f504', elem_id=f"templates-refresh") + templates_refresh.click(fn=wizard_refresh_templates) # , outputs=self.templates_dropdown[int(is_img2img)] - self.templates_region[int(is_img2img)] = gr.Blocks() - wizard_populate_templates(self.templates_region[int(is_img2img)], True) + self.templates_region[int(is_img2img)] = gr.Blocks() + wizard_populate_templates(self.templates_region[int(is_img2img)], True) - self.templates_dropdown[int(is_img2img)].choices = Unprompted.wizard_template_names + self.templates_dropdown[int(is_img2img)].choices = Unprompted.wizard_template_names - wizard_template_btn = gr.Button(value="🧠 Generate Shortcode") + wizard_template_btn = gr.Button(value="🧠 Generate Shortcode") - with gr.Tab("Shortcodes"): - shortcode_list = list(Unprompted.shortcode_objects.keys()) - with gr.Row(): - self.shortcodes_dropdown[int(is_img2img)] = gr.Dropdown(choices=shortcode_list, label="Select shortcode:", value=Unprompted.Config.ui.wizard_default_shortcode, info="GUI for setting up any shortcode in Unprompted. More engaging than reading the manual!") - shortcodes_refresh = ToolButton(value='\U0001f504', elemn_id=f"shortcodes-refresh") - shortcodes_refresh.click(fn=wizard_refresh_shortcodes) # , outputs=self.shortcodes_dropdown[int(is_img2img)] + if Unprompted.Config.ui.wizard_shortcodes: + with gr.Tab("Shortcodes"): + shortcode_list = list(Unprompted.shortcode_objects.keys()) + with gr.Row(): + self.shortcodes_dropdown[int(is_img2img)] = gr.Dropdown(choices=shortcode_list, label="Select shortcode:", value=Unprompted.Config.ui.wizard_default_shortcode, info="GUI for setting up any shortcode in Unprompted. More engaging than reading the manual!") + shortcodes_refresh = ToolButton(value='\U0001f504', elemn_id=f"shortcodes-refresh") + shortcodes_refresh.click(fn=wizard_refresh_shortcodes) # , outputs=self.shortcodes_dropdown[int(is_img2img)] - self.shortcodes_region[int(is_img2img)] = gr.Blocks() - wizard_populate_shortcodes(self.shortcodes_region[int(is_img2img)], True) + self.shortcodes_region[int(is_img2img)] = gr.Blocks() + wizard_populate_shortcodes(self.shortcodes_region[int(is_img2img)], True) - wizard_shortcode_btn = gr.Button(value="🧠 Generate Shortcode") + wizard_shortcode_btn = gr.Button(value="🧠 Generate Shortcode") - with gr.Tab("Capture"): - gr.Markdown(value="This assembles Unprompted code with the WebUI settings for the last image you generated. You can save the code to your `templates` folder and `[call]` it later, or send it to someone as 'preset' for foolproof image reproduction.

**⚠️ Important:** When you change your inference settings, you must generate an image before Unprompted can detect the changes. This is due to a limitation in the WebUI extension framework.") - # wizard_capture_include_inference = gr.Checkbox(label="Include inference settings",value=True) - wizard_capture_include_inference = gr.Radio(label="Include inference settings:", choices=["none", "simple", "verbose"], value="simple", interactive=True) - wizard_capture_include_prompt = gr.Radio(label="Include prompt:", choices=["none", "original", "postprocessed"], value="original", interactive=True) - wizard_capture_include_neg_prompt = gr.Radio(label="Include negative prompt:", choices=["none", "original", "postprocessed"], value="original", interactive=True) - wizard_capture_include_model = gr.Checkbox(label="Include model", value=False) - wizard_capture_add_template_block = gr.Checkbox(label="Add [template] block", value=False) - wizard_capture_btn = gr.Button(value="Generate code for my last image") + if Unprompted.Config.ui.wizard_capture: + with gr.Tab("Capture"): + gr.Markdown(value="This assembles Unprompted code with the WebUI settings for the last image you generated. You can save the code to your `templates` folder and `[call]` it later, or send it to someone as 'preset' for foolproof image reproduction.

**⚠️ Important:** When you change your inference settings, you must generate an image before Unprompted can detect the changes. This is due to a limitation in the WebUI extension framework.") + # wizard_capture_include_inference = gr.Checkbox(label="Include inference settings",value=True) + wizard_capture_include_inference = gr.Radio(label="Include inference settings:", choices=["none", "simple", "verbose"], value="simple", interactive=True) + wizard_capture_include_prompt = gr.Radio(label="Include prompt:", choices=["none", "original", "postprocessed"], value="original", interactive=True) + wizard_capture_include_neg_prompt = gr.Radio(label="Include negative prompt:", choices=["none", "original", "postprocessed"], value="original", interactive=True) + wizard_capture_include_model = gr.Checkbox(label="Include model", value=False) + wizard_capture_add_template_block = gr.Checkbox(label="Add [template] block", value=False) + wizard_capture_btn = gr.Button(value="Generate code for my last image") wizard_result = gr.HTML(label="wizard_result", value="", elem_id="unprompted_result") - wizard_template_btn.click(fn=wizard_generate_template, inputs=[self.templates_dropdown[int(is_img2img)], gr.Variable(value=is_img2img), gr.Variable(value="RESULT: ")], outputs=wizard_result) - wizard_shortcode_btn.click(fn=wizard_generate_shortcode, inputs=[self.shortcodes_dropdown[int(is_img2img)], gr.Variable(value=is_img2img), gr.Variable(value="RESULT: ")], outputs=wizard_result) - wizard_capture_btn.click(fn=wizard_generate_capture, inputs=[wizard_capture_include_inference, wizard_capture_include_prompt, wizard_capture_include_neg_prompt, wizard_capture_include_model, wizard_capture_add_template_block], outputs=wizard_result) + if Unprompted.Config.ui.wizard_templates: wizard_template_btn.click(fn=wizard_generate_template, inputs=[self.templates_dropdown[int(is_img2img)], gr.Variable(value=is_img2img), gr.Variable(value="RESULT: ")], outputs=wizard_result) + if Unprompted.Config.ui.wizard_shortcodes: wizard_shortcode_btn.click(fn=wizard_generate_shortcode, inputs=[self.shortcodes_dropdown[int(is_img2img)], gr.Variable(value=is_img2img), gr.Variable(value="RESULT: ")], outputs=wizard_result) + if Unprompted.Config.ui.wizard_capture: wizard_capture_btn.click(fn=wizard_generate_capture, inputs=[wizard_capture_include_inference, wizard_capture_include_prompt, wizard_capture_include_neg_prompt, wizard_capture_include_model, wizard_capture_add_template_block], outputs=wizard_result) else: gr.HTML(label="wizard_debug", value="You have disabled the Wizard in your config.") @@ -569,13 +575,12 @@ def open_folder(path): with gr.Tab("🎓 Guides"): guide = gr.Markdown(value=get_markdown("docs/GUIDE.md")) - def reload_unprompted(): Unprompted.log.debug("Reloading Unprompted...") Unprompted.log.debug("Reloading `config.json`...") Unprompted.cfg_dict, Unprompted.Config = parse_config(base_dir) Unprompted.load_shortcodes() - # self.shortcodes_dropdown[int(is_img2img)].update(choices=wizard_refresh_shortcodes()) + # self.shortcodes_dropdown[int(is_img2img)].update(choices=wizard_refresh_shortcodes()) # self.templates_dropdown[int(is_img2img)].update(choices=wizard_refresh_templates()) Unprompted.log.debug("Reload completed!") @@ -777,7 +782,6 @@ def process(self, p, is_enabled=True, unprompted_seed=-1, match_main_seed=True, Unprompted.shortcode_user_vars["batch_size_index"] += 1 Unprompted.shortcode_user_vars["batch_real_index"] += 1 - if Unprompted.fix_hires_prompts: Unprompted.log.debug("Synchronizing prompt vars with hr_prompt vars") p.hr_prompt = prompt_result @@ -903,4 +907,4 @@ def postprocess(self, p, processed, is_enabled=True, unprompted_seed=-1, match_m self.allow_postprocess = True - return processed \ No newline at end of file + return processed diff --git a/shortcodes/basic/get.py b/shortcodes/basic/get.py index 42844c9..1a51e6c 100644 --- a/shortcodes/basic/get.py +++ b/shortcodes/basic/get.py @@ -6,8 +6,9 @@ def __init__(self, Unprompted): def run_atomic(self, pargs, kwargs, context): import lib_unprompted.helpers as helpers _default = str(self.Unprompted.parse_advanced(kwargs["_default"], context)) if "_default" in kwargs else "" - _sep = str(self.Unprompted.parse_advanced(kwargs["_sep"], context)) if "_sep" in kwargs else " " + _sep = str(self.Unprompted.parse_advanced(kwargs["_sep"], context)) if "_sep" in kwargs else self.Unprompted.Config.syntax.delimiter _escape = self.Unprompted.parse_arg("_escape",False) + _key = self.Unprompted.parse_arg("_key",False) return_string = "" @@ -20,7 +21,17 @@ def run_atomic(self, pargs, kwargs, context): self.Unprompted.shortcode_user_vars[key] = value if "_var" in kwargs: - return_string += str(self.Unprompted.parse_advanced(kwargs["_var"], context)) + return_string += str(self.Unprompted.parse_advanced(kwargs["_var"], context)) + _sep + + if "_regex" in kwargs: + import re + regex = re.compile(kwargs["_regex"]) + for key, value in self.Unprompted.shortcode_user_vars.items(): + if regex.match(key): + if _key: return_string += f"{key}{_sep}" + else: return_string += f"{value}{_sep}" + + if return_string: return_string = return_string[:-len(_sep)] for idx, parg in enumerate(pargs): self.Unprompted.is_var_deprecated(parg) @@ -48,7 +59,9 @@ def run_atomic(self, pargs, kwargs, context): this_var = self.Unprompted.process_string(self.Unprompted.shortcode_user_vars[parg],context) if "_read_only" not in pargs: self.Unprompted.shortcode_user_vars[parg] = this_var - else: this_var = self.Unprompted.shortcode_user_vars[parg] + else: + if _key: this_var = parg + else: this_var = self.Unprompted.shortcode_user_vars[parg] if (isinstance(this_var, list)): return_string += _sep.join(str(x) for x in this_var) else: return_string += str(this_var) diff --git a/shortcodes/basic/max.py b/shortcodes/basic/max.py index b43e205..af8c3cc 100644 --- a/shortcodes/basic/max.py +++ b/shortcodes/basic/max.py @@ -4,10 +4,26 @@ def __init__(self,Unprompted): self.description = "Returns the maximum value among the given arguments." def run_atomic(self, pargs, kwargs, context): max_value = None + return_key = self.Unprompted.parse_arg("_key", False) + to_return = "" + for key in pargs: - this_value = self.Unprompted.parse_advanced(key) - if max_value is None or float(this_value) > max_value: max_value = this_value - return(max_value) + # Array support: + key_split = self.Unprompted.parse_alt_tags(key).split(self.Unprompted.Config.syntax.delimiter) + for this_key in key_split: + if self.Unprompted.is_system_arg(this_key): continue + + this_value = self.Unprompted.parse_advanced(this_key) + try: + if max_value is None or float(this_value) > max_value: + max_value = this_value + + if return_key: to_return = this_key + else: to_return = max_value + except: + pass + + return(to_return) def ui(self,gr): pass \ No newline at end of file diff --git a/shortcodes/basic/min.py b/shortcodes/basic/min.py index 53910ff..6e8f164 100644 --- a/shortcodes/basic/min.py +++ b/shortcodes/basic/min.py @@ -4,10 +4,26 @@ def __init__(self,Unprompted): self.description = "Returns the minimum value among the given arguments." def run_atomic(self, pargs, kwargs, context): min_value = None + return_key = self.Unprompted.parse_arg("_key", False) + to_return = "" + for key in pargs: - this_value = self.Unprompted.parse_advanced(key) - if min_value is None or float(this_value) < min_value: min_value = this_value - return(min_value) + # Array support: + key_split = self.Unprompted.parse_alt_tags(key).split(self.Unprompted.Config.syntax.delimiter) + for this_key in key_split: + if self.Unprompted.is_system_arg(this_key): continue + + this_value = self.Unprompted.parse_advanced(key) + try: + if min_value is None or float(this_value) < min_value: + min_value = this_value + + if return_key: to_return = this_key + else: to_return = min_value + except: + pass + + return(to_return) def ui(self,gr): pass \ No newline at end of file diff --git a/shortcodes/basic/set.py b/shortcodes/basic/set.py index f656eb6..7243dce 100644 --- a/shortcodes/basic/set.py +++ b/shortcodes/basic/set.py @@ -10,14 +10,16 @@ def run_block(self, pargs, kwargs, context, content): import lib_unprompted.helpers as helpers overrides = self.Unprompted.shortcode_objects["overrides"] can_set = True - + if (content is None or len(content) < 1): return "" - self.Unprompted.is_var_deprecated(pargs[0]) + key = self.Unprompted.parse_alt_tags(pargs[0],context) + + self.Unprompted.is_var_deprecated(key) # Prep content with override support - if (pargs[0] in overrides.shortcode_overrides): - content = overrides.shortcode_overrides[pargs[0]] + if (key in overrides.shortcode_overrides): + content = overrides.shortcode_overrides[key] elif "_defer" not in pargs: if "_raw" in pargs: content = self.Unprompted.process_string(content, context) @@ -26,24 +28,24 @@ def run_block(self, pargs, kwargs, context, content): content = helpers.autocast(content) if "_new" in pargs: - if pargs[0] in self.Unprompted.shortcode_user_vars: + if key in self.Unprompted.shortcode_user_vars: # Check if this var already holds a valid value, if not we will set it if "_choices" in kwargs: - if self.Unprompted.shortcode_user_vars[pargs[0]] in self.Unprompted.parse_advanced(kwargs["_choices"], context).split(self.Unprompted.Config.syntax.delimiter): can_set = False + if self.Unprompted.shortcode_user_vars[key] in self.Unprompted.parse_advanced(kwargs["_choices"], context).split(self.Unprompted.Config.syntax.delimiter): can_set = False else: can_set = False elif "_choices" in kwargs: if str(content) not in self.Unprompted.parse_advanced(kwargs["_choices"], context).split(self.Unprompted.Config.syntax.delimiter): can_set = False if can_set: - if ("_append" in pargs): self.Unprompted.shortcode_user_vars[pargs[0]] += content - elif ("_prepend" in pargs): self.Unprompted.shortcode_user_vars[pargs[0]] = content + self.Unprompted.shortcode_user_vars[pargs[0]] - else: self.Unprompted.shortcode_user_vars[pargs[0]] = content + if ("_append" in pargs): self.Unprompted.shortcode_user_vars[key] += content + elif ("_prepend" in pargs): self.Unprompted.shortcode_user_vars[key] = content + self.Unprompted.shortcode_user_vars[key] + else: self.Unprompted.shortcode_user_vars[key] = content - self.log.debug(f"Setting {pargs[0]} to {self.Unprompted.shortcode_user_vars[pargs[0]]}") + self.log.debug(f"Setting {key} to {self.Unprompted.shortcode_user_vars[key]}") if "_remember" in pargs: - if pargs[0] not in self.Unprompted.shortcode_objects["remember"].globals: - self.Unprompted.shortcode_objects["remember"].globals.append(pargs[0]) + if key not in self.Unprompted.shortcode_objects["remember"].globals: + self.Unprompted.shortcode_objects["remember"].globals.append(key) if "_external" in kwargs: import json @@ -51,12 +53,12 @@ def run_block(self, pargs, kwargs, context, content): # We load the file twice so that we can prepare the full data to send with json.dump json_obj = helpers.create_load_json(filepath, encoding=self.Unprompted.Config.formats.default_encoding) - json_obj[pargs[0]] = self.Unprompted.shortcode_user_vars[pargs[0]] + json_obj[key] = self.Unprompted.shortcode_user_vars[key] with open(filepath, "w", encoding=self.Unprompted.Config.formats.default_encoding) as f: json.dump(json_obj, f, ensure_ascii=False) - if ("_out" in pargs): return (self.Unprompted.shortcode_user_vars[pargs[0]]) + if ("_out" in pargs): return (self.Unprompted.shortcode_user_vars[key]) else: return ("") def ui(self, gr): diff --git a/shortcodes/stable_diffusion/faceswap.py b/shortcodes/stable_diffusion/faceswap.py index 4677b71..2778a7c 100644 --- a/shortcodes/stable_diffusion/faceswap.py +++ b/shortcodes/stable_diffusion/faceswap.py @@ -111,7 +111,7 @@ def get_faces(img_data: np.ndarray, face_index=0, det_size=(640, 640)): self.fs_pipeline[swap_method]["face"] = [face] embedding_str = self.Unprompted.parse_arg("embedding_path","blended_faces") - embedding_path = self.Unprompted.parse_filepath(helpers.str_with_ext(embedding_str, "safetensors"), context=context, must_exist=False, root=self.base_dir + "/user/faces") + embedding_path = self.Unprompted.parse_filepath(helpers.str_with_ext(embedding_str, ".safetensors"), context=context, must_exist=False, root=self.Unprompted.base_dir + "/user/faces") os.makedirs(os.path.dirname(embedding_path), exist_ok=True) # If embedding file already exists, increment the filename until it doesn't dupe_counter = 2