mirror of
				https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
				synced 2025-10-31 10:03:40 +00:00 
			
		
		
		
	 df02498d03
			
		
	
	
		df02498d03
		
	
	
	
	
		
			
			split some code from ui.py into ui_settings.py ui_gradio_edxtensions.py add before_process callback for scripts add ability for alwayson scripts to specify section and let user reorder those sections
		
			
				
	
	
		
			242 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import json
 | |
| import html
 | |
| import os
 | |
| import platform
 | |
| import sys
 | |
| 
 | |
| import gradio as gr
 | |
| import subprocess as sp
 | |
| 
 | |
| from modules import call_queue, shared
 | |
| from modules.generation_parameters_copypaste import image_from_url_text
 | |
| import modules.images
 | |
| from modules.ui_components import ToolButton
 | |
| 
 | |
| 
 | |
| folder_symbol = '\U0001f4c2'  # 📂
 | |
| refresh_symbol = '\U0001f504'  # 🔄
 | |
| 
 | |
| 
 | |
| def update_generation_info(generation_info, html_info, img_index):
 | |
|     try:
 | |
|         generation_info = json.loads(generation_info)
 | |
|         if img_index < 0 or img_index >= len(generation_info["infotexts"]):
 | |
|             return html_info, gr.update()
 | |
|         return plaintext_to_html(generation_info["infotexts"][img_index]), gr.update()
 | |
|     except Exception:
 | |
|         pass
 | |
|     # if the json parse or anything else fails, just return the old html_info
 | |
|     return html_info, gr.update()
 | |
| 
 | |
| 
 | |
| def plaintext_to_html(text):
 | |
|     text = "<p>" + "<br>\n".join([f"{html.escape(x)}" for x in text.split('\n')]) + "</p>"
 | |
|     return text
 | |
| 
 | |
| 
 | |
| def save_files(js_data, images, do_make_zip, index):
 | |
|     import csv
 | |
|     filenames = []
 | |
|     fullfns = []
 | |
| 
 | |
|     #quick dictionary to class object conversion. Its necessary due apply_filename_pattern requiring it
 | |
|     class MyObject:
 | |
|         def __init__(self, d=None):
 | |
|             if d is not None:
 | |
|                 for key, value in d.items():
 | |
|                     setattr(self, key, value)
 | |
| 
 | |
|     data = json.loads(js_data)
 | |
| 
 | |
|     p = MyObject(data)
 | |
|     path = shared.opts.outdir_save
 | |
|     save_to_dirs = shared.opts.use_save_to_dirs_for_ui
 | |
|     extension: str = shared.opts.samples_format
 | |
|     start_index = 0
 | |
|     only_one = False
 | |
| 
 | |
|     if index > -1 and shared.opts.save_selected_only and (index >= data["index_of_first_image"]):  # ensures we are looking at a specific non-grid picture, and we have save_selected_only
 | |
|         only_one = True
 | |
|         images = [images[index]]
 | |
|         start_index = index
 | |
| 
 | |
|     os.makedirs(shared.opts.outdir_save, exist_ok=True)
 | |
| 
 | |
|     with open(os.path.join(shared.opts.outdir_save, "log.csv"), "a", encoding="utf8", newline='') as file:
 | |
|         at_start = file.tell() == 0
 | |
|         writer = csv.writer(file)
 | |
|         if at_start:
 | |
|             writer.writerow(["prompt", "seed", "width", "height", "sampler", "cfgs", "steps", "filename", "negative_prompt"])
 | |
| 
 | |
|         for image_index, filedata in enumerate(images, start_index):
 | |
|             image = image_from_url_text(filedata)
 | |
| 
 | |
|             is_grid = image_index < p.index_of_first_image
 | |
|             i = 0 if is_grid else (image_index - p.index_of_first_image)
 | |
| 
 | |
|             p.batch_index = image_index-1
 | |
