7 Commits

Author SHA1 Message Date
  w-e-w 04903af798
Merge pull request #16604 from Haoming02/ext-updt-parallel 1 year ago
  w-e-w e8c3b1f2a0
Merge pull request #16718 from Haoming02/bracket-checker-order 1 year ago
  Haoming 8bf30e3c42 revert IIFE 1 year ago
  Haoming fbc51fa210 skip escaped 1 year ago
  Haoming 7025a2c4a5 check-for-order 1 year ago
  w-e-w 95686227bd limit number of simultaneous updates 1 year ago
  Haoming df74c3c638 threading 1 year ago
3 changed files with 68 additions and 27 deletions
Split View
  1. +55
    -22
      extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js
  2. +1
    -0
      modules/shared_options.py
  3. +12
    -5
      modules/ui_extensions.py

+ 55
- 22
extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js View File

@@ -1,36 +1,69 @@
// Stable Diffusion WebUI - Bracket checker
// By Hingashi no Florin/Bwin4L & @akx
// Stable Diffusion WebUI - Bracket Checker
// By @Bwin4L, @akx, @w-e-w, @Haoming02
// Counts open and closed brackets (round, square, curly) in the prompt and negative prompt text boxes in the txt2img and img2img tabs.
// If there's a mismatch, the keyword counter turns red and if you hover on it, a tooltip tells you what's wrong.
// If there's a mismatch, the keyword counter turns red, and if you hover on it, a tooltip tells you what's wrong.

function checkBrackets(textArea, counterElem) {
const pairs = [
['(', ')', 'round brackets'],
['[', ']', 'square brackets'],
['{', '}', 'curly brackets']
];

function checkBrackets(textArea, counterElt) {
const counts = {};
textArea.value.matchAll(/(?<!\\)(?:\\\\)*?([(){}[\]])/g).forEach(bracket => {
counts[bracket[1]] = (counts[bracket[1]] || 0) + 1;
});
const errors = [];

function checkPair(open, close, kind) {
if (counts[open] !== counts[close]) {
errors.push(
`${open}...${close} - Detected ${counts[open] || 0} opening and ${counts[close] || 0} closing ${kind}.`
);
const errors = new Set();
let i = 0;

while (i < textArea.value.length) {
let char = textArea.value[i];
let escaped = false;
while (char === '\\' && i + 1 < textArea.value.length) {
escaped = !escaped;
i++;
char = textArea.value[i];
}

if (escaped) {
i++;
continue;
}

for (const [open, close, label] of pairs) {
if (char === open) {
counts[label] = (counts[label] || 0) + 1;
} else if (char === close) {
counts[label] = (counts[label] || 0) - 1;
if (counts[label] < 0) {
errors.add(`Incorrect order of ${label}.`);
}
}
}

i++;
}

for (const [open, close, label] of pairs) {
if (counts[label] == undefined) {
continue;
}

if (counts[label] > 0) {
errors.add(`${open} ... ${close} - Detected ${counts[label]} more opening than closing ${label}.`);
} else if (counts[label] < 0) {
errors.add(`${open} ... ${close} - Detected ${-counts[label]} more closing than opening ${label}.`);
}
}

checkPair('(', ')', 'round brackets');
checkPair('[', ']', 'square brackets');
checkPair('{', '}', 'curly brackets');
counterElt.title = errors.join('\n');
counterElt.classList.toggle('error', errors.length !== 0);
counterElem.title = [...errors].join('\n');
counterElem.classList.toggle('error', errors.size !== 0);
}

function setupBracketChecking(id_prompt, id_counter) {
var textarea = gradioApp().querySelector("#" + id_prompt + " > label > textarea");
var counter = gradioApp().getElementById(id_counter);
const textarea = gradioApp().querySelector(`#${id_prompt} > label > textarea`);
const counter = gradioApp().getElementById(id_counter);

if (textarea && counter) {
textarea.addEventListener("input", () => checkBrackets(textarea, counter));
onEdit(`${id_prompt}_BracketChecking`, textarea, 400, () => checkBrackets(textarea, counter));
}
}



+ 1
- 0
modules/shared_options.py View File

@@ -128,6 +128,7 @@ options_templates.update(options_section(('system', "System", "system"), {
"disable_mmap_load_safetensors": OptionInfo(False, "Disable memmapping for loading .safetensors files.").info("fixes very slow loading speed in some cases"),
"hide_ldm_prints": OptionInfo(True, "Prevent Stability-AI's ldm/sgm modules from printing noise to console."),
"dump_stacks_on_signal": OptionInfo(False, "Print stack traces before exiting the program with ctrl+c."),
"concurrent_git_fetch_limit": OptionInfo(16, "Number of simultaneous extension update checks ", gr.Slider, {"step": 1, "minimum": 1, "maximum": 100}).info("reduce extension update check time"),
}))
options_templates.update(options_section(('profiler', "Profiler", "system"), {


+ 12
- 5
modules/ui_extensions.py View File

@@ -1,5 +1,6 @@
import json
import os
from concurrent.futures import ThreadPoolExecutor
import threading
import time
from datetime import datetime, timezone
@@ -106,18 +107,24 @@ def check_updates(id_task, disable_list):
exts = [ext for ext in extensions.extensions if ext.remote is not None and ext.name not in disabled]
shared.state.job_count = len(exts)
for ext in exts:
shared.state.textinfo = ext.name
lock = threading.Lock()
def _check_update(ext):
try:
ext.check_updates()
except FileNotFoundError as e:
if 'FETCH_HEAD' not in str(e):
raise
except Exception:
errors.report(f"Error checking updates for {ext.name}", exc_info=True)
shared.state.nextjob()
with lock:
errors.report(f"Error checking updates for {ext.name}", exc_info=True)
with lock:
shared.state.textinfo = ext.name
shared.state.nextjob()
with ThreadPoolExecutor(max_workers=max(1, int(shared.opts.concurrent_git_fetch_limit))) as executor:
for ext in exts:
executor.submit(_check_update, ext)
return extension_table(), ""


Loading…
Cancel
Save
Baidu
map