allow refreshing single card after editing user metadata instead of all cards
This commit is contained in:
parent
efceed8c7f
commit
a1d6ada69a
@ -182,6 +182,4 @@ class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor)
|
|||||||
self.edit_notes,
|
self.edit_notes,
|
||||||
]
|
]
|
||||||
|
|
||||||
self.button_save\
|
self.setup_save_handler(self.button_save, self.save_lora_user_metadata, edited_components)
|
||||||
.click(fn=self.save_lora_user_metadata, inputs=[self.edit_name_input, *edited_components], outputs=[]) \
|
|
||||||
.then(fn=None, _js="extraNetworksReloadAll")
|
|
||||||
|
@ -13,31 +13,37 @@ class ExtraNetworksPageLora(ui_extra_networks.ExtraNetworksPage):
|
|||||||
def refresh(self):
|
def refresh(self):
|
||||||
lora.list_available_loras()
|
lora.list_available_loras()
|
||||||
|
|
||||||
|
def create_item(self, name, index=None):
|
||||||
|
lora_on_disk = lora.available_loras.get(name)
|
||||||
|
|
||||||
|
path, ext = os.path.splitext(lora_on_disk.filename)
|
||||||
|
|
||||||
|
alias = lora_on_disk.get_alias()
|
||||||
|
|
||||||
|
item = {
|
||||||
|
"name": name,
|
||||||
|
"filename": lora_on_disk.filename,
|
||||||
|
"preview": self.find_preview(path),
|
||||||
|
"description": self.find_description(path),
|
||||||
|
"search_term": self.search_terms_from_path(lora_on_disk.filename),
|
||||||
|
"local_preview": f"{path}.{shared.opts.samples_format}",
|
||||||
|
"metadata": json.dumps(lora_on_disk.metadata, indent=4) if lora_on_disk.metadata else None,
|
||||||
|
"sort_keys": {'default': index, **self.get_sort_keys(lora_on_disk.filename)},
|
||||||
|
}
|
||||||
|
|
||||||
|
self.read_user_metadata(item)
|
||||||
|
activation_text = item["user_metadata"].get("activation text")
|
||||||
|
preferred_weight = item["user_metadata"].get("preferred weight", 0.0)
|
||||||
|
item["prompt"] = json.dumps(f"<lora:{alias}:") + " + " + (str(preferred_weight) if preferred_weight else "opts.extra_networks_default_multiplier") + " + " + json.dumps(">")
|
||||||
|
|
||||||
|
if activation_text:
|
||||||
|
item["prompt"] += " + " + json.dumps(" " + activation_text)
|
||||||
|
|
||||||
|
return item
|
||||||
|
|
||||||
def list_items(self):
|
def list_items(self):
|
||||||
for index, (name, lora_on_disk) in enumerate(lora.available_loras.items()):
|
for index, name in enumerate(lora.available_loras):
|
||||||
path, ext = os.path.splitext(lora_on_disk.filename)
|
item = self.create_item(name, index)
|
||||||
|
|
||||||
alias = lora_on_disk.get_alias()
|
|
||||||
|
|
||||||
item = {
|
|
||||||
"name": name,
|
|
||||||
"filename": lora_on_disk.filename,
|
|
||||||
"preview": self.find_preview(path),
|
|
||||||
"description": self.find_description(path),
|
|
||||||
"search_term": self.search_terms_from_path(lora_on_disk.filename),
|
|
||||||
"local_preview": f"{path}.{shared.opts.samples_format}",
|
|
||||||
"metadata": json.dumps(lora_on_disk.metadata, indent=4) if lora_on_disk.metadata else None,
|
|
||||||
"sort_keys": {'default': index, **self.get_sort_keys(lora_on_disk.filename)},
|
|
||||||
}
|
|
||||||
|
|
||||||
self.read_user_metadata(item)
|
|
||||||
activation_text = item["user_metadata"].get("activation text")
|
|
||||||
preferred_weight = item["user_metadata"].get("preferred weight", 0.0)
|
|
||||||
item["prompt"] = json.dumps(f"<lora:{alias}:") + " + " + (str(preferred_weight) if preferred_weight else "opts.extra_networks_default_multiplier") + " + " + json.dumps(">")
|
|
||||||
|
|
||||||
if activation_text:
|
|
||||||
item["prompt"] += " + " + json.dumps(" " + activation_text)
|
|
||||||
|
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
def allowed_directories_for_previews(self):
|
def allowed_directories_for_previews(self):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div class='card' style={style} onclick={card_clicked} {sort_keys}>
|
<div class='card' style={style} onclick={card_clicked} data-name="{name}" {sort_keys}>
|
||||||
{background_image}
|
{background_image}
|
||||||
<div class="button-row">
|
<div class="button-row">
|
||||||
{edit_button}
|
{edit_button}
|
||||||
|
@ -296,9 +296,18 @@ function extraNetworksEditUserMetadata(event, tabname, extraPage, cardName) {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
function extraNetworksReloadAll() {
|
function extraNetworksRefreshSingleCard(page, tabname, name) {
|
||||||
closePopup();
|
requestGet("./sd_extra_networks/get-single-card", {page: page, tabname: tabname, name: name}, function(data) {
|
||||||
|
if (data && data.html) {
|
||||||
|
var card = gradioApp().querySelector('.card[data-name=' + JSON.stringify(name) + ']'); // likely using the wrong stringify function
|
||||||
|
|
||||||
gradioApp().getElementById('txt2img_extra_refresh').click();
|
var newDiv = document.createElement('DIV');
|
||||||
gradioApp().getElementById('img2img_extra_refresh').click();
|
newDiv.innerHTML = data.html;
|
||||||
|
var newCard = newDiv.firstElementChild;
|
||||||
|
|
||||||
|
newCard.style = '';
|
||||||
|
card.parentElement.insertBefore(newCard, card);
|
||||||
|
card.parentElement.removeChild(card);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -51,9 +51,26 @@ def get_metadata(page: str = "", item: str = ""):
|
|||||||
return JSONResponse({"metadata": metadata})
|
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):
|
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/thumb", fetch_file, methods=["GET"])
|
||||||
app.add_api_route("/sd_extra_networks/metadata", get_metadata, 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:
|
class ExtraNetworksPage:
|
||||||
@ -168,6 +185,9 @@ class ExtraNetworksPage:
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def create_item(self, name, index=None):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
def list_items(self):
|
def list_items(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -12,21 +12,24 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage):
|
|||||||
def refresh(self):
|
def refresh(self):
|
||||||
shared.refresh_checkpoints()
|
shared.refresh_checkpoints()
|
||||||
|
|
||||||
def list_items(self):
|
def create_item(self, name, index=None):
|
||||||
checkpoint: sd_models.CheckpointInfo
|
checkpoint: sd_models.CheckpointInfo = sd_models.checkpoints_list.get(name)
|
||||||
for index, (name, checkpoint) in enumerate(sd_models.checkpoints_list.items()):
|
path, ext = os.path.splitext(checkpoint.filename)
|
||||||
path, ext = os.path.splitext(checkpoint.filename)
|
return {
|
||||||
yield {
|
"name": checkpoint.name_for_extra,
|
||||||
"name": checkpoint.name_for_extra,
|
"filename": checkpoint.filename,
|
||||||
"filename": checkpoint.filename,
|
"preview": self.find_preview(path),
|
||||||
"preview": self.find_preview(path),
|
"description": self.find_description(path),
|
||||||
"description": self.find_description(path),
|
"search_term": self.search_terms_from_path(checkpoint.filename) + " " + (checkpoint.sha256 or ""),
|
||||||
"search_term": self.search_terms_from_path(checkpoint.filename) + " " + (checkpoint.sha256 or ""),
|
"onclick": '"' + html.escape(f"""return selectCheckpoint({json.dumps(name)})""") + '"',
|
||||||
"onclick": '"' + html.escape(f"""return selectCheckpoint({json.dumps(name)})""") + '"',
|
"local_preview": f"{path}.{shared.opts.samples_format}",
|
||||||
"local_preview": f"{path}.{shared.opts.samples_format}",
|
"sort_keys": {'default': index, **self.get_sort_keys(checkpoint.filename)},
|
||||||
"sort_keys": {'default': index, **self.get_sort_keys(checkpoint.filename)},
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def list_items(self):
|
||||||
|
for index, name in enumerate(sd_models.checkpoints_list):
|
||||||
|
yield self.create_item(name, index)
|
||||||
|
|
||||||
def allowed_directories_for_previews(self):
|
def allowed_directories_for_previews(self):
|
||||||
return [v for v in [shared.cmd_opts.ckpt_dir, sd_models.model_path] if v is not None]
|
return [v for v in [shared.cmd_opts.ckpt_dir, sd_models.model_path] if v is not None]
|
||||||
|
@ -11,21 +11,24 @@ class ExtraNetworksPageHypernetworks(ui_extra_networks.ExtraNetworksPage):
|
|||||||
def refresh(self):
|
def refresh(self):
|
||||||
shared.reload_hypernetworks()
|
shared.reload_hypernetworks()
|
||||||
|
|
||||||
|
def create_item(self, name, index=None):
|
||||||
|
full_path = shared.hypernetworks[name]
|
||||||
|
path, ext = os.path.splitext(full_path)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"filename": full_path,
|
||||||
|
"preview": self.find_preview(path),
|
||||||
|
"description": self.find_description(path),
|
||||||
|
"search_term": self.search_terms_from_path(path),
|
||||||
|
"prompt": json.dumps(f"<hypernet:{name}:") + " + opts.extra_networks_default_multiplier + " + json.dumps(">"),
|
||||||
|
"local_preview": f"{path}.preview.{shared.opts.samples_format}",
|
||||||
|
"sort_keys": {'default': index, **self.get_sort_keys(path + ext)},
|
||||||
|
}
|
||||||
|
|
||||||
def list_items(self):
|
def list_items(self):
|
||||||
for index, (name, full_path) in enumerate(shared.hypernetworks.items()):
|
for index, name in enumerate(shared.hypernetworks):
|
||||||
path, ext = os.path.splitext(full_path)
|
yield self.create_item(name, index)
|
||||||
|
|
||||||
yield {
|
|
||||||
"name": name,
|
|
||||||
"filename": full_path,
|
|
||||||
"preview": self.find_preview(path),
|
|
||||||
"description": self.find_description(path),
|
|
||||||
"search_term": self.search_terms_from_path(path),
|
|
||||||
"prompt": json.dumps(f"<hypernet:{name}:") + " + opts.extra_networks_default_multiplier + " + json.dumps(">"),
|
|
||||||
"local_preview": f"{path}.preview.{shared.opts.samples_format}",
|
|
||||||
"sort_keys": {'default': index, **self.get_sort_keys(path + ext)},
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
def allowed_directories_for_previews(self):
|
def allowed_directories_for_previews(self):
|
||||||
return [shared.cmd_opts.hypernetwork_dir]
|
return [shared.cmd_opts.hypernetwork_dir]
|
||||||
|
@ -12,20 +12,24 @@ class ExtraNetworksPageTextualInversion(ui_extra_networks.ExtraNetworksPage):
|
|||||||
def refresh(self):
|
def refresh(self):
|
||||||
sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=True)
|
sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings(force_reload=True)
|
||||||
|
|
||||||
def list_items(self):
|
def create_item(self, name, index=None):
|
||||||
for index, embedding in enumerate(sd_hijack.model_hijack.embedding_db.word_embeddings.values()):
|
embedding = sd_hijack.model_hijack.embedding_db.word_embeddings.get(name)
|
||||||
path, ext = os.path.splitext(embedding.filename)
|
|
||||||
yield {
|
|
||||||
"name": embedding.name,
|
|
||||||
"filename": embedding.filename,
|
|
||||||
"preview": self.find_preview(path),
|
|
||||||
"description": self.find_description(path),
|
|
||||||
"search_term": self.search_terms_from_path(embedding.filename),
|
|
||||||
"prompt": json.dumps(embedding.name),
|
|
||||||
"local_preview": f"{path}.preview.{shared.opts.samples_format}",
|
|
||||||
"sort_keys": {'default': index, **self.get_sort_keys(embedding.filename)},
|
|
||||||
|
|
||||||
}
|
path, ext = os.path.splitext(embedding.filename)
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"filename": embedding.filename,
|
||||||
|
"preview": self.find_preview(path),
|
||||||
|
"description": self.find_description(path),
|
||||||
|
"search_term": self.search_terms_from_path(embedding.filename),
|
||||||
|
"prompt": json.dumps(embedding.name),
|
||||||
|
"local_preview": f"{path}.preview.{shared.opts.samples_format}",
|
||||||
|
"sort_keys": {'default': index, **self.get_sort_keys(embedding.filename)},
|
||||||
|
}
|
||||||
|
|
||||||
|
def list_items(self):
|
||||||
|
for index, name in enumerate(sd_hijack.model_hijack.embedding_db.word_embeddings):
|
||||||
|
yield self.create_item(name, index)
|
||||||
|
|
||||||
def allowed_directories_for_previews(self):
|
def allowed_directories_for_previews(self):
|
||||||
return list(sd_hijack.model_hijack.embedding_db.embedding_dirs)
|
return list(sd_hijack.model_hijack.embedding_db.embedding_dirs)
|
||||||
|
@ -23,8 +23,10 @@ class UserMetadataEditor:
|
|||||||
|
|
||||||
self.edit_name = None
|
self.edit_name = None
|
||||||
self.edit_description = None
|
self.edit_description = None
|
||||||
|
self.edit_notes = None
|
||||||
self.html_filedata = None
|
self.html_filedata = None
|
||||||
self.html_preview = None
|
self.html_preview = None
|
||||||
|
self.html_status = None
|
||||||
|
|
||||||
self.button_cancel = None
|
self.button_cancel = None
|
||||||
self.button_replace_preview = None
|
self.button_replace_preview = None
|
||||||
@ -57,6 +59,8 @@ class UserMetadataEditor:
|
|||||||
self.button_replace_preview = gr.Button('Replace preview', variant='primary')
|
self.button_replace_preview = gr.Button('Replace preview', variant='primary')
|
||||||
self.button_save = gr.Button('Save', variant='primary')
|
self.button_save = gr.Button('Save', variant='primary')
|
||||||
|
|
||||||
|
self.html_status = gr.HTML(elem_classes="edit-user-metadata-status")
|
||||||
|
|
||||||
self.button_cancel.click(fn=None, _js="closePopup")
|
self.button_cancel.click(fn=None, _js="closePopup")
|
||||||
|
|
||||||
def get_card_html(self, name):
|
def get_card_html(self, name):
|
||||||
@ -107,7 +111,7 @@ class UserMetadataEditor:
|
|||||||
|
|
||||||
table = '<table class="file-metadata">' + "".join(f"<tr><th>{name}</th><td>{value}</td></tr>" for name, value in params) + '</table>'
|
table = '<table class="file-metadata">' + "".join(f"<tr><th>{name}</th><td>{value}</td></tr>" for name, value in params) + '</table>'
|
||||||
|
|
||||||
return html.escape(name), user_metadata.get('description', ''), table, self.get_card_html(name)
|
return html.escape(name), user_metadata.get('description', ''), table, self.get_card_html(name), user_metadata.get('notes', ''),
|
||||||
|
|
||||||
def write_user_metadata(self, name, metadata):
|
def write_user_metadata(self, name, metadata):
|
||||||
item = self.page.items.get(name, {})
|
item = self.page.items.get(name, {})
|
||||||
@ -117,24 +121,30 @@ class UserMetadataEditor:
|
|||||||
with open(basename + '.json', "w", encoding="utf8") as file:
|
with open(basename + '.json', "w", encoding="utf8") as file:
|
||||||
json.dump(metadata, file)
|
json.dump(metadata, file)
|
||||||
|
|
||||||
def save_user_metadata(self, name, desc):
|
def save_user_metadata(self, name, desc, notes):
|
||||||
user_metadata = self.get_user_metadata(name)
|
user_metadata = self.get_user_metadata(name)
|
||||||
user_metadata["description"] = desc
|
user_metadata["description"] = desc
|
||||||
|
user_metadata["notes"] = notes
|
||||||
|
|
||||||
self.write_user_metadata(name, user_metadata)
|
self.write_user_metadata(name, user_metadata)
|
||||||
|
|
||||||
|
def setup_save_handler(self, button, func, components):
|
||||||
|
button\
|
||||||
|
.click(fn=func, inputs=[self.edit_name_input, *components], outputs=[])\
|
||||||
|
.then(fn=None, _js="function(name){closePopup(); extraNetworksRefreshSingleCard(" + json.dumps(self.page.name) + "," + json.dumps(self.tabname) + ", name);}", inputs=[self.edit_name_input], outputs=[])
|
||||||
|
|
||||||
def create_editor(self):
|
def create_editor(self):
|
||||||
self.create_default_editor_elems()
|
self.create_default_editor_elems()
|
||||||
|
|
||||||
|
self.edit_notes = gr.TextArea(label='Notes', lines=4)
|
||||||
|
|
||||||
self.create_default_buttons()
|
self.create_default_buttons()
|
||||||
|
|
||||||
self.button_edit\
|
self.button_edit\
|
||||||
.click(fn=self.put_values_into_components, inputs=[self.edit_name_input], outputs=[self.edit_name, self.edit_description, self.html_filedata, self.html_preview])\
|
.click(fn=self.put_values_into_components, inputs=[self.edit_name_input], outputs=[self.edit_name, self.edit_description, self.html_filedata, self.html_preview, self.edit_notes])\
|
||||||
.then(fn=lambda: gr.update(visible=True), inputs=[], outputs=[self.box])
|
.then(fn=lambda: gr.update(visible=True), inputs=[], outputs=[self.box])
|
||||||
|
|
||||||
self.button_save\
|
self.setup_save_handler(self.button_save, self.save_user_metadata, [self.edit_description, self.edit_notes])
|
||||||
.click(fn=self.save_user_metadata, inputs=[self.edit_name_input, self.edit_description], outputs=[])\
|
|
||||||
.then(fn=None, _js="extraNetworksReloadAll")
|
|
||||||
|
|
||||||
def create_ui(self):
|
def create_ui(self):
|
||||||
with gr.Box(visible=False, elem_id=self.id_part, elem_classes="edit-user-metadata") as box:
|
with gr.Box(visible=False, elem_id=self.id_part, elem_classes="edit-user-metadata") as box:
|
||||||
@ -147,8 +157,7 @@ class UserMetadataEditor:
|
|||||||
|
|
||||||
def save_preview(self, index, gallery, name):
|
def save_preview(self, index, gallery, name):
|
||||||
if len(gallery) == 0:
|
if len(gallery) == 0:
|
||||||
print("There is no image in gallery to save as a preview.")
|
return self.get_card_html(name), "There is no image in gallery to save as a preview."
|
||||||
return [self.get_card_html(name)] + self.regenerate_ui_pages()
|
|
||||||
|
|
||||||
item = self.page.items.get(name, {})
|
item = self.page.items.get(name, {})
|
||||||
|
|
||||||
@ -162,17 +171,20 @@ class UserMetadataEditor:
|
|||||||
|
|
||||||
images.save_image_with_geninfo(image, geninfo, item["local_preview"])
|
images.save_image_with_geninfo(image, geninfo, item["local_preview"])
|
||||||
|
|
||||||
return [self.get_card_html(name)] + self.regenerate_ui_pages()
|
return self.get_card_html(name), ''
|
||||||
|
|
||||||
def regenerate_ui_pages(self):
|
|
||||||
return [page.create_html(self.tabname) for page in self.ui.stored_extra_pages]
|
|
||||||
|
|
||||||
def setup_ui(self, gallery):
|
def setup_ui(self, gallery):
|
||||||
self.button_replace_preview.click(
|
self.button_replace_preview.click(
|
||||||
fn=self.save_preview,
|
fn=self.save_preview,
|
||||||
_js="function(x, y, z){return [selected_gallery_index(), y, z]}",
|
_js="function(x, y, z){return [selected_gallery_index(), y, z]}",
|
||||||
inputs=[self.edit_name_input, gallery, self.edit_name_input],
|
inputs=[self.edit_name_input, gallery, self.edit_name_input],
|
||||||
outputs=[self.html_preview, *self.ui.pages]
|
outputs=[self.html_preview, self.html_status]
|
||||||
|
).then(
|
||||||
|
fn=None,
|
||||||
|
_js="function(name){extraNetworksRefreshSingleCard(" + json.dumps(self.page.name) + "," + json.dumps(self.tabname) + ", name);}",
|
||||||
|
inputs=[self.edit_name_input],
|
||||||
|
outputs=[]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user