fix gallery, update js logging, add en caching

This commit is contained in:
Vladimir Mandic
2023-08-29 14:16:37 -04:00
parent 4bfa2ee877
commit 9e2e2b8b8f
25 changed files with 125 additions and 101 deletions
+6 -1
View File
@@ -32,12 +32,15 @@
"no-useless-escape":"off",
"object-curly-newline":"off",
"prefer-rest-params":"off",
"prefer-destructuring":"off",
"radix":"off"
},
"globals": {
// asssets
"panzoom": "readonly",
//script.js
"log": "readonly",
"debug": "readonly",
"gradioApp": "readonly",
"executeCallbacks": "readonly",
"onAfterUiUpdate": "readonly",
@@ -65,7 +68,9 @@
"create_submit_args": "readonly",
"restart_reload": "readonly",
"updateInput": "readonly",
//extraNetworks.js
// settings.js
"register_drag_drop": "readonly",
//extraNetworks.js
"requestGet": "readonly",
"popup": "readonly",
// from python
+5 -2
View File
@@ -1,10 +1,9 @@
# Change Log for SD.Next
## Update for 2023-08-26
## Update for 2023-08-29
- general:
- all system and image paths are now relative by default
- fix extra networks previews
- add settings validation when performing load/save
- settings tab in ui now shows settings that are changed from default values
- settings tab switch to compact view
@@ -20,6 +19,10 @@
enable with `--use-openvino`
thanks @disty0
- add model **precompile** option (when model compile is enbled)
- **extra network** folder info caching
results in much faster startup when you have large number of extra networks
- fix extra networks previews
- fix gradio gallery
## Update for 2023-08-20
-1
View File
@@ -119,7 +119,6 @@ Below is partial list of all available parameters, run `webui --help` for the fu
SD.Next comes with several extensions pre-installed:
- [Dynamic Thresholding](https://github.com/mcmonkeyprojects/sd-dynamic-thresholding)
- [ControlNet](https://github.com/Mikubill/sd-webui-controlnet)
- [Agent Scheduler](https://github.com/ArtVentureX/sd-webui-agent-scheduler)
- [Multi-Diffusion Tiled Diffusion and VAE](https://github.com/pkuliyi2015/multidiffusion-upscaler-for-automatic1111)
-1
View File
@@ -103,7 +103,6 @@ svg.feather.feather-image, .feather .feather-image { display: none }
#txt2img_cfg_scale { min-width: 200px; }
#txt2img_checkboxes, #img2img_checkboxes { background-color: transparent; }
#txt2img_checkboxes, #img2img_checkboxes { margin-bottom: 0.2em; }
#txt2img_gallery, #img2img_gallery, #extras_gallery { padding: 0; margin: 0; object-fit: contain; box-shadow: none; min-height: 0; }
#txt2img_actions_column, #img2img_actions_column { flex-flow: wrap; justify-content: space-between; }
#txt2img_enqueue_wrapper, #img2img_enqueue_wrapper { min-width: unset; width: 48%; }
#txt2img_generate_box, #img2img_generate_box { min-width: unset; width: 48%; }
+2 -2
View File
@@ -62,9 +62,9 @@ const contextMenuInit = () => {
});
}
function addContextMenuEventListener() {
async function addContextMenuEventListener() {
if (eventListenerApplied) return;
console.log('initContextMenu');
log('initContextMenu');
gradioApp().addEventListener('click', (e) => {
if (!e.isTrusted) return;
const oldMenu = gradioApp().querySelector('#context-menu');
+5 -5
View File
@@ -6,7 +6,7 @@ function extensions_apply(extensions_disabled_list, extensions_update_list, disa
if (x.name.startsWith('update_') && x.checked) update.push(x.name.substring(7));
});
restart_reload();
console.log('Extensions apply:', { disable, update });
log('Extensions apply:', { disable, update });
return [JSON.stringify(disable), JSON.stringify(update), disable_all];
}
@@ -16,7 +16,7 @@ function extensions_check(info, extensions_disabled_list, search_text, sort_colu
if (x.name.startsWith('enable_') && !x.checked) disable.push(x.name.substring(7));
});
const id = randomId();
console.log('Extensions check:', { disable });
log('Extensions check:', { disable });
return [id, JSON.stringify(disable), search_text, sort_column];
}
@@ -27,7 +27,7 @@ function install_extension(button, url) {
const textarea = gradioApp().querySelector('#extension_to_install textarea');
textarea.value = url;
updateInput(textarea);
console.log('Extension install:', { url });
log('Extension install:', { url });
gradioApp().querySelector('#install_extension_button').click();
}
@@ -38,7 +38,7 @@ function uninstall_extension(button, url) {
const textarea = gradioApp().querySelector('#extension_to_install textarea');
textarea.value = url;
updateInput(textarea);
console.log('Extension uninstall:', { url });
log('Extension uninstall:', { url });
gradioApp().querySelector('#uninstall_extension_button').click();
}
@@ -48,6 +48,6 @@ function update_extension(button, url) {
const textarea = gradioApp().querySelector('#extension_to_install textarea');
textarea.value = url;
updateInput(textarea);
console.log('Extension update:', { url });
log('Extension update:', { url });
gradioApp().querySelector('#update_extension_button').click();
}
+2 -2
View File
@@ -4,7 +4,7 @@ function attachGalleryListeners(tab_name) {
const gallery = gradioApp().querySelector(`#${tab_name}_gallery`);
if (!gallery) return null;
gallery.addEventListener('click', () => setTimeout(() => {
console.log('galleryItemSelected:', tab_name);
log('galleryItemSelected:', tab_name);
gradioApp().getElementById(`${tab_name}_generation_info_button`)?.click();
}, 500));
gallery?.addEventListener('keydown', (e) => {
@@ -36,7 +36,7 @@ function initiGenerationParams() {
if (txt2img_gallery && img2img_gallery) generationParamsInitialized = true;
else return;
modalObserver.observe(modal, { attributes: true, attributeFilter: ['style'] });
console.log('initGenerationParams');
log('initGenerationParams');
}
onAfterUiUpdate(initiGenerationParams);
+2 -2
View File
@@ -3,7 +3,7 @@ let dragDropInitialized = false;
async function initDragDrop() {
if (dragDropInitialized) return;
dragDropInitialized = true;
console.log('initDragDrop');
log('initDragDrop');
window.addEventListener('drop', (e) => {
const target = e.composedPath()[0];
if (!target.placeholder) return;
@@ -18,7 +18,7 @@ async function initDragDrop() {
if (fileInput) {
fileInput.files = files;
fileInput.dispatchEvent(new Event('change'));
console.log('dropEvent');
log('dropEvent');
}
});
}
+2 -2
View File
@@ -134,7 +134,7 @@ function galleryClickEventHandler(event) {
}
}
function initImageViewer() {
async function initImageViewer() {
// Each tab has its own gradio-gallery
const galleryPreviews = gradioApp().querySelectorAll('.gradio-gallery > div.preview');
if (galleryPreviews.length > 0) {
@@ -241,7 +241,7 @@ function initImageViewer() {
modalControls.appendChild(modalClose);
gradioApp().appendChild(modal);
console.log('initImageViewer');
log('initImageViewer');
}
onAfterUiUpdate(initImageViewer);
+5 -3
View File
@@ -1,3 +1,5 @@
const appStartTime = performance.now();
async function preloadImages() {
const dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
const imagePromises = [];
@@ -24,7 +26,7 @@ async function preloadImages() {
async function createSplash() {
const dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
console.log('createSplash', { theme: dark ? 'dark' : 'light' });
log('createSplash', { theme: dark ? 'dark' : 'light' });
const num = Math.floor(11 * Math.random());
const splash = `
<div id="splash" class="splash" style="background: ${dark ? 'black' : 'white'}">
@@ -38,8 +40,8 @@ async function createSplash() {
async function removeSplash() {
const splash = document.getElementById('splash');
if (splash) splash.remove();
console.log('removeSplash');
console.log('startupTime', Math.round(performance.now() - appStartTime) / 1000);
log('removeSplash');
log('startupTime', Math.round(performance.now() - appStartTime) / 1000);
}
window.onload = createSplash;
+1 -1
View File
@@ -52,7 +52,7 @@ async function initLogMonitor() {
`;
el.style.display = 'none';
logMonitor();
console.log('initLogMonitor');
log('initLogMonitor');
}
onAfterUiUpdate(initLogMonitor);
+1 -1
View File
@@ -26,7 +26,7 @@ function initNotifications() {
parent.focus();
this.close();
};
console.log('sendNotification');
log('sendNotification');
}
onAfterUiUpdate(initNotifications);
+1 -1
View File
@@ -1017,7 +1017,7 @@ function autoRun() {
return;
}
var options = collectOptions(panzoomScript);
console.log(options);
log(options);
window[globalName] = createPanZoom(el, options);
}
+1 -1
View File
@@ -103,7 +103,7 @@ function requestProgress(id_task, progressEl, galleryEl, atEnd = null, onProgres
};
const done = () => {
console.debug('taskEnd:', id_task);
debug('taskEnd:', id_task);
localStorage.removeItem('task');
setProgress();
if (parentGallery && livePreview) parentGallery.removeChild(livePreview);
+11 -1
View File
@@ -1,4 +1,14 @@
const appStartTime = performance.now();
const log = (...msg) => {
const dt = new Date();
const ts = `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}.${dt.getMilliseconds().toString().padStart(3, '0')}`;
console.log(ts, ...msg); // eslint-disable-line no-console
};
const debug = (...msg) => {
const dt = new Date();
const ts = `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}.${dt.getMilliseconds().toString().padStart(3, '0')}`;
console.debug(ts, ...msg); // eslint-disable-line no-console
};
function gradioApp() {
const elems = document.getElementsByTagName('gradio-app');
+5 -5
View File
@@ -31,19 +31,19 @@ async function tooltipHide(e) {
async function validateHints(elements, data) {
let original = elements.map((e) => e.textContent.toLowerCase().trim()).sort((a, b) => a > b);
original = [...new Set(original)];
console.log('all hints:', original);
console.log('hints-differences', { elements: original.length, hints: data.length });
log('all hints:', original);
log('hints-differences', { elements: original.length, hints: data.length });
const current = data.map((e) => e.label.toLowerCase().trim()).sort((a, b) => a > b);
let missing = [];
for (let i = 0; i < original.length; i++) {
if (!current.includes(original[i])) missing.push(original[i]);
}
console.log('missing in locale:', missing);
log('missing in locale:', missing);
missing = [];
for (let i = 0; i < current.length; i++) {
if (!original.includes(current[i])) missing.push(current[i]);
}
console.log('in locale but not ui:', missing);
log('in locale but not ui:', missing);
}
async function setHints() {
@@ -84,7 +84,7 @@ async function setHints() {
}
}
const t1 = performance.now();
console.log('setHints', { type: localeData.type, elements: elements.length, localized, hints, data: localeData.data.length, time: t1 - t0 });
log('setHints', { type: localeData.type, elements: elements.length, localized, hints, data: localeData.data.length, time: t1 - t0 });
removeSplash();
// validateHints(elements, localeData.data)
}
+16 -20
View File
@@ -1,10 +1,9 @@
let opts_metadata = {};
const opts_tabs = {};
const monitoredOpts = [
{ sd_model_checkpoint: null },
{
sd_backend: () => {
gradioApp().getElementById('refresh_sd_model_checkpoint')?.click();
},
},
{ sd_backend: () => gradioApp().getElementById('refresh_sd_model_checkpoint')?.click() },
];
function updateOpts(json_string) {
@@ -13,7 +12,7 @@ function updateOpts(json_string) {
const key = Object.keys(op)[0];
const callback = op[key];
if (opts[key] && opts[key] !== settings_data.values[key]) {
console.log('updateOpts', key, opts[key], settings_data.values[key]);
log('updateOpts', key, opts[key], settings_data.values[key]);
if (callback) callback();
}
}
@@ -31,9 +30,7 @@ function updateOpts(json_string) {
function showAllSettings() {
// Try to ensure that the show all settings tab is opened by clicking on its tab button
const tab_dirty_indicator = gradioApp().getElementById('modification_indicator_show_all_pages');
if (tab_dirty_indicator && tab_dirty_indicator.nextSibling) {
tab_dirty_indicator.nextSibling.click();
}
if (tab_dirty_indicator && tab_dirty_indicator.nextSibling) tab_dirty_indicator.nextSibling.click();
gradioApp().querySelectorAll('#settings > .tab-content > .tabitem').forEach((elem) => {
if (elem.id === 'settings_tab_licenses' || elem.id === 'settings_show_all_pages') return;
elem.style.display = 'block';
@@ -42,17 +39,16 @@ function showAllSettings() {
function markIfModified(setting_name, value) {
const elem = gradioApp().getElementById(`modification_indicator_${setting_name}`);
if (elem == null) return;
// Use JSON.stringify to compare nested objects (e.g. arrays for checkbox-groups)
const previous_value_json = JSON.stringify(opts[setting_name]);
const changed_value = JSON.stringify(value) !== previous_value_json;
if (changed_value) elem.title = `click to revert to previous value: ${previous_value_json}`;
const is_unsaved = opts_metadata[setting_name].is_stored;
if (is_unsaved) elem.title = 'custom value';
elem.disabled = !(is_unsaved || changed_value);
if (!elem) return;
const previous_value = JSON.stringify(opts[setting_name]);
const current_value = JSON.stringify(value);
const changed_value = previous_value !== current_value;
if (changed_value) elem.title = `click to revert to previous value: ${previous_value}`;
const is_stored = opts_metadata[setting_name].is_stored;
if (is_stored) elem.title = 'custom value';
elem.disabled = !changed_value && !is_stored;
elem.classList.toggle('changed', changed_value);
elem.classList.toggle('unsaved', is_unsaved);
elem.classList.toggle('saved', is_stored);
const { tab_name } = opts_metadata[setting_name];
if (!opts_tabs[tab_name].changed) opts_tabs[tab_name].changed = new Set();
@@ -67,7 +63,7 @@ function markIfModified(setting_name, value) {
tab_nav_indicator.disabled = (changed_items.size === 0) && (unsaved.size === 0);
tab_nav_indicator.title = '';
tab_nav_indicator.classList.toggle('changed', changed_items.size > 0);
tab_nav_indicator.classList.toggle('unsaved', saved.size > 0);
tab_nav_indicator.classList.toggle('saved', saved.size > 0);
if (changed_items.size > 0) tab_nav_indicator.title += `click to reset ${changed_items.size} unapplied changes in this tab\n`;
if (saved.size > 0) tab_nav_indicator.title += `${saved.size} custom values\n${unsaved.size} default values}`;
}
+1 -3
View File
@@ -67,8 +67,6 @@ button.custom-button{
.performance { font-size: 0.85em; color: #444; }
.performance p { display: inline-block; color: var(--body-text-color-subdued) !important }
.performance .time { margin-right: 0; }
@media screen and (min-width: 2500px) { #txt2img_gallery, #img2img_gallery { min-height: 768px; } }
#txt2img_gallery img, #img2img_gallery img, #extras_gallery img { object-fit: scale-down; width: -webkit-fill-available !important; }
#txt2img_footer, #img2img_footer, #extras_footer { height: fit-content; }
#txt2img_footer, #img2img_footer { height: fit-content; display: none; }
#txt2img_generate_box, #img2img_generate_box { gap: 0.5em; flex-wrap: wrap-reverse; height: fit-content; }
@@ -133,7 +131,7 @@ div#extras_scale_to_tab div.form{ flex-direction: row; }
#settings .dirtyable.hidden { display: none; }
#settings .modification-indicator { height: 1.2em; border-radius: 1em !important; padding: 0; width: 0; margin-right: 0.5em; }
#settings .modification-indicator:disabled { visibility: hidden; }
#settings .modification-indicator.unsaved { background: var(--color-accent-soft); width: 4px; }
#settings .modification-indicator.saved { background: var(--color-accent-soft); width: 4px; }
#settings .modification-indicator.changed { background: var(--color-accent); width: 4px; }
#settings .modification-indicator.changed.unsaved { background-image: linear-gradient(var(--color-accent) 25%, var(--color-accent-soft) 75%); width: 4px; }
#settings_result { margin: 0 1.2em; }
+15 -18
View File
@@ -7,8 +7,6 @@ let img2img_textarea;
const wait_time = 800;
const token_timeouts = {};
let uiLoaded = false;
let opts_metadata = {};
const opts_tabs = {};
function rememberGallerySelection(name) {
// dummy
@@ -27,7 +25,7 @@ function update_token_counter(button_id) {
function clip_gallery_urls(gallery) {
const files = gallery.map((v) => v.data);
navigator.clipboard.writeText(JSON.stringify(files)).then(
() => console.log('clipboard:', files),
() => log('clipboard:', files),
(err) => console.error('clipboard:', files, err),
);
}
@@ -146,7 +144,7 @@ function clearGallery(tabname) {
}
function submit(...args) {
console.log('submitTxt');
log('submitTxt');
clearGallery('txt2img');
const id = randomId();
requestProgress(id, null, gradioApp().getElementById('txt2img_gallery'));
@@ -156,7 +154,7 @@ function submit(...args) {
}
function submit_img2img(...args) {
console.log('submitImg');
log('submitImg');
clearGallery('img2img');
const id = randomId();
requestProgress(id, null, gradioApp().getElementById('img2img_gallery'));
@@ -167,7 +165,7 @@ function submit_img2img(...args) {
}
function submit_postprocessing(...args) {
console.log('SubmitExtras');
log('SubmitExtras');
clearGallery('extras');
return args;
}
@@ -227,7 +225,7 @@ function register_drag_drop() {
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
for (const f of evt.dataTransfer.files) {
console.log('QuickSettingsDrop', f);
log('QuickSettingsDrop', f);
}
});
}
@@ -259,13 +257,13 @@ function sortUIElements() {
const scriptsImg = gradioApp().getElementById('scripts_alwayson_img2img').children;
for (const el of Array.from(scriptsImg)) el.style.order = find(el, tabsOrder);
console.log('sortUIElements');
log('sortUIElements');
}
onAfterUiUpdate(async () => {
let promptsInitialized = false;
function registerTextarea(id, id_counter, id_button) {
async function registerTextarea(id, id_counter, id_button) {
const prompt = gradioApp().getElementById(id);
if (!prompt) return;
const counter = gradioApp().getElementById(id_counter);
@@ -275,7 +273,7 @@ onAfterUiUpdate(async () => {
prompt.parentElement.style.position = 'relative';
promptTokecountUpdateFuncs[id] = () => { update_token_counter(id_button); };
localTextarea.addEventListener('input', promptTokecountUpdateFuncs[id]);
if (!promptsInitialized) console.log('initPrompts')
if (!promptsInitialized) log('initPrompts');
promptsInitialized = true;
}
@@ -378,16 +376,15 @@ async function preview_theme() {
}
}
function reconnectUI() {
async function reconnectUI() {
const gallery = gradioApp().getElementById('txt2img_gallery');
if (!gallery) return;
const task_id = localStorage.getItem('task');
const api_logo = Array.from(gradioApp().querySelectorAll('img')).filter((el) => el?.src?.endsWith('api-logo.svg'));
if (api_logo.length > 0) api_logo[0].remove();
const gallery = gradioApp().getElementById('txt2img_gallery');
const task_id = localStorage.getItem('task');
if (!gallery) return;
clearInterval(start_check); // eslint-disable-line no-use-before-define
if (task_id) {
console.debug('task check:', task_id);
debug('task check:', task_id);
requestProgress(task_id, null, gallery, null, null, true);
}
uiLoaded = true;
@@ -411,7 +408,7 @@ function reconnectUI() {
};
const sd_model_observer = new MutationObserver(sd_model_callback);
sd_model_observer.observe(sd_model, { attributes: true, childList: true, subtree: true });
console.log('reconnectUI');
log('reconnectUI');
}
const start_check = setInterval(reconnectUI, 50);
const start_check = setInterval(reconnectUI, 100);
+1 -8
View File
@@ -551,9 +551,6 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i
file_decoration = shared.opts.samples_filename_pattern
else:
file_decoration = "[seq]-[prompt_words]"
# add_number = shared.opts.save_images_add_number or file_decoration == ''
# if file_decoration != "" and add_number:
# file_decoration = f"-{file_decoration}"
file_decoration = namegen.apply(file_decoration) + suffix
if shared.opts.save_images_add_number:
if '[seq]' not in file_decoration:
@@ -578,10 +575,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i
params = script_callbacks.ImageSaveParams(image, p, fullfn, pnginfo)
script_callbacks.before_image_saved_callback(params)
exifinfo = params.pnginfo.get('UserComment', '')
if len(exifinfo) > 0:
exifinfo = exifinfo + ', ' + params.pnginfo.get(pnginfo_section_name, '')
else:
exifinfo = params.pnginfo.get(pnginfo_section_name, '')
exifinfo = (exifinfo + ', ' if len(exifinfo) > 0 else '') + params.pnginfo.get(pnginfo_section_name, '')
filename, extension = os.path.splitext(params.filename)
if hasattr(os, 'statvfs'):
max_name_len = os.statvfs(path).f_namemax
@@ -591,7 +585,6 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='jpg', i
save_queue.put((params.image, filename, extension, params, exifinfo, txt_fullfn)) # actual save is executed in a thread that polls data from queue
save_queue.join()
# atomically_save_image(params.image, filename, extension, params, exifinfo, txt_fullfn)
params.image.already_saved_as = params.filename
script_callbacks.image_saved_callback(params)
+6 -5
View File
@@ -498,7 +498,8 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su
generation_params.update(p.extra_generation_params)
generation_params_text = ", ".join([k if k == v else f'{k}: {generation_parameters_copypaste.quote(v)}' for k, v in generation_params.items() if v is not None])
negative_prompt_text = f"\nNegative prompt: {all_negative_prompts[index]}" if all_negative_prompts[index] else ""
return f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
infotext = f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
return infotext
"""
@@ -776,19 +777,19 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
p.ops.append('color')
image = apply_color_correction(p.color_corrections[i], image)
image = apply_overlay(image, p.paste_to, i, p.overlay_images)
if shared.opts.samples_save and not p.do_not_save_samples:
images.save_image(image, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=infotext(i), p=p)
text = infotext(i)
infotexts.append(text)
image.info["parameters"] = text
output_images.append(image)
if shared.opts.samples_save and not p.do_not_save_samples:
images.save_image(image, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p)
if hasattr(p, 'mask_for_overlay') and p.mask_for_overlay and any([shared.opts.save_mask, shared.opts.save_mask_composite, shared.opts.return_mask, shared.opts.return_mask_composite]):
image_mask = p.mask_for_overlay.convert('RGB')
image_mask_composite = Image.composite(image.convert('RGBA').convert('RGBa'), Image.new('RGBa', image.size), images.resize_image(3, p.mask_for_overlay, image.width, image.height).convert('L')).convert('RGBA')
if shared.opts.save_mask:
images.save_image(image_mask, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=infotext(i), p=p, suffix="-mask")
images.save_image(image_mask, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p, suffix="-mask")
if shared.opts.save_mask_composite:
images.save_image(image_mask_composite, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=infotext(i), p=p, suffix="-mask-composite")
images.save_image(image_mask_composite, p.outpath_samples, "", p.seeds[i], p.prompts[i], shared.opts.samples_format, info=text, p=p, suffix="-mask-composite")
if shared.opts.return_mask:
output_images.append(image_mask)
if shared.opts.return_mask_composite:
+3 -3
View File
@@ -215,13 +215,13 @@ def model_hash(filename):
try:
with open(filename, "rb") as file:
import hashlib
t0 = time.time()
# t0 = time.time()
m = hashlib.sha256()
file.seek(0x100000)
m.update(file.read(0x10000))
shorthash = m.hexdigest()[0:8]
t1 = time.time()
shared.log.debug(f'Calculating short hash: {filename} hash={shorthash} time={(t1-t0):.2f}')
# t1 = time.time()
# shared.log.debug(f'Calculating short hash: {filename} hash={shorthash} time={(t1-t0):.2f}')
return shorthash
except FileNotFoundError:
return 'NOFILE'
+3 -3
View File
@@ -280,7 +280,7 @@ def disable_extensions():
else:
opts.data['disabled_extensions'] = [x for x in opts.disabled_extensions if x != 'Lora']
if backend == Backend.DIFFUSERS:
for ext in ['sd-webui-controlnet', 'sd-dynamic-thresholding', 'multidiffusion-upscaler-for-automatic1111', 'a1111-sd-webui-lycoris']:
for ext in ['sd-webui-controlnet', 'multidiffusion-upscaler-for-automatic1111', 'a1111-sd-webui-lycoris']:
if ext not in opts.disabled_extensions:
log.warning(f'Diffusers disabling uncompatible extension: {ext}')
opts.data['disabled_extensions'].append(ext)
@@ -385,7 +385,7 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
"upcast_sampling": OptionInfo(True if sys.platform == "darwin" else False, "Enable upcast sampling"),
"upcast_attn": OptionInfo(False, "Enable upcast cross attention layer"),
"cuda_cast_unet": OptionInfo(False, "Use fixed UNet precision"),
"disable_nan_check": OptionInfo(True, "Disable NaN check in produced images/latent spaces"),
"disable_nan_check": OptionInfo(True, "Disable NaN check in produced images/latent spaces", gr.Checkbox, {"visible": False}),
"rollback_vae": OptionInfo(False, "Attempt VAE roll back when produced NaN values (experimental)"),
"opt_channelslast": OptionInfo(False, "Use channels last as torch memory format "),
"cudnn_benchmark": OptionInfo(False, "Enable full-depth cuDNN benchmark feature"),
@@ -399,7 +399,7 @@ options_templates.update(options_section(('cuda', "Compute Settings"), {
"cuda_compile_verbose": OptionInfo(False, "Model compile verbose mode"),
"cuda_compile_errors": OptionInfo(True, "Model compile suppress errors"),
"ipex_optimize": OptionInfo(True if devices.backend == "ipex" else False, "Enable IPEX Optimize for Intel GPUs"),
"directml_memory_provider": OptionInfo(default_memory_provider, '[DirectML] Memory stats provider', gr.Dropdown, lambda: {"choices": memory_providers}),
"directml_memory_provider": OptionInfo(default_memory_provider, 'DirectML memory stats provider', gr.Dropdown, lambda: {"choices": memory_providers}),
}))
options_templates.update(options_section(('diffusers', "Diffusers Settings"), {
+3 -2
View File
@@ -82,8 +82,8 @@ def save_files(js_data, images, html_info, index):
self.prompt = getattr(self, 'prompt', None) or getattr(self, 'Prompt', None)
self.all_seeds = getattr(self, 'all_seeds', [self.seed])
self.all_prompts = getattr(self, 'all_prompts', [self.prompt])
self.infotext = html_info
self.infotexts = getattr(self, 'infotexts', [html_info])
self.infotext = self.infotexts[0] if len(self.infotexts) > 0 else html_info
self.index_of_first_image = getattr(self, 'index_of_first_image', 0)
try:
data = json.loads(js_data)
@@ -164,7 +164,8 @@ def create_output_panel(tabname, outdir):
with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
with gr.Group(elem_id=f"{tabname}_gallery_container"):
result_gallery = gr.Gallery(value=[], label='Output', show_label=False, elem_id=f"{tabname}_gallery", elem_classes="logo").style(preview=False, container=False, columns=[1,2,3,4,5,6]) # <576px, <768px, <992px, <1200px, <1400px, >1400px
# columns are for <576px, <768px, <992px, <1200px, <1400px, >1400px
result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, elem_id=f"{tabname}_gallery", container=False, preview=True, columns=[1,2,3,4,5,6], object_fit='scale-down')
with gr.Column(elem_id=f"{tabname}_footer", elem_classes="gallery_footer"):
with gr.Row(elem_id=f"image_buttons_{tabname}", elem_classes="image-buttons"):
+28 -8
View File
@@ -1,4 +1,5 @@
import re
import time
import json
import html
import os.path
@@ -14,10 +15,23 @@ from modules.ui_components import ToolButton
extra_pages = []
allowed_dirs = set()
dir_cache = {}
refresh_symbol = '\U0001f504' # 🔄
close_symbol = '\U0000274C' # ❌
def listdir(path):
if path in dir_cache and os.path.getmtime(path) == dir_cache[path][0]:
return dir_cache[path][1]
else:
dir_cache[path] = (
os.path.getmtime(path),
[os.path.join(path, f) for f in os.listdir(path)]
)
return dir_cache[path][1]
def register_page(page):
"""registers extra networks page for the UI; recommend doing it in on_before_ui() callback for extensions"""
extra_pages.append(page)
@@ -125,7 +139,7 @@ class ExtraNetworksPage:
return ""
def is_empty(self, folder):
for f in os.listdir(folder):
for f in listdir(folder):
_fn, ext = os.path.splitext(f)
if ext.lower() in ['.ckpt', '.safetensors', '.pt'] or os.path.isdir(os.path.join(folder, f)):
return False
@@ -154,6 +168,7 @@ class ExtraNetworksPage:
self.missing_thumbs.clear()
def create_html(self, tabname, skip = False):
t0 = time.time()
self_name_id = self.name.replace(" ", "_")
if skip:
return f"<div id='{tabname}_{self_name_id}_subdirs' class='extra-network-subdirs'></div><div id='{tabname}_{self_name_id}_cards' class='extra-network-cards'>Extra network page not ready<br>Click refresh to try again</div>"
@@ -199,7 +214,8 @@ class ExtraNetworksPage:
res = f"<div id='{tabname}_{self_name_id}_subdirs' class='extra-network-subdirs'>{subdirs_html}</div><div id='{tabname}_{self_name_id}_cards' class='extra-network-cards'>{self.html}</div>"
else:
return ''
shared.log.debug(f'Extra networks: {self.name} items={len(self.items)} subdirs={len(subdirs)}')
t1 = time.time()
shared.log.debug(f'Extra networks: {self.name} items={len(self.items)} subdirs={len(subdirs)} time={round(t1-t0, 2)}')
threading.Thread(target=self.create_thumb).start()
return res
except Exception as e:
@@ -240,7 +256,6 @@ class ExtraNetworksPage:
args['title'] += f'\nAlias: {item["alias"]}'
if item.get("tags", None) is not None:
args['title'] += f'\nTags: {", ".join(tags)}'
#self.card.format(**args)
return self.card.format(**args)
except Exception as e:
shared.log.error(f'Extra networks item error: page={tabname} item={item["name"]} {e}')
@@ -248,16 +263,20 @@ class ExtraNetworksPage:
def find_preview(self, path):
preview_extensions = ["jpg", "jpeg", "png", "webp", "tiff", "jp2"]
files = listdir(os.path.dirname(path))
for file in [f'{path}{mid}{ext}' for ext in preview_extensions for mid in ['.thumb.', '.preview.', '.']]:
if os.path.exists(file):
# if os.path.exists(file):
if file in files:
if '.thumb.' not in file:
self.missing_thumbs.append(file)
return self.link_preview(file)
return self.link_preview('html/card-no-preview.png')
def find_description(self, path):
files = listdir(os.path.dirname(path))
for file in [f"{path}.txt", f"{path}.description.txt"]:
if os.path.exists(file):
# if os.path.exists(file):
if file in files:
try:
with open(file, "r", encoding="utf-8", errors="replace") as f:
txt = f.read()
@@ -269,8 +288,10 @@ class ExtraNetworksPage:
def find_info(self, path):
basename, _ext = os.path.splitext(path)
files = listdir(os.path.dirname(path))
for file in [f"{path}.info", f"{path}.civitai.info", f"{basename}.info", f"{basename}.civitai.info"]:
if os.path.exists(file):
# if os.path.exists(file):
if file in files:
try:
with open(file, "r", encoding="utf-8", errors="replace") as f:
txt = f.read()
@@ -278,8 +299,7 @@ class ExtraNetworksPage:
return txt
except OSError:
pass
return None
return None
def initialize():