Safely retrieve options

- Fixes issues where first launch after install raises AttributeError
- Moved all constants into _constants.py
- Moved all settings related functions into _settings.py
- Add sane defaults for last resort
pull/5/head
544146 2023-03-20 20:09:05 +00:00
parent 912ff1844d
commit 2898de8abd
5 changed files with 155 additions and 95 deletions

View File

@ -34,4 +34,4 @@ Install via the extensions tab on the [AUTOMATIC1111 webui](https://github.com/A
- Open to suggestions
- Pull requests are appreciated
- Write tests if possible and useful
- Run pre-commit!
- Run pre-commit

View File

@ -0,0 +1,23 @@
_EXTENSION_NAME = 'Aspect Ratio Helper'
_MAX_DIMENSION = 2048
_MIN_DIMENSION = 64
_ARH_EXPAND_BY_DEFAULT_KEY = 'arh_expand_by_default'
_ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY = 'arh_show_max_width_or_height'
_ARH_MAX_WIDTH_OR_HEIGHT_KEY = 'arh_max_width_or_height'
_ARH_SHOW_PREDEFINED_PERCENTAGES_KEY = 'arh_show_predefined_percentages'
_ARH_PREDEFINED_PERCENTAGES_KEY = 'arh_predefined_percentages'
_ARH_PREDEFINED_PERCENTAGES_DISPLAY_KEY \
= 'arh_predefined_percentages_display_key'
_DEFAULT_PERCENTAGES_DISPLAY_KEY \
= 'Incremental/decremental percentage (-50%, +50%)'
_OPT_KEY_TO_DEFAULT_MAP = {
_ARH_EXPAND_BY_DEFAULT_KEY: False,
_ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY: True,
_ARH_MAX_WIDTH_OR_HEIGHT_KEY: _MAX_DIMENSION / 2,
_ARH_SHOW_PREDEFINED_PERCENTAGES_KEY: True,
_ARH_PREDEFINED_PERCENTAGES_KEY: '25, 50, 75, 125, 150, 175, 200',
_ARH_PREDEFINED_PERCENTAGES_DISPLAY_KEY: _DEFAULT_PERCENTAGES_DISPLAY_KEY,
}

View File

@ -0,0 +1,103 @@
import contextlib
import gradio as gr
from modules import shared
from aspect_ratio_helper._constants import _ARH_EXPAND_BY_DEFAULT_KEY
from aspect_ratio_helper._constants import _ARH_MAX_WIDTH_OR_HEIGHT_KEY
from aspect_ratio_helper._constants import \
_ARH_PREDEFINED_PERCENTAGES_DISPLAY_KEY
from aspect_ratio_helper._constants import _ARH_PREDEFINED_PERCENTAGES_KEY
from aspect_ratio_helper._constants import _ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY
from aspect_ratio_helper._constants import _ARH_SHOW_PREDEFINED_PERCENTAGES_KEY
from aspect_ratio_helper._constants import _DEFAULT_PERCENTAGES_DISPLAY_KEY
from aspect_ratio_helper._constants import _EXTENSION_NAME
from aspect_ratio_helper._constants import _MAX_DIMENSION
from aspect_ratio_helper._constants import _MIN_DIMENSION
from aspect_ratio_helper._constants import _OPT_KEY_TO_DEFAULT_MAP
from aspect_ratio_helper._util import _display_minus_and_plus
from aspect_ratio_helper._util import _display_multiplication
from aspect_ratio_helper._util import _display_raw_percentage
_PREDEFINED_PERCENTAGES_DISPLAY_MAP = {
_DEFAULT_PERCENTAGES_DISPLAY_KEY: _display_minus_and_plus,
'Raw percentage (50%, 150%)': _display_raw_percentage,
'Multiplication (x0.5, x1.5)': _display_multiplication,
}
# todo: add test coverage to this?..
def _safe_opt(key):
# attempt to retrieve key from shared options
with contextlib.suppress(AttributeError):
return shared.opts.__getattr__(key)
# attempt to retrieve default, and last resort the constant default
return shared.opts.get_default(key) or _OPT_KEY_TO_DEFAULT_MAP.get(key)
def on_ui_settings():
section = 'aspect_ratio_helper', _EXTENSION_NAME
shared.opts.add_option(
key=_ARH_EXPAND_BY_DEFAULT_KEY,
info=shared.OptionInfo(
default=_OPT_KEY_TO_DEFAULT_MAP[_ARH_EXPAND_BY_DEFAULT_KEY],
label='Expand by default',
section=section,
),
)
shared.opts.add_option(
key=_ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY,
info=shared.OptionInfo(
default=_OPT_KEY_TO_DEFAULT_MAP[_ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY],
label='Show maximum width or height button',
section=section,
),
)
shared.opts.add_option(
key=_ARH_MAX_WIDTH_OR_HEIGHT_KEY,
info=shared.OptionInfo(
default=_OPT_KEY_TO_DEFAULT_MAP[_ARH_MAX_WIDTH_OR_HEIGHT_KEY],
label='Maximum width or height default',
component=gr.Slider,
component_args={
'minimum': _MIN_DIMENSION,
'maximum': _MAX_DIMENSION,
'step': 1,
},
section=section,
),
)
shared.opts.add_option(
key=_ARH_SHOW_PREDEFINED_PERCENTAGES_KEY,
info=shared.OptionInfo(
default=_OPT_KEY_TO_DEFAULT_MAP[
_ARH_SHOW_PREDEFINED_PERCENTAGES_KEY
],
label='Show predefined percentage buttons',
section=section,
),
)
shared.opts.add_option(
key=_ARH_PREDEFINED_PERCENTAGES_KEY,
info=shared.OptionInfo(
default=_OPT_KEY_TO_DEFAULT_MAP[_ARH_PREDEFINED_PERCENTAGES_KEY],
label='Predefined percentage buttons, applied to dimensions (75, '
'125, 150)',
section=section,
),
)
shared.opts.add_option(
key=_ARH_PREDEFINED_PERCENTAGES_DISPLAY_KEY,
info=shared.OptionInfo(
default=_OPT_KEY_TO_DEFAULT_MAP[
_ARH_PREDEFINED_PERCENTAGES_DISPLAY_KEY
],
label='Predefined percentage display format',
component=gr.Dropdown,
component_args=lambda: {
'choices': tuple(_PREDEFINED_PERCENTAGES_DISPLAY_MAP.keys()),
},
section=section,
),
)

View File

@ -1,3 +1,7 @@
from aspect_ratio_helper._constants import _MAX_DIMENSION
from aspect_ratio_helper._constants import _MIN_DIMENSION
def _display_multiplication(num):
return f'x{round(num / 100, 3)}'
@ -13,17 +17,6 @@ def _display_minus_and_plus(num):
return f'{num}%'
_DEFAULT_DISPLAY_KEY = 'Incremental/decremental percentage (-50%, +50%)'
_PREDEFINED_PERCENTAGES_DISPLAY_MAP = {
_DEFAULT_DISPLAY_KEY: _display_minus_and_plus,
'Raw percentage (50%, 150%)': _display_raw_percentage,
'Multiplication (x0.5, x1.5)': _display_multiplication,
}
_MIN_DIMENSION = 64
_MAX_DIMENSION = 2048
def _scale_by_percentage(width, height, pct):
aspect_ratio = float(width) / float(height)
step = (pct - 1.0)

View File

@ -1,86 +1,26 @@
import contextlib
from functools import partial
import gradio as gr
from modules import script_callbacks
from modules import scripts
from modules import shared
from modules.shared import opts
from aspect_ratio_helper._util import _DEFAULT_DISPLAY_KEY
from aspect_ratio_helper._util import _MAX_DIMENSION
from aspect_ratio_helper._util import _MIN_DIMENSION
from aspect_ratio_helper._util import _PREDEFINED_PERCENTAGES_DISPLAY_MAP
from aspect_ratio_helper._constants import _ARH_EXPAND_BY_DEFAULT_KEY
from aspect_ratio_helper._constants import _ARH_MAX_WIDTH_OR_HEIGHT_KEY
from aspect_ratio_helper._constants import \
_ARH_PREDEFINED_PERCENTAGES_DISPLAY_KEY
from aspect_ratio_helper._constants import _ARH_PREDEFINED_PERCENTAGES_KEY
from aspect_ratio_helper._constants import _ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY
from aspect_ratio_helper._constants import _ARH_SHOW_PREDEFINED_PERCENTAGES_KEY
from aspect_ratio_helper._constants import _EXTENSION_NAME
from aspect_ratio_helper._constants import _MAX_DIMENSION
from aspect_ratio_helper._constants import _MIN_DIMENSION
from aspect_ratio_helper._settings import _PREDEFINED_PERCENTAGES_DISPLAY_MAP
from aspect_ratio_helper._settings import _safe_opt
from aspect_ratio_helper._settings import on_ui_settings
from aspect_ratio_helper._util import _scale_by_percentage
from aspect_ratio_helper._util import _scale_dimensions_to_max_dimension
_EXTENSION_NAME = 'Aspect Ratio Helper'
def on_ui_settings():
section = 'aspect_ratio_helper', _EXTENSION_NAME
shared.opts.add_option(
key='arh_expand_by_default',
info=shared.OptionInfo(
default=False,
label='Expand by default',
section=section,
),
)
shared.opts.add_option(
key='arh_show_max_width_or_height',
info=shared.OptionInfo(
default=True,
label='Show maximum width or height button',
section=section,
),
)
shared.opts.add_option(
key='arh_max_width_or_height',
info=shared.OptionInfo(
default=_MAX_DIMENSION / 2,
label='Maximum width or height default',
component=gr.Slider,
component_args={
'minimum': _MIN_DIMENSION,
'maximum': _MAX_DIMENSION,
'step': 1,
},
section=section,
),
)
shared.opts.add_option(
key='arh_show_predefined_percentages',
info=shared.OptionInfo(
default=True,
label='Show predefined percentage buttons',
section=section,
),
)
shared.opts.add_option(
key='arh_predefined_percentages',
info=shared.OptionInfo(
default='25, 50, 75, 125, 150, 175, 200',
label='Predefined percentage buttons, applied to dimensions (75, '
'125, 150)',
section=section,
),
)
shared.opts.add_option(
key='arh_predefined_percentages_display_key',
info=shared.OptionInfo(
default=_DEFAULT_DISPLAY_KEY,
label='Predefined percentage display format',
component=gr.Dropdown,
component_args=lambda: {
'choices': tuple(_PREDEFINED_PERCENTAGES_DISPLAY_MAP.keys()),
},
section=section,
),
)
class AspectRatioStepScript(scripts.Script):
def title(self):
@ -91,28 +31,29 @@ class AspectRatioStepScript(scripts.Script):
def ui(self, is_img2img):
if not any([
opts.arh_show_max_width_or_height,
opts.arh_show_predefined_percentages,
_safe_opt(_ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY),
_safe_opt(_ARH_SHOW_PREDEFINED_PERCENTAGES_KEY),
]):
return # return early as no 'show' options enabled
with (
gr.Group(),
gr.Accordion(_EXTENSION_NAME, open=opts.arh_expand_by_default),
contextlib.suppress(AttributeError),
gr.Accordion(
_EXTENSION_NAME,
open=_safe_opt(_ARH_EXPAND_BY_DEFAULT_KEY),
),
):
if is_img2img:
inputs = outputs = [self.i2i_w, self.i2i_h]
else:
inputs = outputs = [self.t2i_w, self.t2i_h]
if opts.arh_show_max_width_or_height:
if _safe_opt(_ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY):
with gr.Row():
max_dimension = gr.inputs.Slider(
minimum=_MIN_DIMENSION,
maximum=_MAX_DIMENSION,
step=1,
default=opts.arh_max_width_or_height,
default=_safe_opt(_ARH_MAX_WIDTH_OR_HEIGHT_KEY),
label='Maximum width or height (whichever is higher)',
)
gr.Button(value='Scale to maximum width or height').click(
@ -121,12 +62,12 @@ class AspectRatioStepScript(scripts.Script):
outputs=outputs,
)
if opts.arh_show_predefined_percentages:
if _safe_opt(_ARH_SHOW_PREDEFINED_PERCENTAGES_KEY):
display_func = _PREDEFINED_PERCENTAGES_DISPLAY_MAP.get(
opts.arh_predefined_percentages_display_key,
_safe_opt(_ARH_PREDEFINED_PERCENTAGES_DISPLAY_KEY),
)
with gr.Column(variant='panel'), gr.Row(variant='compact'):
pps = opts.arh_predefined_percentages
pps = _safe_opt(_ARH_PREDEFINED_PERCENTAGES_KEY)
percentages = [
abs(int(x)) for x in pps.split(',')
]