mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Refactored with more consistent naming and placement. Fixed the table style wrapper.
This commit is contained in:
parent
d96cf3b809
commit
652186d829
9 changed files with 164 additions and 118 deletions
|
|
@ -118,6 +118,9 @@ Web/Django standard initiative (@strikaco)
|
||||||
- `evennia.MONITOR_HANDLER.all` now takes keyword argument `obj` to only retrieve monitors from that specific
|
- `evennia.MONITOR_HANDLER.all` now takes keyword argument `obj` to only retrieve monitors from that specific
|
||||||
Object (rather than all monitors in the entire handler).
|
Object (rather than all monitors in the entire handler).
|
||||||
- Support adding `\f` in command doc strings to force where EvMore puts page breaks.
|
- Support adding `\f` in command doc strings to force where EvMore puts page breaks.
|
||||||
|
- Validation Functions now added with standard API to homogenize user input validation.
|
||||||
|
- Option Classes added to make storing user-options easier and smoother.
|
||||||
|
- `evennia.VALIDATOR_CONTAINER` and `evennia.OPTION_CONTAINER` added to load these.
|
||||||
|
|
||||||
### Contribs
|
### Contribs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,10 @@ TICKER_HANDLER = None
|
||||||
MONITOR_HANDLER = None
|
MONITOR_HANDLER = None
|
||||||
CHANNEL_HANDLER = None
|
CHANNEL_HANDLER = None
|
||||||
|
|
||||||
|
# Containers
|
||||||
|
VALIDATOR_CONTAINER = None
|
||||||
|
OPTION_CONTAINER = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _create_version():
|
def _create_version():
|
||||||
|
|
@ -154,6 +158,7 @@ def _init():
|
||||||
global create_object, create_script, create_account, create_channel, create_message, create_help_entry
|
global create_object, create_script, create_account, create_channel, create_message, create_help_entry
|
||||||
global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers
|
global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers
|
||||||
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER, TASK_HANDLER
|
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER, TASK_HANDLER
|
||||||
|
global VALIDATOR_CONTAINER, OPTION_CONTAINER
|
||||||
global EvMenu, EvTable, EvForm, EvMore, EvEditor
|
global EvMenu, EvTable, EvForm, EvMore, EvEditor
|
||||||
global ANSIString
|
global ANSIString
|
||||||
|
|
||||||
|
|
@ -215,6 +220,10 @@ def _init():
|
||||||
from .comms.channelhandler import CHANNEL_HANDLER
|
from .comms.channelhandler import CHANNEL_HANDLER
|
||||||
from .scripts.monitorhandler import MONITOR_HANDLER
|
from .scripts.monitorhandler import MONITOR_HANDLER
|
||||||
|
|
||||||
|
# containers
|
||||||
|
from .utils.containers import VALIDATOR_CONTAINER
|
||||||
|
from .utils.containers import OPTION_CONTAINER
|
||||||
|
|
||||||
# initialize the doc string
|
# initialize the doc string
|
||||||
global __doc__
|
global __doc__
|
||||||
__doc__ = ansi.parse_ansi(DOCSTRING)
|
__doc__ = ansi.parse_ansi(DOCSTRING)
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,15 @@ All commands in Evennia inherit from the 'Command' class in this module.
|
||||||
from builtins import range
|
from builtins import range
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import math
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from evennia.locks.lockhandler import LockHandler
|
from evennia.locks.lockhandler import LockHandler
|
||||||
from evennia.utils.utils import is_iter, fill, lazy_property, make_iter
|
from evennia.utils.utils import is_iter, fill, lazy_property, make_iter
|
||||||
|
from evennia.utils.evtable import EvTable
|
||||||
|
from evennia.utils.ansi import ANSIString
|
||||||
|
|
||||||
from future.utils import with_metaclass
|
from future.utils import with_metaclass
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -468,6 +472,98 @@ class Command(with_metaclass(CommandMeta, object)):
|
||||||
"""
|
"""
|
||||||
return self.__doc__
|
return self.__doc__
|
||||||
|
|
||||||
|
def width(self):
|
||||||
|
return self.session.protocol_flags['SCREENWIDTH'][0]
|
||||||
|
|
||||||
|
def style_table(self, *args, **kwargs):
|
||||||
|
border_color = self.account.options.get('border_color')
|
||||||
|
column_color = self.account.options.get('column_names_color')
|
||||||
|
|
||||||
|
colornames = ['|%s%s|n' % (column_color, col) for col in args]
|
||||||
|
|
||||||
|
h_line_char = kwargs.pop('header_line_char', '~')
|
||||||
|
header_line_char = ANSIString(f'|{border_color}{h_line_char}|n')
|
||||||
|
|
||||||
|
c_char = kwargs.pop('corner_char', '+')
|
||||||
|
corner_char = ANSIString(f'|{border_color}{c_char}|n')
|
||||||
|
|
||||||
|
b_left_char = kwargs.pop('border_left_char', '||')
|
||||||
|
border_left_char = ANSIString(f'|{border_color}{b_left_char}|n')
|
||||||
|
|
||||||
|
b_right_char = kwargs.pop('border_right_char', '||')
|
||||||
|
border_right_char = ANSIString(f'|{border_color}{b_right_char}|n')
|
||||||
|
|
||||||
|
b_bottom_char = kwargs.pop('border_bottom_char', '-')
|
||||||
|
border_bottom_char = ANSIString(f'|{border_color}{b_bottom_char}|n')
|
||||||
|
|
||||||
|
b_top_char = kwargs.pop('border_top_char', '-')
|
||||||
|
border_top_char = ANSIString(f'|{border_color}{b_top_char}|n')
|
||||||
|
|
||||||
|
table = EvTable(*colornames, header_line_char=header_line_char, corner_char=corner_char,
|
||||||
|
border_left_char=border_left_char, border_right_char=border_right_char,
|
||||||
|
border_top_char=border_top_char, **kwargs)
|
||||||
|
return table
|
||||||
|
|
||||||
|
def render_header(self, header_text=None, fill_character=None, edge_character=None,
|
||||||
|
mode='header', color_header=True):
|
||||||
|
colors = dict()
|
||||||
|
colors['border'] = self.account.options.get('border_color')
|
||||||
|
colors['headertext'] = self.account.options.get('%s_text_color' % mode)
|
||||||
|
colors['headerstar'] = self.account.options.get('%s_star_color' % mode)
|
||||||
|
|
||||||
|
width = self.width()
|
||||||
|
if edge_character:
|
||||||
|
width -= 2
|
||||||
|
|
||||||
|
if header_text:
|
||||||
|
if color_header:
|
||||||
|
header_text = ANSIString(header_text).clean()
|
||||||
|
header_text = ANSIString('|n|%s%s|n' % (colors['headertext'], header_text))
|
||||||
|
if mode == 'header':
|
||||||
|
begin_center = ANSIString("|n|%s<|%s* |n" % (colors['border'], colors['headerstar']))
|
||||||
|
end_center = ANSIString("|n |%s*|%s>|n" % (colors['headerstar'], colors['border']))
|
||||||
|
center_string = ANSIString(begin_center + header_text + end_center)
|
||||||
|
else:
|
||||||
|
center_string = ANSIString('|n |%s%s |n' % (colors['headertext'], header_text))
|
||||||
|
else:
|
||||||
|
center_string = ''
|
||||||
|
|
||||||
|
fill_character = self.account.options.get('%s_fill' % mode)
|
||||||
|
|
||||||
|
remain_fill = width - len(center_string)
|
||||||
|
if remain_fill % 2 == 0:
|
||||||
|
right_width = remain_fill / 2
|
||||||
|
left_width = remain_fill / 2
|
||||||
|
else:
|
||||||
|
right_width = math.floor(remain_fill / 2)
|
||||||
|
left_width = math.ceil(remain_fill / 2)
|
||||||
|
|
||||||
|
right_fill = ANSIString('|n|%s%s|n' % (colors['border'], fill_character * int(right_width)))
|
||||||
|
left_fill = ANSIString('|n|%s%s|n' % (colors['border'], fill_character * int(left_width)))
|
||||||
|
|
||||||
|
if edge_character:
|
||||||
|
edge_fill = ANSIString('|n|%s%s|n' % (colors['border'], edge_character))
|
||||||
|
main_string = ANSIString(center_string)
|
||||||
|
final_send = ANSIString(edge_fill) + left_fill + main_string + right_fill + ANSIString(edge_fill)
|
||||||
|
else:
|
||||||
|
final_send = left_fill + ANSIString(center_string) + right_fill
|
||||||
|
return final_send
|
||||||
|
|
||||||
|
def style_header(self, *args, **kwargs):
|
||||||
|
if 'mode' not in kwargs:
|
||||||
|
kwargs['mode'] = 'header'
|
||||||
|
return self.render_header(*args, **kwargs)
|
||||||
|
|
||||||
|
def style_separator(self, *args, **kwargs):
|
||||||
|
if 'mode' not in kwargs:
|
||||||
|
kwargs['mode'] = 'separator'
|
||||||
|
return self.render_header(*args, **kwargs)
|
||||||
|
|
||||||
|
def style_footer(self, *args, **kwargs):
|
||||||
|
if 'mode' not in kwargs:
|
||||||
|
kwargs['mode'] = 'footer'
|
||||||
|
return self.render_header(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class InterruptCommand(Exception):
|
class InterruptCommand(Exception):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,8 @@ The command template for the default MUX-style command set. There
|
||||||
is also an Account/OOC version that makes sure caller is an Account object.
|
is also an Account/OOC version that makes sure caller is an Account object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import math
|
|
||||||
from evennia.utils import utils
|
from evennia.utils import utils
|
||||||
from evennia.commands.command import Command
|
from evennia.commands.command import Command
|
||||||
from evennia.utils.evtable import EvTable
|
|
||||||
from evennia.utils.ansi import ANSIString
|
|
||||||
|
|
||||||
# limit symbol import for API
|
# limit symbol import for API
|
||||||
__all__ = ("MuxCommand", "MuxAccountCommand")
|
__all__ = ("MuxCommand", "MuxAccountCommand")
|
||||||
|
|
@ -232,98 +229,6 @@ class MuxCommand(Command):
|
||||||
string += "-" * 50
|
string += "-" * 50
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
|
|
||||||
def width(self):
|
|
||||||
return self.session.protocol_flags['SCREENWIDTH'][0]
|
|
||||||
|
|
||||||
def style_table(self, *args, **kwargs):
|
|
||||||
border_color = self.account.options.get('border_color')
|
|
||||||
column_color = self.account.options.get('column_names_color')
|
|
||||||
|
|
||||||
colornames = ['|%s%s|n' % (column_color, col) for col in args]
|
|
||||||
|
|
||||||
h_line_char = kwargs.pop('header_line_char', '-')
|
|
||||||
header_line_char = ANSIString(f'|{border_color}{h_line_char}|n')
|
|
||||||
|
|
||||||
c_char = kwargs.pop('corner_char', '+')
|
|
||||||
corner_char = ANSIString(f'|{border_color}{c_char}|n')
|
|
||||||
|
|
||||||
b_left_char = kwargs.pop('border_left_char', '||')
|
|
||||||
border_left_char = ANSIString(f'|{border_color}{b_left_char}|n')
|
|
||||||
|
|
||||||
b_right_char = kwargs.pop('border_right_char', '||')
|
|
||||||
border_right_char = ANSIString(f'|{border_color}{b_right_char}|n')
|
|
||||||
|
|
||||||
b_bottom_char = kwargs.pop('border_bottom_char', '-')
|
|
||||||
border_bottom_char = ANSIString(f'|{border_color}{b_bottom_char}|n')
|
|
||||||
|
|
||||||
b_top_char = kwargs.pop('border_top_char', '-')
|
|
||||||
border_top_char = ANSIString(f'|{border_color}{b_top_char}|n')
|
|
||||||
|
|
||||||
table = EvTable(*colornames, header_line_char=header_line_char, corner_char=corner_char,
|
|
||||||
border_left_char=border_left_char, border_right_char=border_right_char,
|
|
||||||
border_bottom_char=border_bottom_char, border_top_char=border_top_char, **kwargs)
|
|
||||||
return table
|
|
||||||
|
|
||||||
def render_header(self, header_text=None, fill_character=None, edge_character=None,
|
|
||||||
mode='header', color_header=True):
|
|
||||||
colors = dict()
|
|
||||||
colors['border'] = self.account.options.get('border_color')
|
|
||||||
colors['headertext'] = self.account.options.get('%s_text_color' % mode)
|
|
||||||
colors['headerstar'] = self.account.options.get('%s_star_color' % mode)
|
|
||||||
|
|
||||||
width = self.width()
|
|
||||||
if edge_character:
|
|
||||||
width -= 2
|
|
||||||
|
|
||||||
if header_text:
|
|
||||||
if color_header:
|
|
||||||
header_text = ANSIString(header_text).clean()
|
|
||||||
header_text = ANSIString('|n|%s%s|n' % (colors['headertext'], header_text))
|
|
||||||
if mode == 'header':
|
|
||||||
begin_center = ANSIString("|n|%s<|%s* |n" % (colors['border'], colors['headerstar']))
|
|
||||||
end_center = ANSIString("|n |%s*|%s>|n" % (colors['headerstar'], colors['border']))
|
|
||||||
center_string = ANSIString(begin_center + header_text + end_center)
|
|
||||||
else:
|
|
||||||
center_string = ANSIString('|n |%s%s |n' % (colors['headertext'], header_text))
|
|
||||||
else:
|
|
||||||
center_string = ''
|
|
||||||
|
|
||||||
fill_character = self.account.options.get('%s_fill' % mode)
|
|
||||||
|
|
||||||
remain_fill = width - len(center_string)
|
|
||||||
if remain_fill % 2 == 0:
|
|
||||||
right_width = remain_fill / 2
|
|
||||||
left_width = remain_fill / 2
|
|
||||||
else:
|
|
||||||
right_width = math.floor(remain_fill / 2)
|
|
||||||
left_width = math.ceil(remain_fill / 2)
|
|
||||||
|
|
||||||
right_fill = ANSIString('|n|%s%s|n' % (colors['border'], fill_character * int(right_width)))
|
|
||||||
left_fill = ANSIString('|n|%s%s|n' % (colors['border'], fill_character * int(left_width)))
|
|
||||||
|
|
||||||
if edge_character:
|
|
||||||
edge_fill = ANSIString('|n|%s%s|n' % (colors['border'], edge_character))
|
|
||||||
main_string = ANSIString(center_string)
|
|
||||||
final_send = ANSIString(edge_fill) + left_fill + main_string + right_fill + ANSIString(edge_fill)
|
|
||||||
else:
|
|
||||||
final_send = left_fill + ANSIString(center_string) + right_fill
|
|
||||||
return final_send
|
|
||||||
|
|
||||||
def style_header(self, *args, **kwargs):
|
|
||||||
if 'mode' not in kwargs:
|
|
||||||
kwargs['mode'] = 'header'
|
|
||||||
return self.render_header(*args, **kwargs)
|
|
||||||
|
|
||||||
def style_separator(self, *args, **kwargs):
|
|
||||||
if 'mode' not in kwargs:
|
|
||||||
kwargs['mode'] = 'separator'
|
|
||||||
return self.render_header(*args, **kwargs)
|
|
||||||
|
|
||||||
def style_footer(self, *args, **kwargs):
|
|
||||||
if 'mode' not in kwargs:
|
|
||||||
kwargs['mode'] = 'footer'
|
|
||||||
return self.render_header(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class MuxAccountCommand(MuxCommand):
|
class MuxAccountCommand(MuxCommand):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -511,6 +511,7 @@ OPTIONS_ACCOUNT_DEFAULT = {
|
||||||
'footer_fill': ('Fill for Footer Lines.', 'Text', '='),
|
'footer_fill': ('Fill for Footer Lines.', 'Text', '='),
|
||||||
'help_category_color': ('Help category names.', 'Color', 'g'),
|
'help_category_color': ('Help category names.', 'Color', 'g'),
|
||||||
'help_entry_color': ('Help entry names.', 'Color', 'c'),
|
'help_entry_color': ('Help entry names.', 'Color', 'c'),
|
||||||
|
'timezone': ('Timezone for dates. @tz for a list.', 'Timezone', 'UTC')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -565,11 +566,11 @@ PROTOTYPEFUNC_MODULES = ["evennia.utils.prototypefuncs",
|
||||||
|
|
||||||
# Module holding validator functions. functions in later modules will
|
# Module holding validator functions. functions in later modules will
|
||||||
# override those in earlier ones.
|
# override those in earlier ones.
|
||||||
VALIDATOR_MODULES = ['evennia.utils.validfuncs', ]
|
VALIDATOR_MODULES = ['evennia.utils.validatorfunctions', ]
|
||||||
|
|
||||||
# Modules holding Option classes. Those in later modules will
|
# Modules holding Option classes. Those in later modules will
|
||||||
# override ones in earlier modules.
|
# override ones in earlier modules.
|
||||||
OPTION_MODULES = ['evennia.utils.opclasses', ]
|
OPTION_MODULES = ['evennia.utils.optionclasses', ]
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Default Account setup and access
|
# Default Account setup and access
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from django.conf import settings
|
||||||
from evennia.utils.utils import callables_from_module
|
from evennia.utils.utils import callables_from_module
|
||||||
|
|
||||||
|
|
||||||
class ValidContainer(object):
|
class ValidatorContainer(object):
|
||||||
"""
|
"""
|
||||||
Loads and stores the final list of VALIDATOR FUNCTIONS.
|
Loads and stores the final list of VALIDATOR FUNCTIONS.
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ class ValidContainer(object):
|
||||||
|
|
||||||
|
|
||||||
# Ensure that we have a Singleton of ValidHandler that is always loaded... and only needs to be loaded once.
|
# Ensure that we have a Singleton of ValidHandler that is always loaded... and only needs to be loaded once.
|
||||||
VALID_CONTAINER = ValidContainer()
|
VALIDATOR_CONTAINER = ValidatorContainer()
|
||||||
|
|
||||||
|
|
||||||
class OptionContainer(object):
|
class OptionContainer(object):
|
||||||
|
|
|
||||||
|
|
@ -39,20 +39,49 @@ class OptionHandler(object):
|
||||||
return_list=True, return_obj=True) if s}
|
return_list=True, return_obj=True) if s}
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
|
"""
|
||||||
|
Shortcut to self.get(item) used as a different syntax. This entire object is
|
||||||
|
essentially a dictionary of option_key -> value.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item (str): The Key of the item to get.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The Option's value.
|
||||||
|
"""
|
||||||
return self.get(item).value
|
return self.get(item).value
|
||||||
|
|
||||||
def get(self, item, return_obj=False):
|
def get(self, item, return_obj=False):
|
||||||
|
"""
|
||||||
|
Retrieves an Option stored in the handler. Will load it if it doesn't exist.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item (str): The key to retrieve.
|
||||||
|
return_obj (bool): If True, returns the actual option object instead of its value.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An option value (varies) or the Option itself.
|
||||||
|
"""
|
||||||
if item not in self.options_dict:
|
if item not in self.options_dict:
|
||||||
raise KeyError("Option not found!")
|
raise KeyError("Option not found!")
|
||||||
if item in self.options:
|
if item in self.options:
|
||||||
op_found = self.options[item]
|
op_found = self.options[item]
|
||||||
else:
|
else:
|
||||||
op_found = self.load_option(item)
|
op_found = self._load_option(item)
|
||||||
if return_obj:
|
if return_obj:
|
||||||
return op_found
|
return op_found
|
||||||
return op_found.value
|
return op_found.value
|
||||||
|
|
||||||
def load_option(self, key):
|
def _load_option(self, key):
|
||||||
|
"""
|
||||||
|
Loads option on-demand if it has not been loaded yet.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key (str): The option being loaded.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
option_def = self.options_dict[key]
|
option_def = self.options_dict[key]
|
||||||
save_data = self.save_data.get(key, None)
|
save_data = self.save_data.get(key, None)
|
||||||
self.obj.msg(save_data)
|
self.obj.msg(save_data)
|
||||||
|
|
@ -60,7 +89,7 @@ class OptionHandler(object):
|
||||||
self.options[key] = loaded_option
|
self.options[key] = loaded_option
|
||||||
return loaded_option
|
return loaded_option
|
||||||
|
|
||||||
def set(self, option, value):
|
def set(self, option, value, **kwargs):
|
||||||
"""
|
"""
|
||||||
Change an individual option.
|
Change an individual option.
|
||||||
|
|
||||||
|
|
@ -80,7 +109,7 @@ class OptionHandler(object):
|
||||||
raise ValueError(f"That matched: {', '.join(found)}. Please be more specific.")
|
raise ValueError(f"That matched: {', '.join(found)}. Please be more specific.")
|
||||||
found = found[0]
|
found = found[0]
|
||||||
op = self.get(found, return_obj=True)
|
op = self.get(found, return_obj=True)
|
||||||
op.value = value
|
op.set(value, **kwargs)
|
||||||
return op.display()
|
return op.display()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import datetime as _dt
|
import datetime as _dt
|
||||||
from evennia import logger as _log
|
from evennia import logger as _log
|
||||||
from evennia.utils.ansi import ANSIString as _ANSI
|
from evennia.utils.ansi import ANSIString as _ANSI
|
||||||
from evennia.utils.validfuncs import _TZ_DICT
|
from evennia.utils.validatorfunctions import _TZ_DICT
|
||||||
from evennia.utils.containers import VALID_CONTAINER as _VAL
|
from evennia.utils.containers import VALIDATOR_CONTAINER as _VAL
|
||||||
|
|
||||||
|
|
||||||
class BaseOption(object):
|
class BaseOption(object):
|
||||||
|
|
@ -14,9 +14,8 @@ class BaseOption(object):
|
||||||
Designed to be extremely overloadable as some options can be cantankerous.
|
Designed to be extremely overloadable as some options can be cantankerous.
|
||||||
|
|
||||||
Properties:
|
Properties:
|
||||||
expect_type (str): What users will see this as asking for. Example: Color or email.
|
|
||||||
valid: Shortcut to the loaded VALID_HANDLER.
|
valid: Shortcut to the loaded VALID_HANDLER.
|
||||||
valid_type (str): The key of the Validator this uses.
|
validator_key (str): The key of the Validator this uses.
|
||||||
"""
|
"""
|
||||||
validator_key = ''
|
validator_key = ''
|
||||||
|
|
||||||
|
|
@ -55,7 +54,7 @@ class BaseOption(object):
|
||||||
"""
|
"""
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def _load(self):
|
def load(self):
|
||||||
"""
|
"""
|
||||||
Takes the provided save data, validates it, and gets this Option ready to use.
|
Takes the provided save data, validates it, and gets this Option ready to use.
|
||||||
|
|
||||||
|
|
@ -71,7 +70,7 @@ class BaseOption(object):
|
||||||
_log.log_trace(e)
|
_log.log_trace(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
Exports the current value to an Attribute.
|
Exports the current value to an Attribute.
|
||||||
|
|
||||||
|
|
@ -115,7 +114,7 @@ class BaseOption(object):
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
if not self.loaded and self.save_data is not None:
|
if not self.loaded and self.save_data is not None:
|
||||||
self._load()
|
self.load()
|
||||||
if self.loaded:
|
if self.loaded:
|
||||||
return self.value_storage
|
return self.value_storage
|
||||||
else:
|
else:
|
||||||
|
|
@ -123,22 +122,24 @@ class BaseOption(object):
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
def value(self, value):
|
def value(self, value):
|
||||||
|
self.set(value)
|
||||||
|
|
||||||
|
def set(self, value, **kwargs):
|
||||||
"""
|
"""
|
||||||
Takes user input, presumed to be a string, and changes the value if it is a valid input.
|
Takes user input, presumed to be a string, and changes the value if it is a valid input.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
value:
|
value: The new value of this Option.
|
||||||
account:
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
final_value = self.validate(value)
|
final_value = self.validate(value, **kwargs)
|
||||||
self.value_storage = final_value
|
self.value_storage = final_value
|
||||||
self.loaded = True
|
self.loaded = True
|
||||||
self._save()
|
self.save()
|
||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value, **kwargs):
|
||||||
"""
|
"""
|
||||||
Validate user input, which is presumed to be a string.
|
Validate user input, which is presumed to be a string.
|
||||||
|
|
||||||
|
|
@ -151,7 +152,7 @@ class BaseOption(object):
|
||||||
Returns:
|
Returns:
|
||||||
The results of a Validator call. Might be any kind of python object.
|
The results of a Validator call. Might be any kind of python object.
|
||||||
"""
|
"""
|
||||||
return _VAL[self.validator_key](value, thing_name=self.key)
|
return _VAL[self.validator_key](value, thing_name=self.key, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Text(BaseOption):
|
class Text(BaseOption):
|
||||||
|
|
@ -170,9 +170,11 @@ def timezone(entry, thing_name="Timezone", **kwargs):
|
||||||
"""
|
"""
|
||||||
if not entry:
|
if not entry:
|
||||||
raise ValueError(f"No {thing_name} entered!")
|
raise ValueError(f"No {thing_name} entered!")
|
||||||
found = _partial(list(_TZ_DICT.keys()), entry)
|
found = _partial(list(_TZ_DICT.keys()), entry, ret_index=False)
|
||||||
|
if len(found) > 1:
|
||||||
|
raise ValueError(f"That matched: {', '.join(str(t) for t in found)}. Please be more specific!")
|
||||||
if found:
|
if found:
|
||||||
return _TZ_DICT[found]
|
return _TZ_DICT[found[0]]
|
||||||
raise ValueError(f"Could not find timezone '{entry}' for {thing_name}!")
|
raise ValueError(f"Could not find timezone '{entry}' for {thing_name}!")
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue