fix folder enum and refactor control ipadapter

This commit is contained in:
Vladimir Mandic
2024-01-07 16:06:03 -05:00
parent 119424399f
commit d2940a05d1
21 changed files with 237 additions and 309 deletions
+60 -61
View File
@@ -11,6 +11,7 @@ from installer import log
AlwaysVisible = object()
time_component = {}
time_setup = {}
debug = log.trace if os.environ.get('SD_SCRIPT_DEBUG', None) is not None else lambda *args, **kwargs: None
class PostprocessImageArgs:
@@ -24,6 +25,7 @@ class PostprocessBatchListArgs:
class Script:
parent = None
name = None
filename = None
args_from = None
@@ -172,11 +174,8 @@ class Script:
def elem_id(self, item_id):
"""helper function to generate id for a HTML element, constructs final id out of script name, tab and user-supplied item_id"""
need_tabname = self.show(True) == self.show(False)
tabkind = 'img2img' if self.is_img2img else 'txt2txt'
tabname = f"{tabkind}_" if need_tabname else ""
title = re.sub(r'[^a-z_0-9]', '', re.sub(r'\s', '_', self.title().lower()))
return f'script_{tabname}{title}_{item_id}'
return f'script_{self.parent}_{title}_{item_id}'
current_basedir = paths.script_path
@@ -224,7 +223,7 @@ def list_scripts(scriptdirname, extension):
else:
priority = priority + script.priority
priority_list.append(ScriptFile(script.basedir, script.filename, script.path, priority))
# log.debug(f'Adding script: {script.basedir} {script.filename} {script.path} {priority}')
debug(f'Adding script: {script.basedir} {script.filename} {script.path} {priority}')
priority_sort = sorted(priority_list, key=lambda item: item.priority + item.path.lower(), reverse=False)
return priority_sort
@@ -255,7 +254,7 @@ def load_scripts():
for script_class in module.__dict__.values():
if type(script_class) != type:
continue
# log.debug(f'Registering script: {scriptfile.path}')
debug(f'Registering script: {scriptfile.path}')
if issubclass(script_class, Script):
scripts_data.append(ScriptClassData(script_class, scriptfile.path, scriptfile.basedir, module))
elif issubclass(script_class, scripts_postprocessing.ScriptPostprocessing):
@@ -356,7 +355,7 @@ class ScriptRunner:
log.error(f'Script initialize: {path} {e}')
"""
def create_script_ui(self, script): # TODO this is legacy implementation
def create_script_ui(self, script):
import modules.api.models as api_models
script.args_from = len(self.inputs)
script.args_to = len(self.inputs)
@@ -401,67 +400,69 @@ class ScriptRunner:
def prepare_ui(self):
self.inputs = [None]
def create_script_ui(self, script, inputs = [], inputs_alwayson = []): # noqa
def setup_ui(self, parent='unknown', accordion=True):
import modules.api.models as api_models
script.args_from = len(inputs)
script.args_to = len(inputs)
controls = wrap_call(script.ui, script.filename, "ui", script.is_img2img)
if controls is None:
return
script.name = wrap_call(script.title, script.filename, "title", default=script.filename).lower()
api_args = []
for control in controls:
if not isinstance(control, gr.components.IOComponent):
log.error(f'Invalid script control: "{script.filename}" control={control}')
continue
control.custom_script_source = os.path.basename(script.filename)
arg_info = api_models.ScriptArg(label=control.label or "")
for field in ("value", "minimum", "maximum", "step", "choices"):
v = getattr(control, field, None)
if v is not None:
setattr(arg_info, field, v)
api_args.append(arg_info)
script.api_info = api_models.ScriptInfo(
name=script.name,
is_img2img=script.is_img2img,
is_alwayson=script.alwayson,
args=api_args,
)
if script.infotext_fields is not None:
self.infotext_fields += script.infotext_fields
if script.paste_field_names is not None:
self.paste_field_names += script.paste_field_names
inputs += controls
inputs_alwayson += [script.alwayson for _ in controls]
script.args_to = len(inputs)
def select_script(self, script_index):
selected_script = self.selectable_scripts[script_index - 1] if script_index > 0 else None
return [gr.update(visible=selected_script == s) for s in self.selectable_scripts]
def init_field(self, title):
if title == 'None': # called when an initial value is set from ui-config.json to show script's UI components
return
script_index = self.titles.index(title)
self.selectable_scripts[script_index].group.visible = True
def setup_ui(self, accordion=True):
self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts]
inputs = []
inputs_alwayson = [True]
dropdown = gr.Dropdown(label="Script", elem_id="script_list", choices=["None"] + self.titles, value="None", type="index")
def create_script_ui(script: Script, inputs, inputs_alwayson):
script.parent = parent
script.args_from = len(inputs)
script.args_to = len(inputs)
controls = wrap_call(script.ui, script.filename, "ui", script.is_img2img)
if controls is None:
return
script.name = wrap_call(script.title, script.filename, "title", default=script.filename).lower()
api_args = []
for control in controls:
debug(f'Script control: parent={script.parent} script="{script.name}" label="{control.label}" type={control} id={control.elem_id}')
if not isinstance(control, gr.components.IOComponent):
log.error(f'Invalid script control: "{script.filename}" control={control}')
continue
control.custom_script_source = os.path.basename(script.filename)
arg_info = api_models.ScriptArg(label=control.label or "")
for field in ("value", "minimum", "maximum", "step", "choices"):
v = getattr(control, field, None)
if v is not None:
setattr(arg_info, field, v)
api_args.append(arg_info)
script.api_info = api_models.ScriptInfo(
name=script.name,
is_img2img=script.is_img2img,
is_alwayson=script.alwayson,
args=api_args,
)
if script.infotext_fields is not None:
self.infotext_fields += script.infotext_fields
if script.paste_field_names is not None:
self.paste_field_names += script.paste_field_names
inputs += controls
inputs_alwayson += [script.alwayson for _ in controls]
script.args_to = len(inputs)
dropdown = gr.Dropdown(label="Script", elem_id=f'{parent}_script_list', choices=["None"] + self.titles, value="None", type="index")
inputs.insert(0, dropdown)
for script in self.selectable_scripts:
with gr.Group(visible=False) as group:
t0 = time.time()
self.create_script_ui(script, inputs, inputs_alwayson)
create_script_ui(script, inputs, inputs_alwayson)
time_setup[script.title()] = time_setup.get(script.title(), 0) + (time.time()-t0)
script.group = group
dropdown.init_field = self.init_field
dropdown.change(fn=self.select_script, inputs=[dropdown], outputs=[script.group for script in self.selectable_scripts])
def select_script(script_index):
selected_script = self.selectable_scripts[script_index - 1] if script_index > 0 else None
return [gr.update(visible=selected_script == s) for s in self.selectable_scripts]
def init_field(title):
if title == 'None': # called when an initial value is set from ui-config.json to show script's UI components
return
script_index = self.titles.index(title)
self.selectable_scripts[script_index].group.visible = True
dropdown.init_field = init_field
dropdown.change(fn=select_script, inputs=[dropdown], outputs=[script.group for script in self.selectable_scripts])
def onload_script_visibility(params):
title = params.get('Script', None)
@@ -473,13 +474,11 @@ class ScriptRunner:
else:
return gr.update(visible=False)
# with gr.Group(elem_id='scripts_alwayson_img2img' if self.is_img2img else 'scripts_alwayson_txt2img'):
with gr.Accordion(label="Extensions", elem_id='scripts_alwayson_img2img' if self.is_img2img else 'scripts_alwayson_txt2img') if accordion else gr.Group():
with gr.Accordion(label="Extensions", elem_id=f'{parent}_script_alwayson') if accordion else gr.Group():
for script in self.alwayson_scripts:
t0 = time.time()
elem_id = f'script_{"txt2img" if script.is_txt2img else "img2img"}_{script.title().lower().replace(" ", "_")}'
with gr.Group(elem_id=elem_id, elem_classes=['extension-script']) as group:
self.create_script_ui(script, inputs, inputs_alwayson)
with gr.Group(elem_id=f'{parent}_script_{script.title().lower().replace(" ", "_")}', elem_classes=['extension-script']) as group:
create_script_ui(script, inputs, inputs_alwayson)
script.group = group
time_setup[script.title()] = time_setup.get(script.title(), 0) + (time.time()-t0)