Merge branch 'Add-LyCORIS-parsing' of https://github.com/zixaphir/Stable-Diffusion-Webui-Civitai-Helper into zixaphir-Add-LyCORIS-parsing
* 'Add-LyCORIS-parsing' of https://github.com/zixaphir/Stable-Diffusion-Webui-Civitai-Helper: Hack back in lost Replace Preview functionality. Hack around Lora and Lycoris being treated as the same by webui replace_preview_button is non-functional. Update for basic compatibility with sd-webui-v1.5 Signed-off-by: aleph23 <aleph23@users.noreply.github.com>pull/232/head
commit
079a293c2f
|
|
@ -19,12 +19,12 @@ function ch_gradio_version(){
|
|||
let versions = foot.querySelector(".versions");
|
||||
if (!versions){return null;}
|
||||
|
||||
if (versions.innerHTML.indexOf("gradio: 3.16.2")>0) {
|
||||
if (versions.textContent.indexOf("gradio: 3.16.2")>0) {
|
||||
return "3.16.2";
|
||||
} else {
|
||||
return "3.23.0";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ function ch_gradio_version(){
|
|||
// then will click a button to trigger an action
|
||||
// msg is an object, not a string, will be stringify in this function
|
||||
function send_ch_py_msg(msg){
|
||||
console.log("run send_ch_py_msg")
|
||||
console.log("run send_ch_py_msg");
|
||||
let js_msg_txtbox = gradioApp().querySelector("#ch_js_msg_txtbox textarea");
|
||||
if (js_msg_txtbox && msg) {
|
||||
// fill to msg box
|
||||
|
|
@ -45,15 +45,15 @@ function send_ch_py_msg(msg){
|
|||
// get msg from python side from a hidden textbox
|
||||
// normally this is an old msg, need to wait for a new msg
|
||||
function get_ch_py_msg(){
|
||||
console.log("run get_ch_py_msg")
|
||||
console.log("run get_ch_py_msg");
|
||||
const py_msg_txtbox = gradioApp().querySelector("#ch_py_msg_txtbox textarea");
|
||||
if (py_msg_txtbox && py_msg_txtbox.value) {
|
||||
console.log("find py_msg_txtbox");
|
||||
console.log("py_msg_txtbox value: ");
|
||||
console.log(py_msg_txtbox.value)
|
||||
return py_msg_txtbox.value
|
||||
console.log(py_msg_txtbox.value);
|
||||
return py_msg_txtbox.value;
|
||||
} else {
|
||||
return ""
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ function get_ch_py_msg(){
|
|||
// get msg from python side from a hidden textbox
|
||||
// it will try once in every sencond, until it reach the max try times
|
||||
const get_new_ch_py_msg = (max_count=3) => new Promise((resolve, reject) => {
|
||||
console.log("run get_new_ch_py_msg")
|
||||
console.log("run get_new_ch_py_msg");
|
||||
|
||||
let count = 0;
|
||||
let new_msg = "";
|
||||
|
|
@ -73,11 +73,11 @@ const get_new_ch_py_msg = (max_count=3) => new Promise((resolve, reject) => {
|
|||
if (py_msg_txtbox && py_msg_txtbox.value) {
|
||||
console.log("find py_msg_txtbox");
|
||||
console.log("py_msg_txtbox value: ");
|
||||
console.log(py_msg_txtbox.value)
|
||||
console.log(py_msg_txtbox.value);
|
||||
|
||||
new_msg = py_msg_txtbox.value
|
||||
new_msg = py_msg_txtbox.value;
|
||||
if (new_msg != "") {
|
||||
find_msg=true
|
||||
find_msg = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ const get_new_ch_py_msg = (max_count=3) => new Promise((resolve, reject) => {
|
|||
}
|
||||
|
||||
}, 1000);
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
function getActiveTabType() {
|
||||
|
|
@ -141,10 +141,10 @@ function getActiveNegativePrompt() {
|
|||
async function open_model_url(event, model_type, search_term){
|
||||
console.log("start open_model_url");
|
||||
|
||||
//get hidden components of extension
|
||||
//get hidden components of extension
|
||||
let js_open_url_btn = gradioApp().getElementById("ch_js_open_url_btn");
|
||||
if (!js_open_url_btn) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ async function open_model_url(event, model_type, search_term){
|
|||
"search_term": "",
|
||||
"prompt": "",
|
||||
"neg_prompt": "",
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
msg["action"] = "open_url";
|
||||
|
|
@ -165,14 +165,14 @@ async function open_model_url(event, model_type, search_term){
|
|||
msg["neg_prompt"] = "";
|
||||
|
||||
// fill to msg box
|
||||
send_ch_py_msg(msg)
|
||||
send_ch_py_msg(msg);
|
||||
|
||||
//click hidden button
|
||||
js_open_url_btn.click();
|
||||
|
||||
// stop parent event
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
//check response msg from python
|
||||
let new_py_msg = await get_new_ch_py_msg();
|
||||
|
|
@ -193,7 +193,7 @@ async function open_model_url(event, model_type, search_term){
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
console.log("end open_model_url");
|
||||
|
||||
|
||||
|
|
@ -202,10 +202,10 @@ async function open_model_url(event, model_type, search_term){
|
|||
function add_trigger_words(event, model_type, search_term){
|
||||
console.log("start add_trigger_words");
|
||||
|
||||
//get hidden components of extension
|
||||
//get hidden components of extension
|
||||
let js_add_trigger_words_btn = gradioApp().getElementById("ch_js_add_trigger_words_btn");
|
||||
if (!js_add_trigger_words_btn) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ function add_trigger_words(event, model_type, search_term){
|
|||
"search_term": "",
|
||||
"prompt": "",
|
||||
"neg_prompt": "",
|
||||
}
|
||||
};
|
||||
|
||||
msg["action"] = "add_trigger_words";
|
||||
msg["model_type"] = model_type;
|
||||
|
|
@ -228,26 +228,26 @@ function add_trigger_words(event, model_type, search_term){
|
|||
msg["prompt"] = act_prompt.value;
|
||||
|
||||
// fill to msg box
|
||||
send_ch_py_msg(msg)
|
||||
send_ch_py_msg(msg);
|
||||
|
||||
//click hidden button
|
||||
js_add_trigger_words_btn.click();
|
||||
|
||||
console.log("end add_trigger_words");
|
||||
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function use_preview_prompt(event, model_type, search_term){
|
||||
console.log("start use_preview_prompt");
|
||||
|
||||
//get hidden components of extension
|
||||
//get hidden components of extension
|
||||
let js_use_preview_prompt_btn = gradioApp().getElementById("ch_js_use_preview_prompt_btn");
|
||||
if (!js_use_preview_prompt_btn) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
//msg to python side
|
||||
|
|
@ -257,7 +257,7 @@ function use_preview_prompt(event, model_type, search_term){
|
|||
"search_term": "",
|
||||
"prompt": "",
|
||||
"neg_prompt": "",
|
||||
}
|
||||
};
|
||||
|
||||
msg["action"] = "use_preview_prompt";
|
||||
msg["model_type"] = model_type;
|
||||
|
|
@ -272,15 +272,15 @@ function use_preview_prompt(event, model_type, search_term){
|
|||
msg["neg_prompt"] = neg_prompt.value;
|
||||
|
||||
// fill to msg box
|
||||
send_ch_py_msg(msg)
|
||||
send_ch_py_msg(msg);
|
||||
|
||||
//click hidden button
|
||||
js_use_preview_prompt_btn.click();
|
||||
|
||||
console.log("end use_preview_prompt");
|
||||
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -293,13 +293,13 @@ function ch_dl_model_new_version(event, model_path, version_id, download_url){
|
|||
// must confirm before downloading
|
||||
let dl_confirm = "\nConfirm to download.\n\nCheck Download Model Section's log and console log for detail.";
|
||||
if (!confirm(dl_confirm)) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
//get hidden components of extension
|
||||
//get hidden components of extension
|
||||
let js_dl_model_new_version_btn = gradioApp().getElementById("ch_js_dl_model_new_version_btn");
|
||||
if (!js_dl_model_new_version_btn) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
//msg to python side
|
||||
|
|
@ -308,7 +308,7 @@ function ch_dl_model_new_version(event, model_path, version_id, download_url){
|
|||
"model_path": "",
|
||||
"version_id": "",
|
||||
"download_url": "",
|
||||
}
|
||||
};
|
||||
|
||||
msg["action"] = "dl_model_new_version";
|
||||
msg["model_path"] = model_path;
|
||||
|
|
@ -316,19 +316,61 @@ function ch_dl_model_new_version(event, model_path, version_id, download_url){
|
|||
msg["download_url"] = download_url;
|
||||
|
||||
// fill to msg box
|
||||
send_ch_py_msg(msg)
|
||||
send_ch_py_msg(msg);
|
||||
|
||||
//click hidden button
|
||||
js_dl_model_new_version_btn.click();
|
||||
|
||||
console.log("end dl_model_new_version");
|
||||
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
}
|
||||
|
||||
function waitForEditor(page, type, name) {
|
||||
let id = page + '_' + type + '_edit_user_metadata';
|
||||
|
||||
return new Promise(resolve => {
|
||||
let name_field;
|
||||
let editor = document.getElementById(id);
|
||||
|
||||
let popup = document.querySelector(".global-popup");
|
||||
if (popup != null) {
|
||||
// hide the editor window so it doesn't get in the user's
|
||||
// way while we wait for the replace preview functionality
|
||||
// to become available.
|
||||
popup.style.display = "none";
|
||||
}
|
||||
|
||||
// not only do we need to wait for the editor,
|
||||
// but also for it to populate with the model metadata.
|
||||
if (editor != null) {
|
||||
name_field = editor.querySelector('.extra-network-name');
|
||||
if (name_field.textContent.trim() == name) {
|
||||
return resolve(editor);
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
let editor = document.getElementById(id);
|
||||
let name_field;
|
||||
if (editor != null) {
|
||||
name_field = editor.querySelector('.extra-network-name');
|
||||
if (name_field.textContent.trim() == name) {
|
||||
resolve(editor);
|
||||
observer.disconnect();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
subtree: true,
|
||||
childList: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onUiLoaded(() => {
|
||||
|
||||
|
|
@ -386,7 +428,7 @@ onUiLoaded(() => {
|
|||
if (!replace_preview_text) {
|
||||
replace_preview_text = "replace preview";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// get component
|
||||
|
|
@ -413,12 +455,11 @@ onUiLoaded(() => {
|
|||
let search_term = "";
|
||||
let model_type = "";
|
||||
let cards = null;
|
||||
let need_to_add_buttons = false;
|
||||
let is_thumb_mode = false;
|
||||
|
||||
//get current tab
|
||||
let active_tab_type = getActiveTabType();
|
||||
if (!active_tab_type){active_tab_type = "txt2img";}
|
||||
if (!active_tab_type) {active_tab_type = "txt2img";}
|
||||
|
||||
for (const tab_prefix of tab_prefix_list) {
|
||||
if (tab_prefix != active_tab_type) {continue;}
|
||||
|
|
@ -432,9 +473,9 @@ onUiLoaded(() => {
|
|||
//get active extratab
|
||||
const active_extra_tab = Array.from(get_uiCurrentTabContent().querySelectorAll('.extra-network-cards,.extra-network-thumbs'))
|
||||
.find(el => el.closest('.tabitem').style.display === 'block')
|
||||
?.id.match(/^(txt2img|img2img)_(.+)_cards$/)[2]
|
||||
?.id.match(/^(txt2img|img2img)_(.+)_cards$/)[2];
|
||||
|
||||
|
||||
|
||||
console.log("found active tab: " + active_extra_tab);
|
||||
|
||||
switch (active_extra_tab) {
|
||||
|
|
@ -493,8 +534,10 @@ onUiLoaded(() => {
|
|||
extra_network_id = tab_prefix+"_"+js_model_type+"_"+cardid_suffix;
|
||||
// console.log("searching extra_network_node: " + extra_network_id);
|
||||
extra_network_node = gradioApp().getElementById(extra_network_id);
|
||||
|
||||
// check if extr network is under thumbnail mode
|
||||
is_thumb_mode = false
|
||||
// XXX thumbnail mode removed in sd-webui v1.5.0
|
||||
is_thumb_mode = false;
|
||||
if (extra_network_node) {
|
||||
if (extra_network_node.className == "extra-network-thumbs") {
|
||||
console.log(extra_network_id + " is in thumbnail mode");
|
||||
|
|
@ -517,59 +560,94 @@ onUiLoaded(() => {
|
|||
//get ul node, which is the parent of all buttons
|
||||
ul_node = card.querySelector(".actions .additional ul");
|
||||
if (ul_node==null) {
|
||||
ul_node = document.createElement("ul");
|
||||
ul_node = document.createElement("ul");
|
||||
additional_node.appendChild(ul_node);
|
||||
}
|
||||
// replace preview text button
|
||||
replace_preview_btn = card.querySelector(".actions .additional a");
|
||||
if (replace_preview_btn==null) {
|
||||
replace_preview_btn = document.createElement("a");
|
||||
replace_preview_btn = document.createElement("a");
|
||||
additional_node.appendChild(replace_preview_btn);
|
||||
}
|
||||
if (replace_preview_btn == null) {
|
||||
/*
|
||||
* in sdwebui 1.5, the replace preview button has been
|
||||
* moved to a hard to reach location, so we have to do
|
||||
* quite a lot to get to its functionality.
|
||||
*/
|
||||
|
||||
// waste memory by keeping all of this in scope, per card.
|
||||
let page = active_tab_type;
|
||||
let type = js_model_type;
|
||||
let name = card.dataset.name;
|
||||
|
||||
// create the replace_preview_btn, as it no longer exists
|
||||
replace_preview_btn = document.createElement("a");
|
||||
|
||||
// create an event handler to redirect a click to the real replace_preview_button
|
||||
replace_preview_btn.addEventListener("click", function(e) {
|
||||
// we have to create a whole hidden editor window to access preview replace functionality
|
||||
extraNetworksEditUserMetadata(e, page, type, name);
|
||||
|
||||
// the editor window takes quite some time to populate. What a waste.
|
||||
waitForEditor(page, type, name).then(editor => {
|
||||
// Gather the buttons we need to both replace the preview and close the editor
|
||||
let cancel_button = editor.querySelector('.edit-user-metadata-buttons button:first-of-type');
|
||||
let replace_preview_button = editor.querySelector('.edit-user-metadata-buttons button:nth-of-type(2)');
|
||||
|
||||
replace_preview_button.click();
|
||||
cancel_button.click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// check thumb mode
|
||||
if (is_thumb_mode) {
|
||||
additional_node.style.display = null;
|
||||
|
||||
if (!ul_node) {
|
||||
// nothing to do.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch_show_btn_on_thumb) {
|
||||
ul_node.style.background = btn_thumb_background;
|
||||
} else {
|
||||
//reset
|
||||
ul_node.style.background = null;
|
||||
// console.log("remove existed buttons");
|
||||
// remove existed buttons
|
||||
if (ul_node) {
|
||||
// find all .a child nodes
|
||||
let atags = ul_node.querySelectorAll("a");
|
||||
|
||||
for (let atag of atags) {
|
||||
//reset display
|
||||
//reset
|
||||
ul_node.style.background = null;
|
||||
// find all .a child nodes
|
||||
let atags = ul_node.querySelectorAll("a");
|
||||
|
||||
for (let atag of atags) {
|
||||
//reset display
|
||||
atag.style.display = null;
|
||||
//remove extension's button
|
||||
if (ch_btn_txts.indexOf(atag.textContent)>=0) {
|
||||
//need to remove
|
||||
ul_node.removeChild(atag);
|
||||
} else {
|
||||
//do not remove, just reset
|
||||
atag.textContent = replace_preview_text;
|
||||
atag.style.display = null;
|
||||
//remove extension's button
|
||||
if (ch_btn_txts.indexOf(atag.innerHTML)>=0) {
|
||||
//need to remove
|
||||
ul_node.removeChild(atag);
|
||||
} else {
|
||||
//do not remove, just reset
|
||||
atag.innerHTML = replace_preview_text;
|
||||
atag.style.display = null;
|
||||
atag.style.fontSize = null;
|
||||
atag.style.position = null;
|
||||
atag.style.backgroundImage = null;
|
||||
}
|
||||
atag.style.fontSize = null;
|
||||
atag.style.position = null;
|
||||
atag.style.backgroundImage = null;
|
||||
}
|
||||
|
||||
//also remove br tag in ul
|
||||
let brtag = ul_node.querySelector("br");
|
||||
if (brtag) {
|
||||
ul_node.removeChild(brtag);
|
||||
}
|
||||
|
||||
}
|
||||
//just reset and remove nodes, do nothing else
|
||||
continue;
|
||||
|
||||
//also remove br tag in ul
|
||||
let brtag = ul_node.querySelector("br");
|
||||
if (brtag) {
|
||||
ul_node.removeChild(brtag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//just reset and remove nodes, do nothing else
|
||||
continue;
|
||||
|
||||
} else {
|
||||
// full preview mode
|
||||
if (ch_always_display) {
|
||||
|
|
@ -578,19 +656,24 @@ onUiLoaded(() => {
|
|||
additional_node.style.display = null;
|
||||
}
|
||||
|
||||
// remove br tag
|
||||
let brtag = ul_node.querySelector("br");
|
||||
if (brtag) {
|
||||
ul_node.removeChild(brtag);
|
||||
|
||||
if (!ul_node) {
|
||||
ul_node = document.createElement("ul");
|
||||
} else {
|
||||
// remove br tag
|
||||
let brtag = ul_node.querySelector("br");
|
||||
if (brtag) {
|
||||
ul_node.removeChild(brtag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// change replace preview text button into icon
|
||||
if (replace_preview_btn) {
|
||||
if (replace_preview_btn.innerHTML !== "🖼️") {
|
||||
need_to_add_buttons = true;
|
||||
replace_preview_btn.innerHTML = "🖼️";
|
||||
// change replace preview text button into icon
|
||||
if (replace_preview_btn.textContent !== "🖼️") {
|
||||
ul_node.appendChild(replace_preview_btn);
|
||||
replace_preview_btn.textContent = "🖼️";
|
||||
if (!is_thumb_mode) {
|
||||
replace_preview_btn.style.fontSize = btn_fontSize;
|
||||
replace_preview_btn.style.margin = btn_margin;
|
||||
|
|
@ -604,11 +687,10 @@ onUiLoaded(() => {
|
|||
}
|
||||
}
|
||||
|
||||
if (!need_to_add_buttons) {
|
||||
if (ul_node.querySelector('.openurl')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// search_term node
|
||||
// search_term = subfolder path + model name + ext
|
||||
search_term_node = card.querySelector(".actions .additional .search_term");
|
||||
|
|
@ -618,14 +700,12 @@ onUiLoaded(() => {
|
|||
}
|
||||
|
||||
// get search_term
|
||||
search_term = search_term_node.innerHTML;
|
||||
search_term = search_term_node.textContent;
|
||||
if (!search_term) {
|
||||
console.log("search_term is empty for cards in " + extra_network_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if (is_thumb_mode) {
|
||||
// ul_node.style.background = btn_thumb_background;
|
||||
// }
|
||||
|
|
@ -633,7 +713,8 @@ onUiLoaded(() => {
|
|||
// then we need to add 3 buttons to each ul node:
|
||||
let open_url_node = document.createElement("a");
|
||||
open_url_node.href = "#";
|
||||
open_url_node.innerHTML = "🌐";
|
||||
open_url_node.textContent = "🌐";
|
||||
open_url_node.className = "openurl";
|
||||
if (!is_thumb_mode) {
|
||||
open_url_node.style.fontSize = btn_fontSize;
|
||||
open_url_node.style.margin = btn_margin;
|
||||
|
|
@ -648,7 +729,8 @@ onUiLoaded(() => {
|
|||
|
||||
let add_trigger_words_node = document.createElement("a");
|
||||
add_trigger_words_node.href = "#";
|
||||
add_trigger_words_node.innerHTML = "💡";
|
||||
add_trigger_words_node.textContent = "💡";
|
||||
add_trigger_words_node.className = "addtriggerwords";
|
||||
if (!is_thumb_mode) {
|
||||
add_trigger_words_node.style.fontSize = btn_fontSize;
|
||||
add_trigger_words_node.style.margin = btn_margin;
|
||||
|
|
@ -664,7 +746,8 @@ onUiLoaded(() => {
|
|||
|
||||
let use_preview_prompt_node = document.createElement("a");
|
||||
use_preview_prompt_node.href = "#";
|
||||
use_preview_prompt_node.innerHTML = "🏷️";
|
||||
use_preview_prompt_node.textContent = "🏷️";
|
||||
use_preview_prompt_node.className = "usepreviewprompt";
|
||||
if (!is_thumb_mode) {
|
||||
use_preview_prompt_node.style.fontSize = btn_fontSize;
|
||||
use_preview_prompt_node.style.margin = btn_margin;
|
||||
|
|
@ -686,12 +769,13 @@ onUiLoaded(() => {
|
|||
ul_node.appendChild(add_trigger_words_node);
|
||||
ul_node.appendChild(use_preview_prompt_node);
|
||||
|
||||
|
||||
|
||||
if (!ul_node.parentElement) {
|
||||
additional_node.appendChild(ul_node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -699,7 +783,7 @@ onUiLoaded(() => {
|
|||
}
|
||||
|
||||
|
||||
let tab_id = ""
|
||||
let tab_id = "";
|
||||
let extra_tab = null;
|
||||
let extra_toolbar = null;
|
||||
let extra_network_refresh_btn = null;
|
||||
|
|
@ -720,7 +804,7 @@ onUiLoaded(() => {
|
|||
|
||||
// add refresh button to toolbar
|
||||
let ch_refresh = document.createElement("button");
|
||||
ch_refresh.innerHTML = "🔁";
|
||||
ch_refresh.textContent = "🔁";
|
||||
ch_refresh.title = "Refresh Civitai Helper's additional buttons";
|
||||
ch_refresh.className = "lg secondary gradio-button";
|
||||
ch_refresh.style.fontSize = "200%";
|
||||
|
|
|
|||
|
|
@ -160,31 +160,31 @@ def get_version_info_by_model_id(id:str) -> dict:
|
|||
if not model_info:
|
||||
util.printD(f"Failed to get model info by id: {id}")
|
||||
return
|
||||
|
||||
|
||||
# check content to get version id
|
||||
if "modelVersions" not in model_info.keys():
|
||||
util.printD("There is no modelVersions in this model_info")
|
||||
return
|
||||
|
||||
|
||||
if not model_info["modelVersions"]:
|
||||
util.printD("modelVersions is None")
|
||||
return
|
||||
|
||||
|
||||
if len(model_info["modelVersions"])==0:
|
||||
util.printD("modelVersions is Empty")
|
||||
return
|
||||
|
||||
|
||||
def_version = model_info["modelVersions"][0]
|
||||
if not def_version:
|
||||
util.printD("default version is None")
|
||||
return
|
||||
|
||||
|
||||
if "id" not in def_version.keys():
|
||||
util.printD("default version has no id")
|
||||
return
|
||||
|
||||
|
||||
version_id = def_version["id"]
|
||||
|
||||
|
||||
if not version_id:
|
||||
util.printD("default version's id is None")
|
||||
return
|
||||
|
|
@ -215,11 +215,22 @@ def load_model_info_by_search_term(model_type, search_term):
|
|||
if base[:1] == "/":
|
||||
model_info_base = base[1:]
|
||||
|
||||
model_folder = model.folders[model_type]
|
||||
model_info_filename = model_info_base + suffix + model.info_ext
|
||||
model_info_filepath = os.path.join(model_folder, model_info_filename)
|
||||
if model_type == "lora" and model.folders['lycoris']:
|
||||
model_folders = [model.folders[model_type], model.folders['lycoris']]
|
||||
else:
|
||||
model_folders = [model.folders[model_type]]
|
||||
|
||||
if not os.path.isfile(model_info_filepath):
|
||||
#model_folder = model.folders[model_type]
|
||||
for model_folder in model_folders:
|
||||
model_info_filename = model_info_base + suffix + model.info_ext
|
||||
model_info_filepath = os.path.join(model_folder, model_info_filename)
|
||||
|
||||
found = os.path.isfile(model_info_filepath)
|
||||
|
||||
if found:
|
||||
break;
|
||||
|
||||
if not found:
|
||||
util.printD(f"Can not find model info file: {model_info_filepath}")
|
||||
return
|
||||
|
||||
|
|
@ -234,8 +245,11 @@ def load_model_info_by_search_term(model_type, search_term):
|
|||
# parameter: filter - dict, which kind of model you need
|
||||
# return: model name list
|
||||
def get_model_names_by_type_and_filter(model_type:str, filter:dict) -> list:
|
||||
|
||||
model_folder = model.folders[model_type]
|
||||
|
||||
if model_type == "lora" and model.folders['lycoris']:
|
||||
model_folders = [model.folders[model_type], model.folders['lycoris']]
|
||||
else:
|
||||
model_folders = [model.folders[model_type]]
|
||||
|
||||
# set filter
|
||||
# only get models don't have a civitai info file
|
||||
|
|
@ -253,20 +267,21 @@ def get_model_names_by_type_and_filter(model_type:str, filter:dict) -> list:
|
|||
# get information from filter
|
||||
# only get those model names don't have a civitai model info file
|
||||
model_names = []
|
||||
for root, dirs, files in os.walk(model_folder, followlinks=True):
|
||||
for filename in files:
|
||||
item = os.path.join(root, filename)
|
||||
# check extension
|
||||
base, ext = os.path.splitext(item)
|
||||
if ext in model.exts:
|
||||
# find a model
|
||||
for model_folder in model_folders:
|
||||
for root, dirs, files in os.walk(model_folder, followlinks=True):
|
||||
for filename in files:
|
||||
item = os.path.join(root, filename)
|
||||
# check extension
|
||||
base, ext = os.path.splitext(item)
|
||||
if ext in model.exts:
|
||||
# find a model
|
||||
|
||||
# check filter
|
||||
if no_info_only:
|
||||
# check model info file
|
||||
info_file = base + suffix + model.info_ext
|
||||
if os.path.isfile(info_file):
|
||||
continue
|
||||
# check filter
|
||||
if no_info_only:
|
||||
# check model info file
|
||||
info_file = base + suffix + model.info_ext
|
||||
if os.path.isfile(info_file):
|
||||
continue
|
||||
|
||||
if empty_info_only:
|
||||
# check model info file
|
||||
|
|
@ -277,14 +292,13 @@ def get_model_names_by_type_and_filter(model_type:str, filter:dict) -> list:
|
|||
# find a non-empty model info file
|
||||
continue
|
||||
|
||||
model_names.append(filename)
|
||||
|
||||
model_names.append(filename)
|
||||
|
||||
return model_names
|
||||
|
||||
def get_model_names_by_input(model_type, empty_info_only):
|
||||
return get_model_names_by_type_and_filter(model_type, {"empty_info_only":empty_info_only})
|
||||
|
||||
|
||||
|
||||
# get id from url
|
||||
def get_model_id_from_url(url:str) -> str:
|
||||
|
|
@ -458,7 +472,7 @@ def check_model_new_version_by_path(model_path:str, delay:float=1) -> tuple:
|
|||
|
||||
# get model info by id from civitai
|
||||
model_info = get_model_info_by_id(model_id)
|
||||
# delay before next request, to prevent to be treat as DDoS
|
||||
# delay before next request, to prevent to be treat as DDoS
|
||||
util.printD(f"delay:{delay} second")
|
||||
time.sleep(delay)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from modules import shared
|
|||
# this is the default root path
|
||||
root_path = os.getcwd()
|
||||
|
||||
# if command line arguement is used to change model folder,
|
||||
# if command line arguement is used to change model folder,
|
||||
# then model folder is in absolute path, not based on this root path anymore.
|
||||
# so to make extension work with those absolute model folder paths, model folder also need to be in absolute path
|
||||
folders = {
|
||||
|
|
@ -43,8 +43,19 @@ def get_custom_model_folder():
|
|||
if shared.cmd_opts.lora_dir and os.path.isdir(shared.cmd_opts.lora_dir):
|
||||
folders["lora"] = shared.cmd_opts.lora_dir
|
||||
|
||||
if shared.cmd_opts.lyco_dir and os.path.isdir(shared.cmd_opts.lyco_dir):
|
||||
folders["lycoris"] = shared.cmd_opts.lyco_dir
|
||||
try:
|
||||
# pre-1.5.0
|
||||
if shared.cmd_opts.lyco_dir and os.path.isdir(shared.cmd_opts.lyco_dir):
|
||||
folders["lycoris"] = shared.cmd_opts.lyco_dir
|
||||
|
||||
except:
|
||||
try:
|
||||
# sd-webui v1.5.1 added a backcompat option for lyco.
|
||||
if shared.cmd_opts.lyco_dir_backcompat and os.path.isdir(shared.cmd_opts.lyco_dir_backcompat):
|
||||
folders["lycoris"] = shared.cmd_opts.lyco_dir_backcompat
|
||||
except:
|
||||
# XXX v1.5.0 has no options for the Lyco dir: it is hardcoded as 'os.path.join(paths.models_path, "LyCORIS")'
|
||||
pass
|
||||
|
||||
|
||||
# write model info to file
|
||||
|
|
@ -72,20 +83,24 @@ def load_model_info(path):
|
|||
# parameter: model_type - string
|
||||
# return: model name list
|
||||
def get_model_names_by_type(model_type:str) -> list:
|
||||
|
||||
model_folder = folders[model_type]
|
||||
|
||||
if model_type == "lora" and folders['lycoris']:
|
||||
model_folders = [folders[model_type], folders['lycoris']]
|
||||
else:
|
||||
model_folders = [folders[model_type]]
|
||||
|
||||
# get information from filter
|
||||
# only get those model names don't have a civitai model info file
|
||||
model_names = []
|
||||
for root, dirs, files in os.walk(model_folder, followlinks=True):
|
||||
for filename in files:
|
||||
item = os.path.join(root, filename)
|
||||
# check extension
|
||||
base, ext = os.path.splitext(item)
|
||||
if ext in exts:
|
||||
# find a model
|
||||
model_names.append(filename)
|
||||
for model_folder in model_folders:
|
||||
for root, dirs, files in os.walk(model_folder, followlinks=True):
|
||||
for filename in files:
|
||||
item = os.path.join(root, filename)
|
||||
# check extension
|
||||
base, ext = os.path.splitext(item)
|
||||
if ext in exts:
|
||||
# find a model
|
||||
model_names.append(filename)
|
||||
|
||||
|
||||
return model_names
|
||||
|
|
@ -102,18 +117,23 @@ def get_model_path_by_type_and_name(model_type:str, model_name:str) -> str:
|
|||
util.printD("model name can not be empty")
|
||||
return
|
||||
|
||||
folder = folders[model_type]
|
||||
if model_type == "lora" and folders['lycoris']:
|
||||
model_folders = [folders[model_type], folders['lycoris']]
|
||||
else:
|
||||
model_folders = [folders[model_type]]
|
||||
|
||||
|
||||
# model could be in subfolder, need to walk.
|
||||
model_root = ""
|
||||
model_path = ""
|
||||
for root, dirs, files in os.walk(folder, followlinks=True):
|
||||
for filename in files:
|
||||
if filename == model_name:
|
||||
# find model
|
||||
model_root = root
|
||||
model_path = os.path.join(root, filename)
|
||||
return (model_root, model_path)
|
||||
for folder in model_folders:
|
||||
for root, dirs, files in os.walk(folder, followlinks=True):
|
||||
for filename in files:
|
||||
if filename == model_name:
|
||||
# find model
|
||||
model_root = root
|
||||
model_path = os.path.join(root, filename)
|
||||
return (model_root, model_path)
|
||||
|
||||
return
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue