From c602471b85d270e8c36707817d9bad92b0ff991e Mon Sep 17 00:00:00 2001 From: missionfloyd Date: Wed, 5 Jul 2023 03:19:26 -0600 Subject: Allow gif for extra network previews --- modules/ui_extra_networks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index a7d3bc79..1efd00b0 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -30,8 +30,8 @@ def fetch_file(filename: str = ""): raise ValueError(f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.") ext = os.path.splitext(filename)[1].lower() - if ext not in (".png", ".jpg", ".jpeg", ".webp"): - raise ValueError(f"File cannot be fetched: {filename}. Only png and jpg and webp.") + if ext not in (".png", ".jpg", ".jpeg", ".webp", ".gif"): + raise ValueError(f"File cannot be fetched: {filename}. Only png, jpg, webp, and gif.") # would profit from returning 304 return FileResponse(filename, headers={"Accept-Ranges": "bytes"}) -- cgit v1.2.1 From d7d6e8cfc8b85a99a48f82975ee213d487783c28 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 8 Jul 2023 16:45:59 +0300 Subject: use natural sort for shared.walk_files and shared.listfiles, as well as for dirs in extra networks --- modules/ui_extra_networks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 1efd00b0..693cafb6 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -90,8 +90,8 @@ class ExtraNetworksPage: subdirs = {} for parentdir in [os.path.abspath(x) for x in self.allowed_directories_for_previews()]: - for root, dirs, _ in os.walk(parentdir, followlinks=True): - for dirname in dirs: + for root, dirs, _ in sorted(os.walk(parentdir, followlinks=True), key=lambda x: shared.natural_sort_key(x[0])): + for dirname in sorted(dirs, key=shared.natural_sort_key): x = os.path.join(root, dirname) if not os.path.isdir(x): -- cgit v1.2.1 From e5d3ae2bf4e9d39c35e6edc96d6449fd42528e55 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sat, 15 Jul 2023 20:39:04 +0300 Subject: user metadata system for custom networks --- modules/ui_extra_networks.py | 54 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 693cafb6..eaae6217 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -2,7 +2,7 @@ import os.path import urllib.parse from pathlib import Path -from modules import shared +from modules import shared, ui_extra_networks_user_metadata, errors from modules.images import read_info_from_image, save_image_with_geninfo from modules.ui import up_down_symbol import gradio as gr @@ -60,13 +60,34 @@ class ExtraNetworksPage: def __init__(self, title): self.title = title self.name = title.lower() + self.id_page = self.name.replace(" ", "_") self.card_page = shared.html("extra-networks-card.html") self.allow_negative_prompt = False self.metadata = {} + self.items = {} def refresh(self): pass + def read_user_metadata(self, item): + filename = item.get("filename", None) + basename, ext = os.path.splitext(filename) + metadata_filename = basename + '.json' + + metadata = {} + try: + if os.path.isfile(metadata_filename): + with open(metadata_filename, "r", encoding="utf8") as file: + metadata = json.load(file) + except Exception as e: + errors.display(e, f"reading extra network user metadata from {metadata_filename}") + + desc = metadata.get("description", None) + if desc is not None: + item["description"] = desc + + item["user_metadata"] = metadata + def link_preview(self, filename): quoted_filename = urllib.parse.quote(filename.replace('\\', '/')) mtime = os.path.getmtime(filename) @@ -119,11 +140,15 @@ class ExtraNetworksPage: """ for subdir in subdirs]) - for item in self.list_items(): + self.items = {x["name"]: x for x in self.list_items()} + for item in self.items.values(): metadata = item.get("metadata") if metadata: self.metadata[item["name"]] = metadata + if "user_metadata" not in item: + self.read_user_metadata(item) + items_html += self.create_html_for_item(item, tabname) if items_html == '': @@ -166,7 +191,9 @@ class ExtraNetworksPage: metadata_button = "" metadata = item.get("metadata") if metadata: - metadata_button = f"
" + metadata_button = f"
" + + edit_button = f"
" local_path = "" filename = item.get("filename", "") @@ -200,6 +227,7 @@ class ExtraNetworksPage: "save_card_preview": '"' + html.escape(f"""return saveCardPreview(event, {json.dumps(tabname)}, {json.dumps(item["local_preview"])})""") + '"', "search_term": item.get("search_term", ""), "metadata_button": metadata_button, + "edit_button": edit_button, "search_only": " search_only" if search_only else "", "sort_keys": sort_keys, } @@ -247,6 +275,9 @@ class ExtraNetworksPage: pass return None + def create_user_metadata_editor(self, ui, tabname): + return ui_extra_networks_user_metadata.UserMetadataEditor(ui, tabname, self) + def initialize(): extra_pages.clear() @@ -297,20 +328,23 @@ def create_ui(container, button, tabname): ui = ExtraNetworksUi() ui.pages = [] ui.pages_contents = [] + ui.user_metadata_editors = [] ui.stored_extra_pages = pages_in_preferred_order(extra_pages.copy()) ui.tabname = tabname with gr.Tabs(elem_id=tabname+"_extra_tabs"): for page in ui.stored_extra_pages: - page_id = page.title.lower().replace(" ", "_") - - with gr.Tab(page.title, id=page_id): - elem_id = f"{tabname}_{page_id}_cards_html" + with gr.Tab(page.title, id=page.id_page): + elem_id = f"{tabname}_{page.id_page}_cards_html" page_elem = gr.HTML('Loading...', elem_id=elem_id) ui.pages.append(page_elem) page_elem.change(fn=lambda: None, _js='function(){applyExtraNetworkFilter(' + json.dumps(tabname) + '); return []}', inputs=[], outputs=[]) + editor = page.create_user_metadata_editor(ui, tabname) + editor.create_ui() + ui.user_metadata_editors.append(editor) + gr.Textbox('', show_label=False, elem_id=tabname+"_extra_search", placeholder="Search...", visible=False) gr.Dropdown(choices=['Default Sort', 'Date Created', 'Date Modified', 'Name'], value='Default Sort', elem_id=tabname+"_extra_sort", multiselect=False, visible=False, show_label=False, interactive=True) gr.Button(up_down_symbol, elem_id=tabname+"_extra_sortorder") @@ -363,6 +397,8 @@ def path_is_parent(parent_path, child_path): def setup_ui(ui, gallery): def save_preview(index, images, filename): + # this function is here for backwards compatibility and likely will be removed soon + if len(images) == 0: print("There is no image in gallery to save as a preview.") return [page.create_html(ui.tabname) for page in ui.stored_extra_pages] @@ -394,3 +430,7 @@ def setup_ui(ui, gallery): outputs=[*ui.pages] ) + for editor in ui.user_metadata_editors: + editor.setup_ui(gallery) + + -- cgit v1.2.1 From 8c11b126e5bd5052154c095177390f249e8e9889 Mon Sep 17 00:00:00 2001 From: huchenlei Date: Sat, 15 Jul 2023 23:43:49 -0400 Subject: 404 when thumb file not found --- modules/ui_extra_networks.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 693cafb6..a2565315 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -8,6 +8,7 @@ from modules.ui import up_down_symbol import gradio as gr import json import html +from fastapi.exceptions import HTTPException from modules.generation_parameters_copypaste import image_from_url_text @@ -26,6 +27,9 @@ def register_page(page): def fetch_file(filename: str = ""): from starlette.responses import FileResponse + if not os.path.isfile(filename): + raise HTTPException(status_code=404, detail="File not found") + if not any(Path(x).absolute() in Path(filename).absolute().parents for x in allowed_dirs): raise ValueError(f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.") -- cgit v1.2.1 From a1d6ada69ac686a628e79b61b8f86d01592a7209 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sun, 16 Jul 2023 08:38:23 +0300 Subject: allow refreshing single card after editing user metadata instead of all cards --- modules/ui_extra_networks.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index eaae6217..42c4d0ac 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -51,9 +51,26 @@ def get_metadata(page: str = "", item: str = ""): return JSONResponse({"metadata": metadata}) +def get_single_card(page: str = "", tabname: str = "", name: str = ""): + from starlette.responses import JSONResponse + + page = next(iter([x for x in extra_pages if x.name == page]), None) + + try: + item = page.create_item(name) + except Exception as e: + errors.display(e, "creating item for extra network") + item = page.items.get(name) + + item_html = page.create_html_for_item(item, tabname) + + return JSONResponse({"html": item_html}) + + def add_pages_to_demo(app): app.add_api_route("/sd_extra_networks/thumb", fetch_file, methods=["GET"]) app.add_api_route("/sd_extra_networks/metadata", get_metadata, methods=["GET"]) + app.add_api_route("/sd_extra_networks/get-single-card", get_single_card, methods=["GET"]) class ExtraNetworksPage: @@ -168,6 +185,9 @@ class ExtraNetworksPage: return res + def create_item(self, name, index=None): + raise NotImplementedError() + def list_items(self): raise NotImplementedError() -- cgit v1.2.1 From 47d9dd0240872dc70fd26bc1bf309f49fe17c104 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sun, 16 Jul 2023 09:25:32 +0300 Subject: speedup extra networks listing --- modules/ui_extra_networks.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 42c4d0ac..f9d1fa31 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -73,6 +73,12 @@ def add_pages_to_demo(app): app.add_api_route("/sd_extra_networks/get-single-card", get_single_card, methods=["GET"]) +def quote_js(s): + s = s.replace('\\', '\\\\') + s = s.replace('"', '\\"') + return f'"{s}"' + + class ExtraNetworksPage: def __init__(self, title): self.title = title @@ -203,7 +209,7 @@ class ExtraNetworksPage: onclick = item.get("onclick", None) if onclick is None: - onclick = '"' + html.escape(f"""return cardClicked({json.dumps(tabname)}, {item["prompt"]}, {"true" if self.allow_negative_prompt else "false"})""") + '"' + onclick = '"' + html.escape(f"""return cardClicked({quote_js(tabname)}, {item["prompt"]}, {"true" if self.allow_negative_prompt else "false"})""") + '"' height = f"height: {shared.opts.extra_networks_card_height}px;" if shared.opts.extra_networks_card_height else '' width = f"width: {shared.opts.extra_networks_card_width}px;" if shared.opts.extra_networks_card_width else '' @@ -211,9 +217,9 @@ class ExtraNetworksPage: metadata_button = "" metadata = item.get("metadata") if metadata: - metadata_button = f"" + metadata_button = f"" - edit_button = f"
" + edit_button = f"
" local_path = "" filename = item.get("filename", "") @@ -239,12 +245,12 @@ class ExtraNetworksPage: "background_image": background_image, "style": f"'display: none; {height}{width}'", "prompt": item.get("prompt", None), - "tabname": json.dumps(tabname), - "local_preview": json.dumps(item["local_preview"]), + "tabname": quote_js(tabname), + "local_preview": quote_js(item["local_preview"]), "name": item["name"], "description": (item.get("description") or ""), "card_clicked": onclick, - "save_card_preview": '"' + html.escape(f"""return saveCardPreview(event, {json.dumps(tabname)}, {json.dumps(item["local_preview"])})""") + '"', + "save_card_preview": '"' + html.escape(f"""return saveCardPreview(event, {quote_js(tabname)}, {quote_js(item["local_preview"])})""") + '"', "search_term": item.get("search_term", ""), "metadata_button": metadata_button, "edit_button": edit_button, @@ -359,7 +365,7 @@ def create_ui(container, button, tabname): page_elem = gr.HTML('Loading...', elem_id=elem_id) ui.pages.append(page_elem) - page_elem.change(fn=lambda: None, _js='function(){applyExtraNetworkFilter(' + json.dumps(tabname) + '); return []}', inputs=[], outputs=[]) + page_elem.change(fn=lambda: None, _js='function(){applyExtraNetworkFilter(' + quote_js(tabname) + '); return []}', inputs=[], outputs=[]) editor = page.create_user_metadata_editor(ui, tabname) editor.create_ui() -- cgit v1.2.1 From ccd97886da1f659472cdca3de8731f59a70bbc28 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sun, 16 Jul 2023 09:49:22 +0300 Subject: fix bogus metadata for extra networks appearing out of cache fix description editing for checkpoint not immediately appearing on cards --- modules/ui_extra_networks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 760fba43..a4927c11 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -52,7 +52,7 @@ def get_metadata(page: str = "", item: str = ""): if metadata is None: return JSONResponse({}) - return JSONResponse({"metadata": metadata}) + return JSONResponse({"metadata": json.dumps(metadata, indent=4, ensure_ascii=False)}) def get_single_card(page: str = "", tabname: str = "", name: str = ""): @@ -66,6 +66,7 @@ def get_single_card(page: str = "", tabname: str = "", name: str = ""): errors.display(e, "creating item for extra network") item = page.items.get(name) + page.read_user_metadata(item) item_html = page.create_html_for_item(item, tabname) return JSONResponse({"html": item_html}) -- cgit v1.2.1 From 690d56f3c10e5359e15eeba9c68e56b2eb193ac3 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sun, 16 Jul 2023 10:25:34 +0300 Subject: nuke thumbs extra networks view mode (use settings tab to change width/height/scale to get thumbs) --- modules/ui_extra_networks.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index a4927c11..d9deccb2 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -132,7 +132,6 @@ class ExtraNetworksPage: return "" def create_html(self, tabname): - view = shared.opts.extra_networks_default_view items_html = '' self.metadata = {} @@ -186,10 +185,10 @@ class ExtraNetworksPage: self_name_id = self.name.replace(" ", "_") res = f""" -
+
{subdirs_html}
-
+
{items_html}
""" @@ -248,12 +247,12 @@ class ExtraNetworksPage: args = { "background_image": background_image, - "style": f"'display: none; {height}{width}'", + "style": f"'display: none; {height}{width}; font-size: {shared.opts.extra_networks_card_text_scale*100}%'", "prompt": item.get("prompt", None), "tabname": quote_js(tabname), "local_preview": quote_js(item["local_preview"]), "name": item["name"], - "description": (item.get("description") or ""), + "description": (item.get("description") or "" if shared.opts.extra_networks_card_show_desc else ""), "card_clicked": onclick, "save_card_preview": '"' + html.escape(f"""return saveCardPreview(event, {quote_js(tabname)}, {quote_js(item["local_preview"])})""") + '"', "search_term": item.get("search_term", ""), -- cgit v1.2.1 From 9d3dd64fe9e95873347710ca1df1f1e88d1908e1 Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Sun, 16 Jul 2023 10:44:04 +0300 Subject: minor restyling for extra networks --- modules/ui_extra_networks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index d9deccb2..6c73998f 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -11,6 +11,7 @@ import html from fastapi.exceptions import HTTPException from modules.generation_parameters_copypaste import image_from_url_text +from modules.ui_components import ToolButton extra_pages = [] allowed_dirs = set() @@ -377,7 +378,7 @@ def create_ui(container, button, tabname): gr.Textbox('', show_label=False, elem_id=tabname+"_extra_search", placeholder="Search...", visible=False) gr.Dropdown(choices=['Default Sort', 'Date Created', 'Date Modified', 'Name'], value='Default Sort', elem_id=tabname+"_extra_sort", multiselect=False, visible=False, show_label=False, interactive=True) - gr.Button(up_down_symbol, elem_id=tabname+"_extra_sortorder") + ToolButton(up_down_symbol, elem_id=tabname+"_extra_sortorder") button_refresh = gr.Button('Refresh', elem_id=tabname+"_extra_refresh") ui.button_save_preview = gr.Button('Save preview', elem_id=tabname+"_save_preview", visible=False) -- cgit v1.2.1 From 699108bfbb05c2a7d2ee4a2c7abcfaa0a244d8ea Mon Sep 17 00:00:00 2001 From: AUTOMATIC1111 <16777216c@gmail.com> Date: Mon, 17 Jul 2023 18:56:14 +0300 Subject: hide cards for networks of incompatible stable diffusion version in Lora extra networks interface --- modules/ui_extra_networks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'modules/ui_extra_networks.py') diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 6c73998f..49612298 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -62,7 +62,8 @@ def get_single_card(page: str = "", tabname: str = "", name: str = ""): page = next(iter([x for x in extra_pages if x.name == page]), None) try: - item = page.create_item(name) + item = page.create_item(name, enable_filter=False) + page.items[name] = item except Exception as e: errors.display(e, "creating item for extra network") item = page.items.get(name) -- cgit v1.2.1