diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d95d2717..72b8d6d30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -178,6 +178,7 @@ Models...And support for new models: **CogView-4**, **SANA 1.5**, - fix token counter error style with modernui - fix sampler metadata when using default sampler - fix paste incorrect float to int cast + - fix server restart from ui - do not allow edit of built-in styles - improve lora compatibility with balanced offload diff --git a/javascript/script.js b/javascript/script.js index f943f4626..8c270bb63 100644 --- a/javascript/script.js +++ b/javascript/script.js @@ -65,6 +65,7 @@ function onOptionsChanged(callback) { function executeCallbacks(queue, arg) { // if (!uiLoaded) return for (const callback of queue) { + if (!callback) continue; try { callback(arg); } catch (e) { diff --git a/javascript/settings.js b/javascript/settings.js index 7a43969ac..99902fb02 100644 --- a/javascript/settings.js +++ b/javascript/settings.js @@ -26,7 +26,7 @@ async function updateOpts(json_string) { const key = Object.keys(op)[0]; const callback = op[key]; if (opts[key] && opts[key] !== settings_data.values[key]) { - log('updateOpts', key, opts[key], settings_data.values[key]); + log('updateOpt', key, opts[key], settings_data.values[key]); if (callback) callback(new_opts[key], opts[key]); } } @@ -37,7 +37,8 @@ async function updateOpts(json_string) { if (callback) callback(new_opts[key], opts[key]); } - opts = new_opts; + window.opts = new_opts; + log('updateOpts', Object.keys(new_opts).length); Object.entries(opts_metadata).forEach(([opt, meta]) => { if (!opts_tabs[meta.tab_name]) opts_tabs[meta.tab_name] = {}; if (!opts_tabs[meta.tab_name].unsaved_keys) opts_tabs[meta.tab_name].unsaved_keys = new Set(); diff --git a/javascript/startup.js b/javascript/startup.js index d8407391d..328c167b6 100644 --- a/javascript/startup.js +++ b/javascript/startup.js @@ -3,6 +3,7 @@ window.api = '/sdapi/v1'; window.subpath = ''; async function initStartup() { + const t0 = performance.now(); log('initStartup'); if (window.setupLogger) await setupLogger(); @@ -24,7 +25,11 @@ async function initStartup() { await reconnectUI(); // make sure all of the ui is ready and options are loaded - while (Object.keys(window.opts).length === 0) await sleep(50); + let t1 = performance.now(); + while ((Object.keys(window.opts).length === 0) && (t1 - t0 < 10000)) { + t1 = performance.now(); + await sleep(50); + } log('mountURL', window.opts.subpath); if (window.opts.subpath?.length > 0) { window.subpath = window.opts.subpath; @@ -43,6 +48,8 @@ async function initStartup() { setHints(); applyStyles(); initIndexDB(); + t1 = performance.now(); + log('initStartup', Math.round(1000 * (t1 - t0) / 1000000)); } onUiLoaded(initStartup); diff --git a/modules/shared.py b/modules/shared.py index dd8f8aad7..63d01446c 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -1250,7 +1250,7 @@ total_tqdm = TotalTQDM() def restart_server(restart=True): if demo is None: return - log.warning('Server shutdown requested') + log.critical('Server shutdown requested') try: sys.tracebacklimit = 0 stdout = io.StringIO() diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index a73f33a56..e16a26bbf 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -56,6 +56,9 @@ preview_map = None def init_api(): def fetch_file(filename: str = ""): + global allowed_dirs # pylint: disable=global-statement + if len(allowed_dirs) == 0: + allowed_dirs = shared.demo.allowed_paths if not os.path.exists(filename): return JSONResponse({ "error": f"file {filename}: not found" }, status_code=404) if filename.startswith('html/') or filename.startswith('models/'): @@ -473,6 +476,8 @@ def register_page(page: ExtraNetworksPage): def register_pages(): debug('EN register-pages') + shared.extra_networks.clear() + allowed_dirs.clear() from modules.ui_extra_networks_checkpoints import ExtraNetworksPageCheckpoints from modules.ui_extra_networks_vae import ExtraNetworksPageVAEs from modules.ui_extra_networks_styles import ExtraNetworksPageStyles diff --git a/modules/ui_loadsave.py b/modules/ui_loadsave.py index 1135134d2..594b44c1d 100644 --- a/modules/ui_loadsave.py +++ b/modules/ui_loadsave.py @@ -13,7 +13,6 @@ class UiLoadsave: def __init__(self, filename): self.filename = filename self.component_mapping = {} - self.finalized_ui = False self.ui_defaults_view = None # button self.ui_defaults_apply = None # button self.ui_defaults_review = None # button @@ -24,8 +23,6 @@ class UiLoadsave: self.ui_settings = self.read_from_file() def add_component(self, path, x): - """adds component to the registry of tracked components""" - assert not self.finalized_ui def apply_field(obj, field, condition=None, init_field=None): key = f"{path}/{field}" @@ -253,7 +250,6 @@ class UiLoadsave: return "Restored system defaults for user interface" def create_ui(self): - """creates ui elements for editing defaults UI, without adding any logic to them""" with gr.Row(elem_id="config_row"): self.ui_defaults_apply = gr.Button(value='Set UI defaults', elem_id="ui_defaults_apply", variant="primary") self.ui_defaults_submenu = gr.Button(value='Set UI menu states', elem_id="ui_submenu_apply", variant="primary") @@ -262,9 +258,6 @@ class UiLoadsave: self.ui_defaults_review = gr.HTML("", elem_id="ui_defaults_review") def setup_ui(self): - """adds logic to elements created with create_ui; all add_block class must be made before this""" - assert not self.finalized_ui - self.finalized_ui = True self.ui_defaults_view.click(fn=self.ui_view, inputs=list(self.component_mapping.values()), outputs=[self.ui_defaults_review]) self.ui_defaults_apply.click(fn=self.ui_apply, inputs=list(self.component_mapping.values()), outputs=[self.ui_defaults_review]) self.ui_defaults_restore.click(fn=self.ui_restore, inputs=[], outputs=[self.ui_defaults_review]) diff --git a/modules/ui_settings.py b/modules/ui_settings.py index 06d37c251..bda278a81 100644 --- a/modules/ui_settings.py +++ b/modules/ui_settings.py @@ -3,9 +3,9 @@ import gradio as gr from modules import timer, shared, paths, theme, sd_models, modelloader, ui_common, ui_loadsave, generation_parameters_copypaste, call_queue, script_callbacks +text_settings = None # holds json of entire shared.opts ui_system_tabs = None # required for system-info dummy_component = gr.Textbox(visible=False, value='dummy') -text_settings = gr.Textbox(elem_id="settings_json", value=lambda: shared.opts.dumpjson(), visible=False) loadsave = ui_loadsave.UiLoadsave(shared.cmd_opts.ui_config) quicksettings_names = {x: i for i, x in enumerate(shared.opts.quicksettings_list) if x != 'quicksettings'} quicksettings_list = [] @@ -168,6 +168,8 @@ def run_settings_single(value, key, progress=False): def create_ui(): + global text_settings # pylint: disable=global-statement + text_settings = gr.Textbox(elem_id="settings_json", elem_classes=["settings_json"], value=lambda: shared.opts.dumpjson(), visible=False) with gr.Row(elem_id="system_row"): restart_submit = gr.Button(value="Restart server", variant='primary', elem_id="restart_submit") shutdown_submit = gr.Button(value="Shutdown server", variant='primary', elem_id="shutdown_submit") @@ -203,6 +205,7 @@ def create_ui(): shared.log.debug(f'UI settings: sections={len(sections)} settings={len(list(shared.opts.data_labels))}') with gr.Tabs(elem_id="settings"): + quicksettings_list.clear() for (section_id, section_text) in sections: items = [item for item in shared.opts.data_labels.items() if item[1].section[0] == section_id] # find all items in this section hidden = section_id is None or 'hidden' in section_id.lower() or 'hidden' in section_text.lower() diff --git a/webui.py b/webui.py index c59aa5647..1996c41b5 100644 --- a/webui.py +++ b/webui.py @@ -293,6 +293,8 @@ def start_ui(): allowed_paths = [os.path.dirname(__file__)] if shared.cmd_opts.data_dir is not None and os.path.isdir(shared.cmd_opts.data_dir): allowed_paths.append(shared.cmd_opts.data_dir) + if shared.cmd_opts.models_dir is not None and os.path.isdir(shared.cmd_opts.models_dir): + allowed_paths.append(shared.cmd_opts.models_dir) if shared.cmd_opts.allowed_paths is not None: allowed_paths += [p for p in shared.cmd_opts.allowed_paths if os.path.isdir(p)] shared.log.debug(f'Root paths: {allowed_paths}')