|             fullfn, txt_fullfn = modules.images.save_image(image, path, "", seed=p.all_seeds[i], prompt=p.all_prompts[i], extension=extension, info=p.infotexts[image_index], grid=is_grid, p=p, save_to_dirs=save_to_dirs)
 | |
| 
 | |
|             filename = os.path.relpath(fullfn, path)
 | |
|             filenames.append(filename)
 | |
|             fullfns.append(fullfn)
 | |
|             if txt_fullfn:
 | |
|                 filenames.append(os.path.basename(txt_fullfn))
 | |
|                 fullfns.append(txt_fullfn)
 | |
| 
 | |
|         writer.writerow([data["prompt"], data["seed"], data["width"], data["height"], data["sampler_name"], data["cfg_scale"], data["steps"], filenames[0], data["negative_prompt"]])
 | |
| 
 | |
|     # Make Zip
 | |
|     if do_make_zip:
 | |
|         zip_fileseed = p.all_seeds[index-1] if only_one else p.all_seeds[0]
 | |
|         namegen = modules.images.FilenameGenerator(p, zip_fileseed, p.all_prompts[0], image, True)
 | |
|         zip_filename = namegen.apply(shared.opts.grid_zip_filename_pattern or "[datetime]_[[model_name]]_[seed]-[seed_last]")
 | |
|         zip_filepath = os.path.join(path, f"{zip_filename}.zip")
 | |
| 
 | |
|         from zipfile import ZipFile
 | |
|         with ZipFile(zip_filepath, "w") as zip_file:
 | |
|             for i in range(len(fullfns)):
 | |
|                 with open(fullfns[i], mode="rb") as f:
 | |
|                     zip_file.writestr(filenames[i], f.read())
 | |
|         fullfns.insert(0, zip_filepath)
 | |
| 
 | |
|     return gr.File.update(value=fullfns, visible=True), plaintext_to_html(f"Saved: {filenames[0]}")
 | |
| 
 | |
| 
 | |
| def create_output_panel(tabname, outdir):
 | |
|     from modules import shared
 | |
|     import modules.generation_parameters_copypaste as parameters_copypaste
 | |
| 
 | |
|     def open_folder(f):
 | |
|         if not os.path.exists(f):
 | |
|             print(f'Folder "{f}" does not exist. After you create an image, the folder will be created.')
 | |
|             return
 | |
|         elif not os.path.isdir(f):
 | |
|             print(f"""
 | |
| WARNING
 | |
| An open_folder request was made with an argument that is not a folder.
 | |
| This could be an error or a malicious attempt to run code on your computer.
 | |
| Requested path was: {f}
 | |
| """, file=sys.stderr)
 | |
|             return
 | |
| 
 | |
|         if not shared.cmd_opts.hide_ui_dir_config:
 | |
|             path = os.path.normpath(f)
 | |
|             if platform.system() == "Windows":
 | |
|                 os.startfile(path)
 | |
|             elif platform.system() == "Darwin":
 | |
|                 sp.Popen(["open", path])
 | |
|             elif "microsoft-standard-WSL2" in platform.uname().release:
 | |
|                 sp.Popen(["wsl-open", path])
 | |
|             else:
 | |
|                 sp.Popen(["xdg-open", path])
 | |
| 
 | |
|     with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
 | |
|         with gr.Group(elem_id=f"{tabname}_gallery_container"):
 | |
|             result_gallery = gr.Gallery(label='Output', show_label=False, elem_id=f"{tabname}_gallery").style(columns=4)
 | |
| 
 | |
|         generation_info = None
 | |
|         with gr.Column():
 | |
|             with gr.Row(elem_id=f"image_buttons_{tabname}", elem_classes="image-buttons"):
 | |
|                 open_folder_button = gr.Button(folder_symbol, visible=not shared.cmd_opts.hide_ui_dir_config)
 | |
| 
 | |
|                 if tabname != "extras":
 | |
|                     save = gr.Button('Save', elem_id=f'save_{tabname}')
 | |
