diff --git a/.github/workflows/on_pull_request.yaml b/.github/workflows/on_pull_request.yaml index 9ccbf72df..011fe9b2d 100644 --- a/.github/workflows/on_pull_request.yaml +++ b/.github/workflows/on_pull_request.yaml @@ -23,7 +23,7 @@ jobs: with: python-version: 3.10.6 cache: pip - cache-dependency-path: requirements*txt + cache-dependency-path: requirements.txt - name: Install PyLint run: | python -m pip install --upgrade pip diff --git a/.gitignore b/.gitignore index 030447846..810d1f84d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __pycache__ /setup.log /style.csv /user.css +/javascript/themes.json venv # all models and temp files diff --git a/README.md b/README.md index f15100d9b..a9526413e 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ If you are looking an amazing simple-to-use Stable Diffusion tool, I'd suggest [
-![screenshot](ui-screenshot.jpg) +![screenshot](javscript/black-orange.jpg)
diff --git a/extensions-builtin/sd-extension-system-info b/extensions-builtin/sd-extension-system-info index 44b70636c..cfe15a75a 160000 --- a/extensions-builtin/sd-extension-system-info +++ b/extensions-builtin/sd-extension-system-info @@ -1 +1 @@ -Subproject commit 44b70636c194c5bf6a1a7b23e0b4c6f1bcdc8d7c +Subproject commit cfe15a75ab1654880d6d3726c12fd3e3286c0a5a diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index 0c7998ab0..1dc09b161 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit 0c7998ab05101bcb1ac426e41e11dda5f7e7d8a1 +Subproject commit 1dc09b161abc15aeacc7b7cd0933d073aa7476b5 diff --git a/ui-screenshot.jpg b/javascript/black-orange.jpg similarity index 100% rename from ui-screenshot.jpg rename to javascript/black-orange.jpg diff --git a/javascript/gradio-default.jpg b/javascript/gradio-default.jpg new file mode 100644 index 000000000..bb9097be4 Binary files /dev/null and b/javascript/gradio-default.jpg differ diff --git a/javascript/ui.js b/javascript/ui.js index 61f75762e..654e6a435 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -367,3 +367,31 @@ function selectCheckpoint(name){ desiredCheckpointName = name; gradioApp().getElementById('change_checkpoint').click() } + +function create_theme_element() { + el = document.createElement('img'); + el.id = 'theme-preview'; + el.className = 'theme-preview'; + el.onclick = () => el.style.display = 'none'; + document.body.appendChild(el); + return el; +} + +function preview_theme() { + const name = gradioApp().getElementById('setting_gradio_theme').querySelectorAll('span')[1].innerText; // ugly but we want current value without the need to set apply + console.log('PREVIEW', name); + if (name === 'black-orange' || name === 'gradio/default') { + el = document.getElementById('theme-preview') || create_theme_element(); + el.style.display = el.style.display === 'block' ? 'none' : 'block'; + if (name === 'black-orange') el.src = '/file=javascript/black-orange.jpg'; + else el.src = '/file=javascript/gradio-default.jpg'; + } else { + fetch('/file=javascript/themes.json') + .then((r) => r.json()) + .then(themes => { + theme = themes.find((t)=> t.id === name); + console.log('FOUND', theme); + window.open(theme.subdomain, '_blank'); + }); + } +} diff --git a/modules/script_loading.py b/modules/script_loading.py index 979844125..d5b809492 100644 --- a/modules/script_loading.py +++ b/modules/script_loading.py @@ -6,8 +6,10 @@ import modules.errors as errors def load_module(path): module_spec = importlib.util.spec_from_file_location(os.path.basename(path), path) module = importlib.util.module_from_spec(module_spec) - module_spec.loader.exec_module(module) - + try: + module_spec.loader.exec_module(module) + except Exception as e: + errors.display(e, f'Module load: {path}') return module @@ -26,4 +28,4 @@ def preload_extensions(extensions_dir, parser): module.preload(parser) except Exception as e: - errors.display(e, f'extension preload: {preload_script}') + errors.display(e, f'Extension preload: {preload_script}') diff --git a/modules/shared.py b/modules/shared.py index f118fd0ba..c8353b6d9 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -55,20 +55,6 @@ ui_reorder_categories = [ "scripts", ] -# https://huggingface.co/datasets/freddyaboulton/gradio-theme-subdomains/resolve/main/subdomains.json -gradio_hf_hub_themes = [ - "gradio/glass", - "gradio/monochrome", - "gradio/seafoam", - "gradio/soft", - "freddyaboulton/dracula_revamped", - "gradio/dracula_test", - "abidlabs/dracula_test", - "abidlabs/pakistan", - "dawood/microsoft_windows", - "ysharma/steampunk" -] - cmd_opts.disable_extension_access = (cmd_opts.share or cmd_opts.listen or cmd_opts.server_name) and not cmd_opts.enable_insecure devices.device, devices.device_interrogate, devices.device_gfpgan, devices.device_esrgan, devices.device_codeformer = \ @@ -222,6 +208,26 @@ def list_samplers(): import modules.sd_samplers # pylint: disable=W0621 return modules.sd_samplers.all_samplers +def list_themes(): + if not os.path.exists(os.path.join('javascript', 'themes.json')): + refresh_themes() + with open(os.path.join('javascript', 'themes.json'), mode='r', encoding='utf=8') as f: + res = json.loads(f.read()) + themes = [x['id'] for x in res if x['status'] == 'RUNNING' and 'test' not in x['id'].lower()] + return themes + +def refresh_themes(): + import requests + try: + req = requests.get('https://huggingface.co/datasets/freddyaboulton/gradio-theme-subdomains/resolve/main/subdomains.json', timeout=5) + if req.status_code == 200: + res = req.json() + with open(os.path.join('javascript', 'themes.json'), mode='w', encoding='utf=8') as f: + f.write(json.dumps(res)) + else: + print('Error refreshing UI themes') + except: + print('Exception refreshing UI themes') hide_dirs = {"visible": not cmd_opts.hide_ui_dir_config} tab_names = [] @@ -378,6 +384,7 @@ options_templates.update(options_section(('extra_networks', "Extra Networks"), { })) options_templates.update(options_section(('ui', "User interface"), { + "gradio_theme": OptionInfo("black-orange", "UI theme", gr.Dropdown, lambda: {"choices": ["black-orange", "gradio/default"] + list_themes()}, refresh=refresh_themes), "return_grid": OptionInfo(True, "Show grid in results for web"), "return_mask": OptionInfo(False, "For inpainting, include the greyscale mask in results for web"), "return_mask_composite": OptionInfo(False, "For inpainting, include masked composite in results for web"), @@ -397,7 +404,6 @@ options_templates.update(options_section(('ui', "User interface"), { "hidden_tabs": OptionInfo([], "Hidden UI tabs", ui_components.DropdownMulti, lambda: {"choices": [x for x in tab_names]}), "ui_reorder": OptionInfo(", ".join(ui_reorder_categories), "txt2img/img2img UI item order"), "ui_extra_networks_tab_reorder": OptionInfo("", "Extra networks tab order"), - "gradio_theme": OptionInfo("black-orange", "UI theme", gr.Dropdown, lambda: {"choices": ["black-orange", "gradio/default"] + gradio_hf_hub_themes}), })) options_templates.update(options_section(('ui', "Live previews"), { @@ -603,7 +609,7 @@ if os.path.exists(config_filename): cmd_opts = cmd_args.compatibility_args(opts, cmd_opts) settings_components = None -"""assinged from ui.py, a mapping on setting anmes to gradio components repsponsible for those settings""" +"""assinged from ui.py, a mapping on setting names to gradio components repsponsible for those settings""" latent_upscale_default_mode = "Latent" latent_upscale_modes = { diff --git a/modules/ui.py b/modules/ui.py index 75b669043..f01627806 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -203,7 +203,7 @@ def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: all_seeds = gen_info.get('all_seeds', [-1]) res = all_seeds[index if 0 <= index < len(all_seeds) else 0] - except json.decoder.JSONDecodeError as e: + except json.decoder.JSONDecodeError: if gen_info_string != '': print("Error parsing JSON generation info:", file=sys.stderr) print(gen_info_string, file=sys.stderr) @@ -1389,37 +1389,33 @@ def create_ui(): with gr.Row(): settings_submit = gr.Button(value="Apply settings", variant='primary', elem_id="settings_submit") restart_submit = gr.Button(value="Restart UI", variant='primary', elem_id="restart_submit") - + preview_theme = gr.Button(value="Preview theme", variant='primary', elem_id="settings_preview_theme") + unload_sd_model = gr.Button(value='Unload checkpoint', variant='primary', elem_id="sett_unload_sd_model") + reload_sd_model = gr.Button(value='Reload checkpoint', variant='primary', elem_id="sett_reload_sd_model") + reload_script_bodies = gr.Button(value='Reload scripts', variant='primary', elem_id="settings_reload_script_bodies") result = gr.HTML(elem_id="settings_result") quicksettings_names = [x.strip() for x in opts.quicksettings.split(",")] 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="settings_{}".format(elem_id), label=text) + 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) @@ -1429,23 +1425,15 @@ def create_ui(): 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("Actions"): - request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications") - 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") - + request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications", visible=False) + show_all_pages = gr.Button(value="Show all pages", variant='primary', elem_id="settings_show_all_pages") with gr.TabItem("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() @@ -1481,6 +1469,13 @@ def create_ui(): outputs=[] ) + preview_theme.click( + fn=None, + _js='preview_theme', + inputs=[dummy_component], + outputs=[dummy_component] + ) + interfaces = [ (txt2img_interface, "From Text", "txt2img"), diff --git a/setup.py b/setup.py index e826d745b..d039ce28e 100644 --- a/setup.py +++ b/setup.py @@ -155,7 +155,7 @@ def clone(url, folder, commithash=None): # check python version def check_python(): import platform - supported_minors = [10] if platform.system() != "Windows" else [9, 10, 11] + supported_minors = [9, 10] if platform.system() != "Windows" else [9, 10, 11] log.info(f'Python {platform.python_version()} on {platform.system()}') if not (int(sys.version_info.major) == 3 and int(sys.version_info.minor) in supported_minors): raise RuntimeError(f"Incompatible Python version: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro} required 3.9-3.11") diff --git a/style.css b/style.css index de16a7f2f..a9457210c 100644 --- a/style.css +++ b/style.css @@ -830,3 +830,17 @@ footer { .extra-network-cards .card ul a:hover{ color: red; } + +.theme-preview { + display: none; + position: fixed; + border: 4px solid var(--neutral-600); + box-shadow: 2px 2px 2px 2px var(--neutral-700); + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + max-width: 75vw; + z-index: 999; +} diff --git a/webui.sh b/webui.sh index 59013f3dd..56b7396b2 100755 --- a/webui.sh +++ b/webui.sh @@ -118,7 +118,7 @@ case "$gpu_info" in esac if echo "$gpu_info" | grep -q "AMD" && [[ -z "${TORCH_COMMAND}" ]] then - export TORCH_COMMAND="pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/rocm5.2" + export TORCH_COMMAND="torch torchvision --extra-index-url https://download.pytorch.org/whl/rocm5.2" fi for preq in "${GIT}" "${python_cmd}"