From 903acff924af4531bff907710c69a91265a0347d Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Thu, 10 Nov 2022 18:36:39 -0800 Subject: [PATCH 01/39] Adding Use Settings --- ui/media/css/main.css | 10 ++++++ ui/media/js/image-modifiers.js | 54 +++++++++++++++++++++++++++++++- ui/media/js/main.js | 57 +++++++++++++++++++++++++++++----- 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/ui/media/css/main.css b/ui/media/css/main.css index da87216d..33d18177 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -428,6 +428,16 @@ img { .secondaryButton:hover { background: rgb(177, 27, 0); } +.useSettings { + background: var(--accent-color); + border: var(--make-image-border); + color: rgb(255, 221, 255); + margin-right: 6pt; + float: right; +} +.useSettings:hover { + background: hsl(var(--accent-hue), 100%, calc(var(--accent-lightness) + 6%)); +} .stopTask { float: right; } diff --git a/ui/media/js/image-modifiers.js b/ui/media/js/image-modifiers.js index 12bdd65f..8cf26a49 100644 --- a/ui/media/js/image-modifiers.js +++ b/ui/media/js/image-modifiers.js @@ -148,6 +148,58 @@ async function loadModifiers() { loadCustomModifiers() } +function refreshModifiersState(newTags) { + // clear existing modifiers + document.querySelector('#editor-modifiers').querySelectorAll('.modifier-card').forEach(modifierCard => { + const modifierName = modifierCard.querySelector('.modifier-card-label').innerText + if (activeTags.map(x => x.name).includes(modifierName)) { + modifierCard.classList.remove(activeCardClass) + modifierCard.querySelector('.modifier-card-image-overlay').innerText = '+' + } + }) + activeTags = [] + + // set new modifiers + newTags.forEach(tag => { + let found = false + document.querySelector('#editor-modifiers').querySelectorAll('.modifier-card').forEach(modifierCard => { + const modifierName = modifierCard.querySelector('.modifier-card-label').innerText + if (tag == modifierName) { + // add modifier to active array + activeTags.push({ + 'name': modifierName, + 'element': modifierCard.cloneNode(true), + 'originElement': modifierCard + }) + modifierCard.classList.add(activeCardClass) + modifierCard.querySelector('.modifier-card-image-overlay').innerText = '-' + found = true + } + }) + if (found == false) { // custom tag went missing, create one here + let modifierCard = createModifierCard(tag, undefined) // create a modifier card for the missing tag, no image + + modifierCard.addEventListener('click', () => { + if (activeTags.map(x => x.name).includes(tag)) { + // remove modifier from active array + activeTags = activeTags.filter(x => x.name != tag) + modifierCard.classList.remove(activeCardClass) + + modifierCard.querySelector('.modifier-card-image-overlay').innerText = '+' + } + refreshTagsList() + }) + + activeTags.push({ + 'name': tag, + 'element': modifierCard, + 'originElement': undefined // no origin element for missing tags + }) + } + }) + refreshTagsList() +} + function refreshTagsList() { editorModifierTagsList.innerHTML = '' @@ -167,7 +219,7 @@ function refreshTagsList() { tag.element.addEventListener('click', () => { let idx = activeTags.indexOf(tag) - if (idx !== -1) { + if (idx !== -1 && activeTags[idx].originElement !== undefined) { activeTags[idx].originElement.classList.remove(activeCardClass) activeTags[idx].originElement.querySelector('.modifier-card-image-overlay').innerText = '+' diff --git a/ui/media/js/main.js b/ui/media/js/main.js index b326dee3..f6103eba 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -780,7 +780,9 @@ function getCurrentUserRequest() { stream_progress_updates: true, stream_image_progress: (numOutputsTotal > 50 ? false : streamImageProgressField.checked), show_only_filtered_image: showOnlyFilteredImageField.checked, - output_format: outputFormatField.value + output_format: outputFormatField.value, + original_prompt: promptField.value, + active_tags: (activeTags.map(x => x.name)) } } if (IMAGE_REGEX.test(initImagePreview.src)) { @@ -855,6 +857,7 @@ function createTask(task) { taskEntry.innerHTML = `
Enqueued
+
${taskConfig}
@@ -893,6 +896,47 @@ function createTask(task) { } }) + task['useSettings'] = taskEntry.querySelector('.useSettings') + task['useSettings'].addEventListener('click', async function(e) { + TASK_REQ_NO_EXPORT.forEach((key) => delete task.reqBody[key]) // don't restore system settings when restoring tasks + restoreTaskToUI(task) + e.stopPropagation(); + + // restore the original tag + promptField.value = task.reqBody.original_prompt + + // Restore modifiers + refreshModifiersState(task.reqBody.active_tags) + + // properly reset checkboxes + if (!('use_face_correction' in task.reqBody)) { + useFaceCorrectionField.checked = false + } + if (!('use_upscale' in task.reqBody)) { + useUpscalingField.checked = false + } + if (!('mask' in task.reqBody)) { + maskSetting.checked = false + } + + // Show the source picture if present + initImagePreview.src = (task.reqBody.init_image == undefined ? '' : task.reqBody.init_image) + if (IMAGE_REGEX.test(initImagePreview.src)) { + Boolean(task.reqBody.mask) ? inpaintingEditor.setImg(task.reqBody.mask) : inpaintingEditor.resetBackground() + initImagePreviewContainer.style.display = 'block' + inpaintingEditorContainer.style.display = 'none' + promptStrengthContainer.style.display = 'table-row' + //samplerSelectionContainer.style.display = 'none' + // maskSetting.checked = false + inpaintingEditorContainer.style.display = maskSetting.checked ? 'block' : 'none' + } else { + initImagePreviewContainer.style.display = 'none' + // inpaintingEditorContainer.style.display = 'none' + promptStrengthContainer.style.display = 'none' + // maskSetting.style.display = 'none' + } + }) + imagePreview.insertBefore(taskEntry, previewTools.nextSibling) task.previewPrompt.innerText = task.reqBody.prompt @@ -913,15 +957,14 @@ function getPrompts() { prompts = prompts.map(prompt => prompt.trim()) prompts = prompts.filter(prompt => prompt !== '') + if (activeTags.length > 0) { + const promptTags = activeTags.map(x => x.name).join(", ") + prompts = prompts.map((prompt) => `${prompt}, ${promptTags}`) + } let promptsToMake = applySetOperator(prompts) promptsToMake = applyPermuteOperator(promptsToMake) - if (activeTags.length <= 0) { - return promptsToMake - } - - const promptTags = activeTags.map(x => x.name).join(", ") - return promptsToMake.map((prompt) => `${prompt}, ${promptTags}`) + return promptsToMake } function applySetOperator(prompts) { From 332f2b0678e05ed4c496d6c74cfad66d555abb44 Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Sat, 12 Nov 2022 19:04:23 -0800 Subject: [PATCH 02/39] Hotfix for CSS layout regression --- ui/media/css/main.css | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/media/css/main.css b/ui/media/css/main.css index d878fa19..33d18177 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -28,7 +28,6 @@ label { font-size: 13px; margin-bottom: 6px; margin-top: 5px; - display: block; } .image_preview_container { margin-top: 10pt; @@ -657,9 +656,9 @@ input::file-selector-button { } @media (min-width: 700px) { - /* #editor { + #editor { max-width: 480px; - } */ + } .float-container { padding: 20px; } From a6f3e87921ec157cea3beec350e3d3c6a21f4df8 Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Wed, 16 Nov 2022 00:35:02 -0800 Subject: [PATCH 03/39] Image modifiers drag-and-drop plugin --- ui/plugins/ui/modifiers-dnd.plugin.js | 100 ++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 ui/plugins/ui/modifiers-dnd.plugin.js diff --git a/ui/plugins/ui/modifiers-dnd.plugin.js b/ui/plugins/ui/modifiers-dnd.plugin.js new file mode 100644 index 00000000..9406cf82 --- /dev/null +++ b/ui/plugins/ui/modifiers-dnd.plugin.js @@ -0,0 +1,100 @@ +(function () { + "use strict" + + var styleSheet = document.createElement("style"); + styleSheet.textContent = ` + .modifier-card-tiny.drag-sort-active { + background: transparent; + border: 2px dashed white; + opacity:0.2; + } + `; + document.head.appendChild(styleSheet); + + // observe for changes in tag list + var observer = new MutationObserver(function (mutations) { + // mutations.forEach(function (mutation) { + if (editorModifierTagsList.childNodes.length > 0) { + ModifierDragAndDrop(editorModifierTagsList) + } + // }) + }) + + observer.observe(editorModifierTagsList, { + childList: true + }) + + let current + function ModifierDragAndDrop(target) { + editorModifierTagsList.ondragenter = (e) => { + e.preventDefault() + e.stopPropagation() + } + editorModifierTagsList.ondragover = (e) => { + e.preventDefault() + e.stopPropagation() + } + + let overlays = document.querySelector('#editor-inputs-tags-list').querySelectorAll('.modifier-card-overlay') + overlays.forEach (i => { + i.parentElement.draggable = true; + + i.parentElement.ondragstart = (e) => { + current = i + i.parentElement.getElementsByClassName('modifier-card-image-overlay')[0].innerText = '' + i.parentElement.draggable = true + i.parentElement.classList.add('drag-sort-active') + for(let item of document.querySelector('#editor-inputs-tags-list').getElementsByClassName('modifier-card-image-overlay')) { + if (item.parentElement.parentElement.getElementsByClassName('modifier-card-overlay')[0] != current) { + item.parentElement.parentElement.getElementsByClassName('modifier-card-image-overlay')[0].style.opacity = 0 + if(item.parentElement.getElementsByClassName('modifier-card-image').length > 0) { + item.parentElement.getElementsByClassName('modifier-card-image')[0].style.filter = 'none' + } + item.parentElement.parentElement.style.transform = 'none' + item.parentElement.parentElement.style.boxShadow = 'none' + } + item.innerText = '' + } + } + + i.ondragenter = (e) => { + e.preventDefault() + if (i != current) { + let currentPos = 0, droppedPos = 0; + for (let it = 0; it < overlays.length; it++) { + if (current == overlays[it]) { currentPos = it; } + if (i == overlays[it]) { droppedPos = it; } + } + + if (i.parentElement != current.parentElement) { + let currentPos = 0, droppedPos = 0 + for (let it = 0; it < overlays.length; it++) { + if (current == overlays[it]) { currentPos = it } + if (i == overlays[it]) { droppedPos = it } + } + if (currentPos < droppedPos) { + current = i.parentElement.parentNode.insertBefore(current.parentElement, i.parentElement.nextSibling).getElementsByClassName('modifier-card-overlay')[0] + } else { + current = i.parentElement.parentNode.insertBefore(current.parentElement, i.parentElement).getElementsByClassName('modifier-card-overlay')[0] + } + // update active tags + const tag = activeTags.splice(currentPos, 1) + activeTags.splice(droppedPos, 0, tag[0]) + } + } + }; + + i.ondragover = (e) => { + e.preventDefault() + } + + i.parentElement.ondragend = (e) => { + i.parentElement.classList.remove('drag-sort-active') + for(let item of document.querySelector('#editor-inputs-tags-list').getElementsByClassName('modifier-card-image-overlay')) { + item.style.opacity = '' + item.innerText = '-' + } + } + }) + } +})() From af4a925b54f8fe11a81e9df1fe36ba6fcd900e0a Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Wed, 16 Nov 2022 00:38:17 -0800 Subject: [PATCH 04/39] Delete modifiers-dnd.plugin.js --- ui/plugins/ui/modifiers-dnd.plugin.js | 100 -------------------------- 1 file changed, 100 deletions(-) delete mode 100644 ui/plugins/ui/modifiers-dnd.plugin.js diff --git a/ui/plugins/ui/modifiers-dnd.plugin.js b/ui/plugins/ui/modifiers-dnd.plugin.js deleted file mode 100644 index 9406cf82..00000000 --- a/ui/plugins/ui/modifiers-dnd.plugin.js +++ /dev/null @@ -1,100 +0,0 @@ -(function () { - "use strict" - - var styleSheet = document.createElement("style"); - styleSheet.textContent = ` - .modifier-card-tiny.drag-sort-active { - background: transparent; - border: 2px dashed white; - opacity:0.2; - } - `; - document.head.appendChild(styleSheet); - - // observe for changes in tag list - var observer = new MutationObserver(function (mutations) { - // mutations.forEach(function (mutation) { - if (editorModifierTagsList.childNodes.length > 0) { - ModifierDragAndDrop(editorModifierTagsList) - } - // }) - }) - - observer.observe(editorModifierTagsList, { - childList: true - }) - - let current - function ModifierDragAndDrop(target) { - editorModifierTagsList.ondragenter = (e) => { - e.preventDefault() - e.stopPropagation() - } - editorModifierTagsList.ondragover = (e) => { - e.preventDefault() - e.stopPropagation() - } - - let overlays = document.querySelector('#editor-inputs-tags-list').querySelectorAll('.modifier-card-overlay') - overlays.forEach (i => { - i.parentElement.draggable = true; - - i.parentElement.ondragstart = (e) => { - current = i - i.parentElement.getElementsByClassName('modifier-card-image-overlay')[0].innerText = '' - i.parentElement.draggable = true - i.parentElement.classList.add('drag-sort-active') - for(let item of document.querySelector('#editor-inputs-tags-list').getElementsByClassName('modifier-card-image-overlay')) { - if (item.parentElement.parentElement.getElementsByClassName('modifier-card-overlay')[0] != current) { - item.parentElement.parentElement.getElementsByClassName('modifier-card-image-overlay')[0].style.opacity = 0 - if(item.parentElement.getElementsByClassName('modifier-card-image').length > 0) { - item.parentElement.getElementsByClassName('modifier-card-image')[0].style.filter = 'none' - } - item.parentElement.parentElement.style.transform = 'none' - item.parentElement.parentElement.style.boxShadow = 'none' - } - item.innerText = '' - } - } - - i.ondragenter = (e) => { - e.preventDefault() - if (i != current) { - let currentPos = 0, droppedPos = 0; - for (let it = 0; it < overlays.length; it++) { - if (current == overlays[it]) { currentPos = it; } - if (i == overlays[it]) { droppedPos = it; } - } - - if (i.parentElement != current.parentElement) { - let currentPos = 0, droppedPos = 0 - for (let it = 0; it < overlays.length; it++) { - if (current == overlays[it]) { currentPos = it } - if (i == overlays[it]) { droppedPos = it } - } - if (currentPos < droppedPos) { - current = i.parentElement.parentNode.insertBefore(current.parentElement, i.parentElement.nextSibling).getElementsByClassName('modifier-card-overlay')[0] - } else { - current = i.parentElement.parentNode.insertBefore(current.parentElement, i.parentElement).getElementsByClassName('modifier-card-overlay')[0] - } - // update active tags - const tag = activeTags.splice(currentPos, 1) - activeTags.splice(droppedPos, 0, tag[0]) - } - } - }; - - i.ondragover = (e) => { - e.preventDefault() - } - - i.parentElement.ondragend = (e) => { - i.parentElement.classList.remove('drag-sort-active') - for(let item of document.querySelector('#editor-inputs-tags-list').getElementsByClassName('modifier-card-image-overlay')) { - item.style.opacity = '' - item.innerText = '-' - } - } - }) - } -})() From 061cee207f2cb32ee3380e43e825300e305ea4a5 Mon Sep 17 00:00:00 2001 From: patriceac <48073125+patriceac@users.noreply.github.com> Date: Wed, 16 Nov 2022 00:39:41 -0800 Subject: [PATCH 05/39] Delete modifiers-dnd.plugin.js --- ui/plugins/ui/modifiers-dnd.plugin.js | 100 -------------------------- 1 file changed, 100 deletions(-) delete mode 100644 ui/plugins/ui/modifiers-dnd.plugin.js diff --git a/ui/plugins/ui/modifiers-dnd.plugin.js b/ui/plugins/ui/modifiers-dnd.plugin.js deleted file mode 100644 index 9406cf82..00000000 --- a/ui/plugins/ui/modifiers-dnd.plugin.js +++ /dev/null @@ -1,100 +0,0 @@ -(function () { - "use strict" - - var styleSheet = document.createElement("style"); - styleSheet.textContent = ` - .modifier-card-tiny.drag-sort-active { - background: transparent; - border: 2px dashed white; - opacity:0.2; - } - `; - document.head.appendChild(styleSheet); - - // observe for changes in tag list - var observer = new MutationObserver(function (mutations) { - // mutations.forEach(function (mutation) { - if (editorModifierTagsList.childNodes.length > 0) { - ModifierDragAndDrop(editorModifierTagsList) - } - // }) - }) - - observer.observe(editorModifierTagsList, { - childList: true - }) - - let current - function ModifierDragAndDrop(target) { - editorModifierTagsList.ondragenter = (e) => { - e.preventDefault() - e.stopPropagation() - } - editorModifierTagsList.ondragover = (e) => { - e.preventDefault() - e.stopPropagation() - } - - let overlays = document.querySelector('#editor-inputs-tags-list').querySelectorAll('.modifier-card-overlay') - overlays.forEach (i => { - i.parentElement.draggable = true; - - i.parentElement.ondragstart = (e) => { - current = i - i.parentElement.getElementsByClassName('modifier-card-image-overlay')[0].innerText = '' - i.parentElement.draggable = true - i.parentElement.classList.add('drag-sort-active') - for(let item of document.querySelector('#editor-inputs-tags-list').getElementsByClassName('modifier-card-image-overlay')) { - if (item.parentElement.parentElement.getElementsByClassName('modifier-card-overlay')[0] != current) { - item.parentElement.parentElement.getElementsByClassName('modifier-card-image-overlay')[0].style.opacity = 0 - if(item.parentElement.getElementsByClassName('modifier-card-image').length > 0) { - item.parentElement.getElementsByClassName('modifier-card-image')[0].style.filter = 'none' - } - item.parentElement.parentElement.style.transform = 'none' - item.parentElement.parentElement.style.boxShadow = 'none' - } - item.innerText = '' - } - } - - i.ondragenter = (e) => { - e.preventDefault() - if (i != current) { - let currentPos = 0, droppedPos = 0; - for (let it = 0; it < overlays.length; it++) { - if (current == overlays[it]) { currentPos = it; } - if (i == overlays[it]) { droppedPos = it; } - } - - if (i.parentElement != current.parentElement) { - let currentPos = 0, droppedPos = 0 - for (let it = 0; it < overlays.length; it++) { - if (current == overlays[it]) { currentPos = it } - if (i == overlays[it]) { droppedPos = it } - } - if (currentPos < droppedPos) { - current = i.parentElement.parentNode.insertBefore(current.parentElement, i.parentElement.nextSibling).getElementsByClassName('modifier-card-overlay')[0] - } else { - current = i.parentElement.parentNode.insertBefore(current.parentElement, i.parentElement).getElementsByClassName('modifier-card-overlay')[0] - } - // update active tags - const tag = activeTags.splice(currentPos, 1) - activeTags.splice(droppedPos, 0, tag[0]) - } - } - }; - - i.ondragover = (e) => { - e.preventDefault() - } - - i.parentElement.ondragend = (e) => { - i.parentElement.classList.remove('drag-sort-active') - for(let item of document.querySelector('#editor-inputs-tags-list').getElementsByClassName('modifier-card-image-overlay')) { - item.style.opacity = '' - item.innerText = '-' - } - } - }) - } -})() From 5429a509c6ffcd23b33ffa57babd975175794e37 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Wed, 16 Nov 2022 20:52:40 +0100 Subject: [PATCH 06/39] Visual feedback for the save button in the system settings --- ui/media/css/main.css | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ui/media/css/main.css b/ui/media/css/main.css index 4b09da6b..f99c6f52 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -910,6 +910,16 @@ i.active { float: right; font-weight: bold; } -#save-system-settings-btn { +button#save-system-settings-btn:hover { + transition-duration: 0.1s; + background: hsl(var(--accent-hue), 100%, calc(var(--accent-lightness) + 6%)); +} + +button#save-system-settings-btn:active { + transition-duration: 0.1s; + background-color: white; +} + +button#save-system-settings-btn { padding: 4pt 8pt; } From add09e52ef377111dbc06fdd3e76c8f758555161 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Wed, 16 Nov 2022 20:56:11 +0100 Subject: [PATCH 07/39] Fix typo in the installer's error messages --- scripts/on_sd_start.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/on_sd_start.bat b/scripts/on_sd_start.bat index 51a51549..205cc3ce 100644 --- a/scripts/on_sd_start.bat +++ b/scripts/on_sd_start.bat @@ -275,7 +275,7 @@ echo. > "..\models\vae\Put your VAE files here.txt" for %%I in ("RealESRGAN_x4plus.pth") do if "%%~zI" EQU "67040989" ( echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus were already downloaded" ) else ( - echo. & echo "The GFPGAN model file present at %cd%\RealESRGAN_x4plus.pth is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. + echo. & echo "The RealESRGAN model file present at %cd%\RealESRGAN_x4plus.pth is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. del "RealESRGAN_x4plus.pth" ) ) @@ -305,7 +305,7 @@ echo. > "..\models\vae\Put your VAE files here.txt" for %%I in ("RealESRGAN_x4plus_anime_6B.pth") do if "%%~zI" EQU "17938799" ( echo "Data files (weights) necessary for ESRGAN (Resolution Upscaling) x4plus_anime were already downloaded" ) else ( - echo. & echo "The GFPGAN model file present at %cd%\RealESRGAN_x4plus_anime_6B.pth is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. + echo. & echo "The RealESRGAN model file present at %cd%\RealESRGAN_x4plus_anime_6B.pth is invalid. It is only %%~zI bytes in size. Re-downloading.." & echo. del "RealESRGAN_x4plus_anime_6B.pth" ) ) From 3e18f2f09ca7f079c617ed42a882cb0f84781e21 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Wed, 16 Nov 2022 22:34:02 +0100 Subject: [PATCH 08/39] Picklescan of model files During getModel(), the server picklescans the model files for potential malicious code in the pickled python objects. If a malicious file is found, the web UI will show a big red error message, the makeImage button will be disabled, and the user must remove the malicious file and reload the UI page. --- scripts/on_sd_start.bat | 10 ++++++++++ scripts/on_sd_start.sh | 7 +++++++ ui/media/js/main.js | 10 +++++++++- ui/server.py | 9 +++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/scripts/on_sd_start.bat b/scripts/on_sd_start.bat index 51a51549..df28e57a 100644 --- a/scripts/on_sd_start.bat +++ b/scripts/on_sd_start.bat @@ -191,6 +191,16 @@ call WHERE uvicorn > .tmp exit /b ) +@>nul 2>nul call python -m picklescan --help +@if "%ERRORLEVEL%" NEQ "0" ( + @echo. & echo Picklescan not found. Installing + @call pip install picklescan || ( + echo "Error installing the picklescan package necessary for Stable Diffusion UI. Sorry about that, please try to:" & echo " 1. Run this installer again." & echo " 2. If that doesn't fix it, please try the common troubleshooting steps at https://github.com/cmdr2/stable-diffusion-ui/wiki/Troubleshooting" & echo " 3. If those steps don't help, please copy *all* the error messages in this window, and ask the community at https://discord.com/invite/u9yhsFmEkB" & echo " 4. If that doesn't solve the problem, please file an issue at https://github.com/cmdr2/stable-diffusion-ui/issues" & echo "Thanks!" + pause + exit /b + ) +) + @>nul findstr /m "conda_sd_ui_deps_installed" ..\scripts\install_status.txt @if "%ERRORLEVEL%" NEQ "0" ( @echo conda_sd_ui_deps_installed >> ..\scripts\install_status.txt diff --git a/scripts/on_sd_start.sh b/scripts/on_sd_start.sh index d4bb1ad1..adcba1f2 100755 --- a/scripts/on_sd_start.sh +++ b/scripts/on_sd_start.sh @@ -156,6 +156,13 @@ else echo conda_sd_ui_deps_installed >> ../scripts/install_status.txt fi +if python -m picklescan --help >/dev/null 2>&1; then + echo "Picklescan is already installed." +else + echo "Picklescan not found, installing." + pip install picklescan || fail "Picklescan installation failed." +fi + mkdir -p "../models/stable-diffusion" diff --git a/ui/media/js/main.js b/ui/media/js/main.js index afb0925d..eee7d8b9 100644 --- a/ui/media/js/main.js +++ b/ui/media/js/main.js @@ -1141,8 +1141,16 @@ async function getModels() { let res = await fetch('/get/models') const models = await res.json() - console.log('get models response', models) + console.log('got models response', models) + if ( "scan-error" in models ) { + // let previewPane = document.getElementById('tab-content-wrapper') + let previewPane = document.getElementById('preview') + previewPane.style.background="red" + previewPane.style.textAlign="center" + previewPane.innerHTML = '

🔥Malware alert!🔥

The file ' + models['scan-error'] + ' in your models/stable-diffusion folder is probably malware infected.

Please delete this file from the folder before proceeding!

After deleting the file, reload this page.

' + makeImageBtn.disabled = true + } let modelOptions = models['options'] let stableDiffusionOptions = modelOptions['stable-diffusion'] let vaeOptions = modelOptions['vae'] diff --git a/ui/server.py b/ui/server.py index 8b54f847..154fc6cd 100644 --- a/ui/server.py +++ b/ui/server.py @@ -7,6 +7,8 @@ import traceback import sys import os +import picklescan.scanner +import rich SD_DIR = os.getcwd() print('started in ', SD_DIR) @@ -206,6 +208,13 @@ def getModels(): os.makedirs(models_dir) for file in os.listdir(models_dir): + scan_result = picklescan.scanner.scan_file_path( os.path.join(models_dir, file)) + if ( scan_result.issues_count >0 or scan_result.infected_files >0): + rich.print(":warning: [bold red]Scan %s: %d scanned, %d issue, %d infected.[/bold red]" % ( file, scan_result.scanned_files, scan_result.issues_count, scan_result.infected_files) ) + models['scan-error'] = file + return models + else: + rich.print("Scan %s: [green]%d scanned, %d issue, %d infected.[/green]" % ( file, scan_result.scanned_files, scan_result.issues_count, scan_result.infected_files ) ) for model_extension in model_extensions: if file.endswith(model_extension): model_name = file[:-len(model_extension)] From 8cebb5314754a0fa636a4c7f899d27c79832c966 Mon Sep 17 00:00:00 2001 From: JeLuF Date: Wed, 16 Nov 2022 23:35:27 +0100 Subject: [PATCH 09/39] Textarea for negative prompts --- ui/index.html | 2 +- ui/media/css/main.css | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ui/index.html b/ui/index.html index 81ab64be..c3502d5d 100644 --- a/ui/index.html +++ b/ui/index.html @@ -54,7 +54,7 @@ (optional)
- +
diff --git a/ui/media/css/main.css b/ui/media/css/main.css index 4b09da6b..6850fa32 100644 --- a/ui/media/css/main.css +++ b/ui/media/css/main.css @@ -30,6 +30,14 @@ label { margin-top: 5px; display: block; } +#negative_prompt { + width: 100%; + height: 50pt; + font-size: 9px; + margin-bottom: 5px; + margin-top: 5px; + display: block; +} .image_preview_container { margin-top: 10pt; } From 7b4cfbeeaa80d69655885fdeb2a81fa4c259ceca Mon Sep 17 00:00:00 2001 From: JeLuF Date: Wed, 16 Nov 2022 23:47:24 +0100 Subject: [PATCH 10/39] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index c9553b22..05562b34 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ ### 2.4.6 * 16 Nov 2022 - Fix a regression in VRAM usage during startup, which caused 'Out of Memory' errors when starting on GPUs with 4gb (or less) VRAM +* 16 Nov 2022 - Add Picklescan - a scanner for malicious model files. If it finds a malicious file, it will halt the web application and alert the user ### 2.4.5 * 16 Nov 2022 - Add checkbox for "Open browser on startup". From 507491fbec69777fdeefd45644c5eb18914e6cfe Mon Sep 17 00:00:00 2001 From: Malcolm Diller Date: Thu, 17 Nov 2022 17:58:09 -0800 Subject: [PATCH 11/39] added fancy switches and updated the ui of the settings tab --- ui/index.html | 5 ++- ui/media/css/auto-save.css | 58 +++++++++++++++++++++++++------- ui/media/css/main.css | 69 +++++++++++++++++++++++++++++++++----- ui/media/css/themes.css | 12 +++++++ ui/media/js/auto-save.js | 3 +- ui/media/js/main.js | 1 + ui/media/js/parameters.js | 27 +++++++++++---- ui/media/js/utils.js | 16 +++++++++ 8 files changed, 158 insertions(+), 33 deletions(-) diff --git a/ui/index.html b/ui/index.html index 43a327ad..abb373e5 100644 --- a/ui/index.html +++ b/ui/index.html @@ -47,7 +47,6 @@ or -