|                     save_zip = gr.Button('Zip', elem_id=f'save_zip_{tabname}')
 | |
| 
 | |
|                 buttons = parameters_copypaste.create_buttons(["img2img", "inpaint", "extras"])
 | |
| 
 | |
|             open_folder_button.click(
 | |
|                 fn=lambda: open_folder(shared.opts.outdir_samples or outdir),
 | |
|                 inputs=[],
 | |
|                 outputs=[],
 | |
|             )
 | |
| 
 | |
|             if tabname != "extras":
 | |
|                 download_files = gr.File(None, file_count="multiple", interactive=False, show_label=False, visible=False, elem_id=f'download_files_{tabname}')
 | |
| 
 | |
|                 with gr.Group():
 | |
|                     html_info = gr.HTML(elem_id=f'html_info_{tabname}', elem_classes="infotext")
 | |
|                     html_log = gr.HTML(elem_id=f'html_log_{tabname}')
 | |
| 
 | |
|                     generation_info = gr.Textbox(visible=False, elem_id=f'generation_info_{tabname}')
 | |
|                     if tabname == 'txt2img' or tabname == 'img2img':
 | |
|                         generation_info_button = gr.Button(visible=False, elem_id=f"{tabname}_generation_info_button")
 | |
|                         generation_info_button.click(
 | |
|                             fn=update_generation_info,
 | |
|                             _js="function(x, y, z){ return [x, y, selected_gallery_index()] }",
 | |
|                             inputs=[generation_info, html_info, html_info],
 | |
|                             outputs=[html_info, html_info],
 | |
|                             show_progress=False,
 | |
|                         )
 | |
| 
 | |
|                     save.click(
 | |
|                         fn=call_queue.wrap_gradio_call(save_files),
 | |
|                         _js="(x, y, z, w) => [x, y, false, selected_gallery_index()]",
 | |
|                         inputs=[
 | |
|                             generation_info,
 | |
|                             result_gallery,
 | |
|                             html_info,
 | |
|                             html_info,
 | |
|                         ],
 | |
|                         outputs=[
 | |
|                             download_files,
 | |
|                             html_log,
 | |
|                         ],
 | |
|                         show_progress=False,
 | |
|                     )
 | |
| 
 | |
|                     save_zip.click(
 | |
|                         fn=call_queue.wrap_gradio_call(save_files),
 | |
|                         _js="(x, y, z, w) => [x, y, true, selected_gallery_index()]",
 | |
|                         inputs=[
 | |
|                             generation_info,
 | |
|                             result_gallery,
 | |
|                             html_info,
 | |
|                             html_info,
 | |
|                         ],
 | |
|                         outputs=[
 | |
|                             download_files,
 | |
|                             html_log,
 | |
|                         ]
 | |
|                     )
 | |
| 
 | |
|             else:
 | |
|                 html_info_x = gr.HTML(elem_id=f'html_info_x_{tabname}')
 | |
|                 html_info = gr.HTML(elem_id=f'html_info_{tabname}', elem_classes="infotext")
 | |
|                 html_log = gr.HTML(elem_id=f'html_log_{tabname}')
 | |
| 
 | |
|             paste_field_names = []
 | |
|             if tabname == "txt2img":
 | |
|                 paste_field_names = modules.scripts.scripts_txt2img.paste_field_names
 | |
|             elif tabname == "img2img":
 | |
|                 paste_field_names = modules.scripts.scripts_img2img.paste_field_names
 | |
| 
 | |
|             for paste_tabname, paste_button in buttons.items():
 | |
|                 parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(
 | |
|                     paste_button=paste_button, tabname=paste_tabname, source_tabname="txt2img" if tabname == "txt2img" else None, source_image_component=result_gallery,
 | |
|                     paste_field_names=paste_field_names
 | |
|                 ))
 | |
| 
 | |
|             return result_gallery, generation_info if tabname != "extras" else html_info_x, html_info, html_log
 | |
| 
 | |
| 
 | |
| 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
 | |
| 
 |