|
@@ -1,21 +1,23 @@
|
|
|
+import datetime
|
|
|
import json
|
|
|
import mimetypes
|
|
|
import os
|
|
|
import sys
|
|
|
-import traceback
|
|
|
from functools import reduce
|
|
|
import warnings
|
|
|
|
|
|
import gradio as gr
|
|
|
-import gradio.routes
|
|
|
import gradio.utils
|
|
|
import numpy as np
|
|
|
from PIL import Image, PngImagePlugin # noqa: F401
|
|
|
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call
|
|
|
|
|
|
-from modules import sd_hijack, sd_models, localization, script_callbacks, ui_extensions, deepbooru, sd_vae, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave
|
|
|
+from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, sd_vae, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, errors, shared_items, ui_settings, timer, sysinfo
|
|
|
from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML
|
|
|
-from modules.paths import script_path, data_path
|
|
|
+from modules.paths import script_path
|
|
|
+from modules.ui_common import create_refresh_button
|
|
|
+from modules.ui_gradio_extensions import reload_javascript
|
|
|
+
|
|
|
|
|
|
from modules.shared import opts, cmd_opts
|
|
|
|
|
@@ -35,6 +37,8 @@ import modules.hypernetworks.ui
|
|
|
from modules.generation_parameters_copypaste import image_from_url_text
|
|
|
import modules.extras
|
|
|
|
|
|
+create_setting_component = ui_settings.create_setting_component
|
|
|
+
|
|
|
warnings.filterwarnings("default" if opts.show_warnings else "ignore", category=UserWarning)
|
|
|
|
|
|
# this is a fix for Windows users. Without it, javascript files will be served with text/html content-type and the browser will not show any UI
|
|
@@ -76,6 +80,7 @@ extra_networks_symbol = '\U0001F3B4' # 🎴
|
|
|
switch_values_symbol = '\U000021C5' # ⇅
|
|
|
restore_progress_symbol = '\U0001F300' # 🌀
|
|
|
detect_image_size_symbol = '\U0001F4D0' # 📐
|
|
|
+up_down_symbol = '\u2195\ufe0f' # ↕️
|
|
|
|
|
|
|
|
|
def plaintext_to_html(text):
|
|
@@ -231,9 +236,8 @@ def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info:
|
|
|
res = all_seeds[index if 0 <= index < len(all_seeds) else 0]
|
|
|
|
|
|
except json.decoder.JSONDecodeError:
|
|
|
- if gen_info_string != '':
|
|
|
- print("Error parsing JSON generation info:", file=sys.stderr)
|
|
|
- print(gen_info_string, file=sys.stderr)
|
|
|
+ if gen_info_string:
|
|
|
+ errors.report(f"Error parsing JSON generation info: {gen_info_string}")
|
|
|
|
|
|
return [res, gr_show(False)]
|
|
|
|
|
@@ -368,25 +372,6 @@ def apply_setting(key, value):
|
|
|
return getattr(opts, key)
|
|
|
|
|
|
|
|
|
-def create_refresh_button(refresh_component, refresh_method, refreshed_args, elem_id):
|
|
|
- def refresh():
|
|
|
- refresh_method()
|
|
|
- args = refreshed_args() if callable(refreshed_args) else refreshed_args
|
|
|
-
|
|
|
- for k, v in args.items():
|
|
|
- setattr(refresh_component, k, v)
|
|
|
-
|
|
|
- return gr.update(**(args or {}))
|
|
|
-
|
|
|
- refresh_button = ToolButton(value=refresh_symbol, elem_id=elem_id)
|
|
|
- refresh_button.click(
|
|
|
- fn=refresh,
|
|
|
- inputs=[],
|
|
|
- outputs=[refresh_component]
|
|
|
- )
|
|
|
- return refresh_button
|
|
|
-
|
|
|
-
|
|
|
def create_output_panel(tabname, outdir):
|
|
|
return ui_common.create_output_panel(tabname, outdir)
|
|
|
|
|
@@ -405,27 +390,17 @@ def create_sampler_and_steps_selection(choices, tabname):
|
|
|
|
|
|
|
|
|
def ordered_ui_categories():
|
|
|
- user_order = {x.strip(): i * 2 + 1 for i, x in enumerate(shared.opts.ui_reorder.split(","))}
|
|
|
+ user_order = {x.strip(): i * 2 + 1 for i, x in enumerate(shared.opts.ui_reorder_list)}
|
|
|
|
|
|
- for _, category in sorted(enumerate(shared.ui_reorder_categories), key=lambda x: user_order.get(x[1], x[0] * 2 + 0)):
|
|
|
+ for _, category in sorted(enumerate(shared_items.ui_reorder_categories()), key=lambda x: user_order.get(x[1], x[0] * 2 + 0)):
|
|
|
yield category
|
|
|
|
|
|
|
|
|
-def get_value_for_setting(key):
|
|
|
- value = getattr(opts, key)
|
|
|
-
|
|
|
- info = opts.data_labels[key]
|
|
|
- args = info.component_args() if callable(info.component_args) else info.component_args or {}
|
|
|
- args = {k: v for k, v in args.items() if k not in {'precision'}}
|
|
|
-
|
|
|
- return gr.update(value=value, **args)
|
|
|
-
|
|
|
-
|
|
|
def create_override_settings_dropdown(tabname, row):
|
|
|
dropdown = gr.Dropdown([], label="Override settings", visible=False, elem_id=f"{tabname}_override_settings", multiselect=True)
|
|
|
|
|
|
dropdown.change(
|
|
|
- fn=lambda x: gr.Dropdown.update(visible=len(x) > 0),
|
|
|
+ fn=lambda x: gr.Dropdown.update(visible=bool(x)),
|
|
|
inputs=[dropdown],
|
|
|
outputs=[dropdown],
|
|
|
)
|
|
@@ -456,6 +431,8 @@ def create_ui():
|
|
|
|
|
|
with gr.Row().style(equal_height=False):
|
|
|
with gr.Column(variant='compact', elem_id="txt2img_settings"):
|
|
|
+ modules.scripts.scripts_txt2img.prepare_ui()
|
|
|
+
|
|
|
for category in ordered_ui_categories():
|
|
|
if category == "sampler":
|
|
|
steps, sampler_index = create_sampler_and_steps_selection(samplers, "txt2img")
|
|
@@ -524,6 +501,9 @@ def create_ui():
|
|
|
with FormGroup(elem_id="txt2img_script_container"):
|
|
|
custom_inputs = modules.scripts.scripts_txt2img.setup_ui()
|
|
|
|
|
|
+ else:
|
|
|
+ modules.scripts.scripts_txt2img.setup_ui_for_section(category)
|
|
|
+
|
|
|
hr_resolution_preview_inputs = [enable_hr, width, height, hr_scale, hr_resize_x, hr_resize_y]
|
|
|
|
|
|
for component in hr_resolution_preview_inputs:
|
|
@@ -616,7 +596,8 @@ def create_ui():
|
|
|
outputs=[
|
|
|
txt2img_prompt,
|
|
|
txt_prompt_img
|
|
|
- ]
|
|
|
+ ],
|
|
|
+ show_progress=False,
|
|
|
)
|
|
|
|
|
|
enable_hr.change(
|
|
@@ -641,6 +622,7 @@ def create_ui():
|
|
|
(subseed_strength, "Variation seed strength"),
|
|
|
(seed_resize_from_w, "Seed resize from-1"),
|
|
|
(seed_resize_from_h, "Seed resize from-2"),
|
|
|
+ (txt2img_prompt_styles, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()),
|
|
|
(denoising_strength, "Denoising strength"),
|
|
|
(enable_hr, lambda d: "Denoising strength" in d),
|
|
|
(hr_options, lambda d: gr.Row.update(visible="Denoising strength" in d)),
|
|
@@ -779,6 +761,8 @@ def create_ui():
|
|
|
with FormRow():
|
|
|
resize_mode = gr.Radio(label="Resize mode", elem_id="resize_mode", choices=["Just resize", "Crop and resize", "Resize and fill", "Just resize (latent upscale)"], type="index", value="Just resize")
|
|
|
|
|
|
+ modules.scripts.scripts_img2img.prepare_ui()
|
|
|
+
|
|
|
for category in ordered_ui_categories():
|
|
|
if category == "sampler":
|
|
|
steps, sampler_index = create_sampler_and_steps_selection(samplers_for_img2img, "img2img")
|
|
@@ -789,7 +773,7 @@ def create_ui():
|
|
|
selected_scale_tab = gr.State(value=0)
|
|
|
|
|
|
with gr.Tabs():
|
|
|
- with gr.Tab(label="Resize to") as tab_scale_to:
|
|
|
+ with gr.Tab(label="Resize to", elem_id="img2img_tab_resize_to") as tab_scale_to:
|
|
|
with FormRow():
|
|
|
with gr.Column(elem_id="img2img_column_size", scale=4):
|
|
|
width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="img2img_width")
|
|
@@ -798,7 +782,7 @@ def create_ui():
|
|
|
res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="img2img_res_switch_btn")
|
|
|
detect_image_size_btn = ToolButton(value=detect_image_size_symbol, elem_id="img2img_detect_image_size_btn")
|
|
|
|
|
|
- with gr.Tab(label="Resize by") as tab_scale_by:
|
|
|
+ with gr.Tab(label="Resize by", elem_id="img2img_tab_resize_by") as tab_scale_by:
|
|
|
scale_by = gr.Slider(minimum=0.05, maximum=4.0, step=0.05, label="Scale", value=1.0, elem_id="img2img_scale")
|
|
|
|
|
|
with FormRow():
|
|
@@ -888,6 +872,8 @@ def create_ui():
|
|
|
inputs=[],
|
|
|
outputs=[inpaint_controls, mask_alpha],
|
|
|
)
|
|
|
+ else:
|
|
|
+ modules.scripts.scripts_img2img.setup_ui_for_section(category)
|
|
|
|
|
|
img2img_gallery, generation_info, html_info, html_log = create_output_panel("img2img", opts.outdir_img2img_samples)
|
|
|
|
|
@@ -902,7 +888,8 @@ def create_ui():
|
|
|
outputs=[
|
|
|
img2img_prompt,
|
|
|
img2img_prompt_img
|
|
|
- ]
|
|
|
+ ],
|
|
|
+ show_progress=False,
|
|
|
)
|
|
|
|
|
|
img2img_args = dict(
|
|
@@ -1051,6 +1038,7 @@ def create_ui():
|
|
|
(subseed_strength, "Variation seed strength"),
|
|
|
(seed_resize_from_w, "Seed resize from-1"),
|
|
|
(seed_resize_from_h, "Seed resize from-2"),
|
|
|
+ (img2img_prompt_styles, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()),
|
|
|
(denoising_strength, "Denoising strength"),
|
|
|
(mask_blur, "Mask blur"),
|
|
|
*modules.scripts.scripts_img2img.infotext_fields
|
|
@@ -1460,195 +1448,10 @@ def create_ui():
|
|
|
outputs=[],
|
|
|
)
|
|
|
|
|
|
- def create_setting_component(key, is_quicksettings=False):
|
|
|
- def fun():
|
|
|
- return opts.data[key] if key in opts.data else opts.data_labels[key].default
|
|
|
-
|
|
|
- info = opts.data_labels[key]
|
|
|
- t = type(info.default)
|
|
|
-
|
|
|
- args = info.component_args() if callable(info.component_args) else info.component_args
|
|
|
-
|
|
|
- if info.component is not None:
|
|
|
- comp = info.component
|
|
|
- elif t == str:
|
|
|
- comp = gr.Textbox
|
|
|
- elif t == int:
|
|
|
- comp = gr.Number
|
|
|
- elif t == bool:
|
|
|
- comp = gr.Checkbox
|
|
|
- else:
|
|
|
- raise Exception(f'bad options item type: {t} for key {key}')
|
|
|
-
|
|
|
- elem_id = f"setting_{key}"
|
|
|
-
|
|
|
- if info.refresh is not None:
|
|
|
- if is_quicksettings:
|
|
|
- res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
|
|
|
- create_refresh_button(res, info.refresh, info.component_args, f"refresh_{key}")
|
|
|
- else:
|
|
|
- with FormRow():
|
|
|
- res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
|
|
|
- create_refresh_button(res, info.refresh, info.component_args, f"refresh_{key}")
|
|
|
- else:
|
|
|
- res = comp(label=info.label, value=fun(), elem_id=elem_id, **(args or {}))
|
|
|
-
|
|
|
- return res
|
|
|
-
|
|
|
loadsave = ui_loadsave.UiLoadsave(cmd_opts.ui_config_file)
|
|
|
|
|
|
- components = []
|
|
|
- component_dict = {}
|
|
|
- shared.settings_components = component_dict
|
|
|
-
|
|
|
- script_callbacks.ui_settings_callback()
|
|
|
- opts.reorder()
|
|
|
-
|
|
|
- def run_settings(*args):
|
|
|
- changed = []
|
|
|
-
|
|
|
- for key, value, comp in zip(opts.data_labels.keys(), args, components):
|
|
|
- assert comp == dummy_component or opts.same_type(value, opts.data_labels[key].default), f"Bad value for setting {key}: {value}; expecting {type(opts.data_labels[key].default).__name__}"
|
|
|
-
|
|
|
- for key, value, comp in zip(opts.data_labels.keys(), args, components):
|
|
|
- if comp == dummy_component:
|
|
|
- continue
|
|
|
-
|
|
|
- if opts.set(key, value):
|
|
|
- changed.append(key)
|
|
|
-
|
|
|
- try:
|
|
|
- opts.save(shared.config_filename)
|
|
|
- except RuntimeError:
|
|
|
- return opts.dumpjson(), f'{len(changed)} settings changed without save: {", ".join(changed)}.'
|
|
|
- return opts.dumpjson(), f'{len(changed)} settings changed{": " if len(changed) > 0 else ""}{", ".join(changed)}.'
|
|
|
-
|
|
|
- def run_settings_single(value, key):
|
|
|
- if not opts.same_type(value, opts.data_labels[key].default):
|
|
|
- return gr.update(visible=True), opts.dumpjson()
|
|
|
-
|
|
|
- if not opts.set(key, value):
|
|
|
- return gr.update(value=getattr(opts, key)), opts.dumpjson()
|
|
|
-
|
|
|
- opts.save(shared.config_filename)
|
|
|
-
|
|
|
- return get_value_for_setting(key), opts.dumpjson()
|
|
|
-
|
|
|
- with gr.Blocks(analytics_enabled=False) as settings_interface:
|
|
|
- with gr.Row():
|
|
|
- with gr.Column(scale=6):
|
|
|
- settings_submit = gr.Button(value="Apply settings", variant='primary', elem_id="settings_submit")
|
|
|
- with gr.Column():
|
|
|
- restart_gradio = gr.Button(value='Reload UI', variant='primary', elem_id="settings_restart_gradio")
|
|
|
-
|
|
|
- result = gr.HTML(elem_id="settings_result")
|
|
|
-
|
|
|
- quicksettings_names = opts.quicksettings_list
|
|
|
- quicksettings_names = {x: i for i, x in enumerate(quicksettings_names) if x != 'quicksettings'}
|
|
|
-
|
|
|
- quicksettings_list = []
|
|
|
-
|
|
|
- previous_section = None
|
|
|
- current_tab = None
|
|
|
- current_row = None
|
|
|
- with gr.Tabs(elem_id="settings"):
|
|
|
- for i, (k, item) in enumerate(opts.data_labels.items()):
|
|
|
- section_must_be_skipped = item.section[0] is None
|
|
|
-
|
|
|
- if previous_section != item.section and not section_must_be_skipped:
|
|
|
- elem_id, text = item.section
|
|
|
-
|
|
|
- if current_tab is not None:
|
|
|
- current_row.__exit__()
|
|
|
- current_tab.__exit__()
|
|
|
-
|
|
|
- gr.Group()
|
|
|
- current_tab = gr.TabItem(elem_id=f"settings_{elem_id}", label=text)
|
|
|
- current_tab.__enter__()
|
|
|
- current_row = gr.Column(variant='compact')
|
|
|
- current_row.__enter__()
|
|
|
-
|
|
|
- previous_section = item.section
|
|
|
-
|
|
|
- if k in quicksettings_names and not shared.cmd_opts.freeze_settings:
|
|
|
- quicksettings_list.append((i, k, item))
|
|
|
- components.append(dummy_component)
|
|
|
- elif section_must_be_skipped:
|
|
|
- components.append(dummy_component)
|
|
|
- else:
|
|
|
- component = create_setting_component(k)
|
|
|
- component_dict[k] = component
|
|
|
- components.append(component)
|
|
|
-
|
|
|
- if current_tab is not None:
|
|
|
- current_row.__exit__()
|
|
|
- current_tab.__exit__()
|
|
|
-
|
|
|
- with gr.TabItem("Defaults", id="defaults", elem_id="settings_tab_defaults"):
|
|
|
- loadsave.create_ui()
|
|
|
-
|
|
|
- with gr.TabItem("Actions", id="actions", elem_id="settings_tab_actions"):
|
|
|
- request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications")
|
|
|
- download_localization = gr.Button(value='Download localization template', elem_id="download_localization")
|
|
|
- reload_script_bodies = gr.Button(value='Reload custom script bodies (No ui updates, No restart)', variant='secondary', elem_id="settings_reload_script_bodies")
|
|
|
- with gr.Row():
|
|
|
- unload_sd_model = gr.Button(value='Unload SD checkpoint to free VRAM', elem_id="sett_unload_sd_model")
|
|
|
- reload_sd_model = gr.Button(value='Reload the last SD checkpoint back into VRAM', elem_id="sett_reload_sd_model")
|
|
|
-
|
|
|
- with gr.TabItem("Licenses", id="licenses", elem_id="settings_tab_licenses"):
|
|
|
- gr.HTML(shared.html("licenses.html"), elem_id="licenses")
|
|
|
-
|
|
|
- gr.Button(value="Show all pages", elem_id="settings_show_all_pages")
|
|
|
-
|
|
|
-
|
|
|
- def unload_sd_weights():
|
|
|
- modules.sd_models.unload_model_weights()
|
|
|
-
|
|
|
- def reload_sd_weights():
|
|
|
- modules.sd_models.reload_model_weights()
|
|
|
-
|
|
|
- unload_sd_model.click(
|
|
|
- fn=unload_sd_weights,
|
|
|
- inputs=[],
|
|
|
- outputs=[]
|
|
|
- )
|
|
|
-
|
|
|
- reload_sd_model.click(
|
|
|
- fn=reload_sd_weights,
|
|
|
- inputs=[],
|
|
|
- outputs=[]
|
|
|
- )
|
|
|
-
|
|
|
- request_notifications.click(
|
|
|
- fn=lambda: None,
|
|
|
- inputs=[],
|
|
|
- outputs=[],
|
|
|
- _js='function(){}'
|
|
|
- )
|
|
|
-
|
|
|
- download_localization.click(
|
|
|
- fn=lambda: None,
|
|
|
- inputs=[],
|
|
|
- outputs=[],
|
|
|
- _js='download_localization'
|
|
|
- )
|
|
|
-
|
|
|
- def reload_scripts():
|
|
|
- modules.scripts.reload_script_body_only()
|
|
|
- reload_javascript() # need to refresh the html page
|
|
|
-
|
|
|
- reload_script_bodies.click(
|
|
|
- fn=reload_scripts,
|
|
|
- inputs=[],
|
|
|
- outputs=[]
|
|
|
- )
|
|
|
-
|
|
|
- restart_gradio.click(
|
|
|
- fn=shared.state.request_restart,
|
|
|
- _js='restart_reload',
|
|
|
- inputs=[],
|
|
|
- outputs=[],
|
|
|
- )
|
|
|
+ settings = ui_settings.UiSettings()
|
|
|
+ settings.create_ui(loadsave, dummy_component)
|
|
|
|
|
|
interfaces = [
|
|
|
(txt2img_interface, "txt2img", "txt2img"),
|
|
@@ -1660,7 +1463,7 @@ def create_ui():
|
|
|
]
|
|
|
|
|
|
interfaces += script_callbacks.ui_tabs_callback()
|
|
|
- interfaces += [(settings_interface, "Settings", "settings")]
|
|
|
+ interfaces += [(settings.interface, "Settings", "settings")]
|
|
|
|
|
|
extensions_interface = ui_extensions.create_ui()
|
|
|
interfaces += [(extensions_interface, "Extensions", "extensions")]
|
|
@@ -1670,10 +1473,7 @@ def create_ui():
|
|
|
shared.tab_names.append(label)
|
|
|
|
|
|
with gr.Blocks(theme=shared.gradio_theme, analytics_enabled=False, title="Stable Diffusion") as demo:
|
|
|
- with gr.Row(elem_id="quicksettings", variant="compact"):
|
|
|
- for _i, k, _item in sorted(quicksettings_list, key=lambda x: quicksettings_names.get(x[1], x[0])):
|
|
|
- component = create_setting_component(k, is_quicksettings=True)
|
|
|
- component_dict[k] = component
|
|
|
+ settings.add_quicksettings()
|
|
|
|
|
|
parameters_copypaste.connect_paste_params_buttons()
|
|
|
|
|
@@ -1701,58 +1501,20 @@ def create_ui():
|
|
|
gr.Audio(interactive=False, value=os.path.join(script_path, "notification.mp3"), elem_id="audio_notification", visible=False)
|
|
|
|
|
|
footer = shared.html("footer.html")
|
|
|
- footer = footer.format(versions=versions_html())
|
|
|
+ footer = footer.format(versions=versions_html(), api_docs="/docs" if shared.cmd_opts.api else "https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/API")
|
|
|
gr.HTML(footer, elem_id="footer")
|
|
|
|
|
|
- text_settings = gr.Textbox(elem_id="settings_json", value=lambda: opts.dumpjson(), visible=False)
|
|
|
- settings_submit.click(
|
|
|
- fn=wrap_gradio_call(run_settings, extra_outputs=[gr.update()]),
|
|
|
- inputs=components,
|
|
|
- outputs=[text_settings, result],
|
|
|
- )
|
|
|
-
|
|
|
- for _i, k, _item in quicksettings_list:
|
|
|
- component = component_dict[k]
|
|
|
- info = opts.data_labels[k]
|
|
|
-
|
|
|
- change_handler = component.release if hasattr(component, 'release') else component.change
|
|
|
- change_handler(
|
|
|
- fn=lambda value, k=k: run_settings_single(value, key=k),
|
|
|
- inputs=[component],
|
|
|
- outputs=[component, text_settings],
|
|
|
- show_progress=info.refresh is not None,
|
|
|
- )
|
|
|
+ settings.add_functionality(demo)
|
|
|
|
|
|
update_image_cfg_scale_visibility = lambda: gr.update(visible=shared.sd_model and shared.sd_model.cond_stage_key == "edit")
|
|
|
- text_settings.change(fn=update_image_cfg_scale_visibility, inputs=[], outputs=[image_cfg_scale])
|
|
|
+ settings.text_settings.change(fn=update_image_cfg_scale_visibility, inputs=[], outputs=[image_cfg_scale])
|
|
|
demo.load(fn=update_image_cfg_scale_visibility, inputs=[], outputs=[image_cfg_scale])
|
|
|
|
|
|
- button_set_checkpoint = gr.Button('Change checkpoint', elem_id='change_checkpoint', visible=False)
|
|
|
- button_set_checkpoint.click(
|
|
|
- fn=lambda value, _: run_settings_single(value, key='sd_model_checkpoint'),
|
|
|
- _js="function(v){ var res = desiredCheckpointName; desiredCheckpointName = ''; return [res || v, null]; }",
|
|
|
- inputs=[component_dict['sd_model_checkpoint'], dummy_component],
|
|
|
- outputs=[component_dict['sd_model_checkpoint'], text_settings],
|
|
|
- )
|
|
|
-
|
|
|
- component_keys = [k for k in opts.data_labels.keys() if k in component_dict]
|
|
|
-
|
|
|
- def get_settings_values():
|
|
|
- return [get_value_for_setting(key) for key in component_keys]
|
|
|
-
|
|
|
- demo.load(
|
|
|
- fn=get_settings_values,
|
|
|
- inputs=[],
|
|
|
- outputs=[component_dict[k] for k in component_keys],
|
|
|
- queue=False,
|
|
|
- )
|
|
|
-
|
|
|
def modelmerger(*args):
|
|
|
try:
|
|
|
results = modules.extras.run_modelmerger(*args)
|
|
|
except Exception as e:
|
|
|
- print("Error loading/saving model file:", file=sys.stderr)
|
|
|
- print(traceback.format_exc(), file=sys.stderr)
|
|
|
+ errors.report("Error loading/saving model file", exc_info=True)
|
|
|
modules.sd_models.list_models() # to remove the potentially missing models from the list
|
|
|
return [*[gr.Dropdown.update(choices=modules.sd_models.checkpoint_tiles()) for _ in range(4)], f"Error merging checkpoints: {e}"]
|
|
|
return results
|
|
@@ -1780,7 +1542,7 @@ def create_ui():
|
|
|
primary_model_name,
|
|
|
secondary_model_name,
|
|
|
tertiary_model_name,
|
|
|
- component_dict['sd_model_checkpoint'],
|
|
|
+ settings.component_dict['sd_model_checkpoint'],
|
|
|
modelmerger_result,
|
|
|
]
|
|
|
)
|
|
@@ -1794,70 +1556,6 @@ def create_ui():
|
|
|
return demo
|
|
|
|
|
|
|
|
|
-def webpath(fn):
|
|
|
- if fn.startswith(script_path):
|
|
|
- web_path = os.path.relpath(fn, script_path).replace('\\', '/')
|
|
|
- else:
|
|
|
- web_path = os.path.abspath(fn)
|
|
|
-
|
|
|
- return f'file={web_path}?{os.path.getmtime(fn)}'
|
|
|
-
|
|
|
-
|
|
|
-def javascript_html():
|
|
|
- # Ensure localization is in `window` before scripts
|
|
|
- head = f'<script type="text/javascript">{localization.localization_js(shared.opts.localization)}</script>\n'
|
|
|
-
|
|
|
- script_js = os.path.join(script_path, "script.js")
|
|
|
- head += f'<script type="text/javascript" src="{webpath(script_js)}"></script>\n'
|
|
|
-
|
|
|
- for script in modules.scripts.list_scripts("javascript", ".js"):
|
|
|
- head += f'<script type="text/javascript" src="{webpath(script.path)}"></script>\n'
|
|
|
-
|
|
|
- for script in modules.scripts.list_scripts("javascript", ".mjs"):
|
|
|
- head += f'<script type="module" src="{webpath(script.path)}"></script>\n'
|
|
|
-
|
|
|
- if cmd_opts.theme:
|
|
|
- head += f'<script type="text/javascript">set_theme(\"{cmd_opts.theme}\");</script>\n'
|
|
|
-
|
|
|
- return head
|
|
|
-
|
|
|
-
|
|
|
-def css_html():
|
|
|
- head = ""
|
|
|
-
|
|
|
- def stylesheet(fn):
|
|
|
- return f'<link rel="stylesheet" property="stylesheet" href="{webpath(fn)}">'
|
|
|
-
|
|
|
- for cssfile in modules.scripts.list_files_with_name("style.css"):
|
|
|
- if not os.path.isfile(cssfile):
|
|
|
- continue
|
|
|
-
|
|
|
- head += stylesheet(cssfile)
|
|
|
-
|
|
|
- if os.path.exists(os.path.join(data_path, "user.css")):
|
|
|
- head += stylesheet(os.path.join(data_path, "user.css"))
|
|
|
-
|
|
|
- return head
|
|
|
-
|
|
|
-
|
|
|
-def reload_javascript():
|
|
|
- js = javascript_html()
|
|
|
- css = css_html()
|
|
|
-
|
|
|
- def template_response(*args, **kwargs):
|
|
|
- res = shared.GradioTemplateResponseOriginal(*args, **kwargs)
|
|
|
- res.body = res.body.replace(b'</head>', f'{js}</head>'.encode("utf8"))
|
|
|
- res.body = res.body.replace(b'</body>', f'{css}</body>'.encode("utf8"))
|
|
|
- res.init_headers()
|
|
|
- return res
|
|
|
-
|
|
|
- gradio.routes.templates.TemplateResponse = template_response
|
|
|
-
|
|
|
-
|
|
|
-if not hasattr(shared, 'GradioTemplateResponseOriginal'):
|
|
|
- shared.GradioTemplateResponseOriginal = gradio.routes.templates.TemplateResponse
|
|
|
-
|
|
|
-
|
|
|
def versions_html():
|
|
|
import torch
|
|
|
import launch
|
|
@@ -1901,3 +1599,17 @@ def setup_ui_api(app):
|
|
|
app.add_api_route("/internal/quicksettings-hint", quicksettings_hint, methods=["GET"], response_model=List[QuicksettingsHint])
|
|
|
|
|
|
app.add_api_route("/internal/ping", lambda: {}, methods=["GET"])
|
|
|
+
|
|
|
+ app.add_api_route("/internal/profile-startup", lambda: timer.startup_record, methods=["GET"])
|
|
|
+
|
|
|
+ def download_sysinfo(attachment=False):
|
|
|
+ from fastapi.responses import PlainTextResponse
|
|
|
+
|
|
|
+ text = sysinfo.get()
|
|
|
+ filename = f"sysinfo-{datetime.datetime.utcnow().strftime('%Y-%m-%d-%H-%M')}.txt"
|
|
|
+
|
|
|
+ return PlainTextResponse(text, headers={'Content-Disposition': f'{"attachment" if attachment else "inline"}; filename="{filename}"'})
|
|
|
+
|
|
|
+ app.add_api_route("/internal/sysinfo", download_sysinfo, methods=["GET"])
|
|
|
+ app.add_api_route("/internal/sysinfo-download", lambda: download_sysinfo(attachment=True), methods=["GET"])
|
|
|
+
|