Cleanups. Containers created and BaseOption done better.
This commit is contained in:
parent
5bc9a42bb5
commit
d96cf3b809
9 changed files with 159 additions and 234 deletions
|
|
@ -198,6 +198,10 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
||||||
def sessions(self):
|
def sessions(self):
|
||||||
return AccountSessionHandler(self)
|
return AccountSessionHandler(self)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def options(self):
|
||||||
|
return OptionHandler(self, options_dict=settings.OPTIONS_ACCOUNT_DEFAULT, save_category='option')
|
||||||
|
|
||||||
# Do not make this a lazy property; the web UI will not refresh it!
|
# Do not make this a lazy property; the web UI will not refresh it!
|
||||||
@property
|
@property
|
||||||
def characters(self):
|
def characters(self):
|
||||||
|
|
@ -1384,10 +1388,6 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
||||||
look_string = ("-" * 68) + "\n" + "".join(result) + "\n" + ("-" * 68)
|
look_string = ("-" * 68) + "\n" + "".join(result) + "\n" + ("-" * 68)
|
||||||
return look_string
|
return look_string
|
||||||
|
|
||||||
@lazy_property
|
|
||||||
def options(self):
|
|
||||||
return OptionHandler(self, options_dict=settings.ACCOUNT_OPTIONS, save_category='option')
|
|
||||||
|
|
||||||
|
|
||||||
class DefaultGuest(DefaultAccount):
|
class DefaultGuest(DefaultAccount):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
"""
|
|
||||||
Styles (playing off CSS) are a way to change the colors and symbols used for standardized
|
|
||||||
displays used in Evennia. Accounts all have a StyleHandler accessible via .style which
|
|
||||||
retrieves per-Account settings, falling back to the global settings contained in settings.py.
|
|
||||||
|
|
||||||
"""
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
|
|
||||||
class StyleHandler(object):
|
|
||||||
category = 'style'
|
|
||||||
|
|
||||||
def __init__(self, acc):
|
|
||||||
self.acc = acc
|
|
||||||
|
|
||||||
def set(self, option, value):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get(self, option):
|
|
||||||
"""
|
|
||||||
Get the stored Style information from this Account's Attributes if possible.
|
|
||||||
If not, fallback to the Global.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
option (str): The key of the Style to retrieve.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
String or None
|
|
||||||
"""
|
|
||||||
stored = self.acc.attributes.get(option, category=self.category)
|
|
||||||
if stored:
|
|
||||||
return stored
|
|
||||||
default = settings.DEFAULT_STYLES.get(option, None)
|
|
||||||
if default:
|
|
||||||
return default[2]
|
|
||||||
return None
|
|
||||||
|
|
@ -886,12 +886,12 @@ class CmdStyle(COMMAND_DEFAULT_CLASS):
|
||||||
styles_table = self.style_table('Option', 'Description', 'Type', 'Value', width=78)
|
styles_table = self.style_table('Option', 'Description', 'Type', 'Value', width=78)
|
||||||
for op_key in self.account.options.options_dict.keys():
|
for op_key in self.account.options.options_dict.keys():
|
||||||
op_found = self.account.options.get(op_key, return_obj=True)
|
op_found = self.account.options.get(op_key, return_obj=True)
|
||||||
styles_table.add_row(op_key, op_found.description, op_found.expect_type, op_found.display())
|
styles_table.add_row(op_key, op_found.description, op_found.__class__.__name__, op_found.display())
|
||||||
self.msg(str(styles_table))
|
self.msg(str(styles_table))
|
||||||
|
|
||||||
def set(self):
|
def set(self):
|
||||||
try:
|
try:
|
||||||
result = self.account.options.set(self.lhs, self.rhs, account=self.account)
|
result = self.account.options.set(self.lhs, self.rhs)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.msg(str(e))
|
self.msg(str(e))
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -500,7 +500,7 @@ TYPECLASS_AGGRESSIVE_CACHE = True
|
||||||
# Option tuples are in this format:
|
# Option tuples are in this format:
|
||||||
# ("Description", 'Option Class', 'Default Value')
|
# ("Description", 'Option Class', 'Default Value')
|
||||||
|
|
||||||
ACCOUNT_OPTIONS = {
|
OPTIONS_ACCOUNT_DEFAULT = {
|
||||||
'border_color': ('Headers, footers, table borders, etc.', 'Color', 'M'),
|
'border_color': ('Headers, footers, table borders, etc.', 'Color', 'M'),
|
||||||
'header_star_color': ('* inside Header lines.', 'Color', 'm'),
|
'header_star_color': ('* inside Header lines.', 'Color', 'm'),
|
||||||
'header_text_color': ('Text inside Header lines.', 'Color', 'w'),
|
'header_text_color': ('Text inside Header lines.', 'Color', 'w'),
|
||||||
|
|
@ -565,11 +565,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.
|
||||||
VALIDFUNC_MODULES = ['evennia.utils.validfuncs', ]
|
VALIDATOR_MODULES = ['evennia.utils.validfuncs', ]
|
||||||
|
|
||||||
# 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.
|
||||||
OPTIONCLASS_MODULES = ['evennia.utils.opclasses', ]
|
OPTION_MODULES = ['evennia.utils.opclasses', ]
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Default Account setup and access
|
# Default Account setup and access
|
||||||
|
|
|
||||||
47
evennia/utils/containers.py
Normal file
47
evennia/utils/containers.py
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from evennia.utils.utils import callables_from_module
|
||||||
|
|
||||||
|
|
||||||
|
class ValidContainer(object):
|
||||||
|
"""
|
||||||
|
Loads and stores the final list of VALIDATOR FUNCTIONS.
|
||||||
|
|
||||||
|
Can access these as properties or dictionary-contents.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.valid_storage = {}
|
||||||
|
for module in settings.VALIDATOR_MODULES:
|
||||||
|
self.valid_storage.update(callables_from_module(module))
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
return self.valid_storage.get(item, None)
|
||||||
|
|
||||||
|
def __getattr__(self, item):
|
||||||
|
return self[item]
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure that we have a Singleton of ValidHandler that is always loaded... and only needs to be loaded once.
|
||||||
|
VALID_CONTAINER = ValidContainer()
|
||||||
|
|
||||||
|
|
||||||
|
class OptionContainer(object):
|
||||||
|
"""
|
||||||
|
Loads and stores the final list of OPTION CLASSES.
|
||||||
|
|
||||||
|
Can access these as properties or dictionary-contents.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.option_storage = {}
|
||||||
|
for module in settings.OPTION_MODULES:
|
||||||
|
self.option_storage.update(callables_from_module(module))
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
return self.option_storage.get(item, None)
|
||||||
|
|
||||||
|
def __getattr__(self, item):
|
||||||
|
return self[item]
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure that we have a Singleton that keeps all loaded Options.
|
||||||
|
OPTION_CONTAINER = OptionContainer()
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import datetime as _dt
|
import datetime as _dt
|
||||||
|
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.validfuncs import _TZ_DICT
|
||||||
from evennia.utils.valid import VALID_HANDLER as _VAL
|
from evennia.utils.containers import VALID_CONTAINER as _VAL
|
||||||
|
|
||||||
|
|
||||||
class _BaseOption(object):
|
class BaseOption(object):
|
||||||
"""
|
"""
|
||||||
Abstract Class to deal with encapsulating individual Options. An Option has a name/key, a description
|
Abstract Class to deal with encapsulating individual Options. An Option has a name/key, a description
|
||||||
to display in relevant commands and menus, and a default value. It saves to the owner's Attributes using
|
to display in relevant commands and menus, and a default value. It saves to the owner's Attributes using
|
||||||
|
|
@ -17,9 +18,7 @@ class _BaseOption(object):
|
||||||
valid: Shortcut to the loaded VALID_HANDLER.
|
valid: Shortcut to the loaded VALID_HANDLER.
|
||||||
valid_type (str): The key of the Validator this uses.
|
valid_type (str): The key of the Validator this uses.
|
||||||
"""
|
"""
|
||||||
expect_type = ''
|
validator_key = ''
|
||||||
valid = _VAL
|
|
||||||
valid_type = ''
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.key
|
return self.key
|
||||||
|
|
@ -47,7 +46,16 @@ class _BaseOption(object):
|
||||||
# And it's not loaded until it's called upon to spit out its contents.
|
# And it's not loaded until it's called upon to spit out its contents.
|
||||||
self.loaded = False
|
self.loaded = False
|
||||||
|
|
||||||
def load(self):
|
def display(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Renders the Option's value as something pretty to look at.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
How the stored value should be projected to users. a raw timedelta is pretty ugly, y'know?
|
||||||
|
"""
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
@ -56,17 +64,23 @@ class _BaseOption(object):
|
||||||
"""
|
"""
|
||||||
if self.save_data is not None:
|
if self.save_data is not None:
|
||||||
try:
|
try:
|
||||||
self.value_storage = self.valid_save(self.save_data)
|
self.value_storage = self.deserialize(self.save_data)
|
||||||
self.loaded = True
|
self.loaded = True
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e) # need some kind of error message here!
|
_log.log_trace(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def customized(self):
|
def _save(self):
|
||||||
return self.value_storage != self.default_value
|
"""
|
||||||
|
Exports the current value to an Attribute.
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
self.handler.obj.attributes.add(self.key, category=self.handler.save_category, value=self.serialize())
|
||||||
|
|
||||||
|
def deserialize(self, save_data):
|
||||||
"""
|
"""
|
||||||
Perform sanity-checking on the save data. This isn't the same as Validators, as Validators deal with
|
Perform sanity-checking on the save data. This isn't the same as Validators, as Validators deal with
|
||||||
user input. save data might be a timedelta or a list or some other object. isinstance() is probably
|
user input. save data might be a timedelta or a list or some other object. isinstance() is probably
|
||||||
|
|
@ -81,16 +95,18 @@ class _BaseOption(object):
|
||||||
"""
|
"""
|
||||||
return save_data
|
return save_data
|
||||||
|
|
||||||
def clear(self):
|
def serialize(self):
|
||||||
"""
|
"""
|
||||||
Resets this Option to default settings.
|
Serializes the save data for Attribute storage if it's something complicated.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
self. Why?
|
Whatever best handles the Attribute.
|
||||||
"""
|
"""
|
||||||
self.value_storage = None
|
return self.value_storage
|
||||||
self.loaded = False
|
|
||||||
return self
|
@property
|
||||||
|
def changed(self):
|
||||||
|
return self.value_storage != self.default_value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default(self):
|
def default(self):
|
||||||
|
|
@ -99,13 +115,30 @@ 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:
|
||||||
return self.default
|
return self.default
|
||||||
|
|
||||||
def validate(self, value, account):
|
@value.setter
|
||||||
|
def value(self, value):
|
||||||
|
"""
|
||||||
|
Takes user input, presumed to be a string, and changes the value if it is a valid input.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value:
|
||||||
|
account:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
final_value = self.validate(value)
|
||||||
|
self.value_storage = final_value
|
||||||
|
self.loaded = True
|
||||||
|
self._save()
|
||||||
|
|
||||||
|
def validate(self, value):
|
||||||
"""
|
"""
|
||||||
Validate user input, which is presumed to be a string.
|
Validate user input, which is presumed to be a string.
|
||||||
|
|
||||||
|
|
@ -118,202 +151,128 @@ 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 self.do_validate(value, account)
|
return _VAL[self.validator_key](value, thing_name=self.key)
|
||||||
|
|
||||||
def do_validate(self, value, account):
|
|
||||||
"""
|
|
||||||
Second layer of abstraction on validation due to design choices.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value:
|
|
||||||
account:
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
"""
|
|
||||||
return self.valid[self.valid_type](value, thing_name=self.key, account=account)
|
|
||||||
|
|
||||||
def set(self, value, account):
|
|
||||||
"""
|
|
||||||
Takes user input, presumed to be a string, and changes the value if it is a valid input.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value:
|
|
||||||
account:
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
"""
|
|
||||||
final_value = self.validate(value, account)
|
|
||||||
self.value_storage = final_value
|
|
||||||
self.loaded = True
|
|
||||||
self.save()
|
|
||||||
return self.display()
|
|
||||||
|
|
||||||
def display(self):
|
|
||||||
"""
|
|
||||||
Renders the Option's value as something pretty to look at.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
How the stored value should be projected to users. a raw timedelta is pretty ugly, y'know?
|
|
||||||
"""
|
|
||||||
return self.value
|
|
||||||
|
|
||||||
def export(self):
|
|
||||||
"""
|
|
||||||
Serializes the save data for Attribute storage if it's something complicated.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Whatever best handles the Attribute.
|
|
||||||
"""
|
|
||||||
return self.value_storage
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
"""
|
|
||||||
Exports the current value to an Attribute.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
None
|
|
||||||
"""
|
|
||||||
self.handler.obj.attributes.add(self.key, category=self.handler.save_category, value=self.export())
|
|
||||||
|
|
||||||
|
|
||||||
class Text(_BaseOption):
|
class Text(BaseOption):
|
||||||
expect_type = 'Text'
|
validator_key = 'text'
|
||||||
valid_type = 'text'
|
|
||||||
|
|
||||||
def do_validate(self, value, account):
|
def deserialize(self, save_data):
|
||||||
if not str(value):
|
|
||||||
raise ValueError("Must enter some text!")
|
|
||||||
return str(value)
|
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
|
||||||
got_data = str(save_data)
|
got_data = str(save_data)
|
||||||
if not got_data:
|
if not got_data:
|
||||||
raise ValueError(f"{self.key} expected Text data, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Text data, got '{save_data}'")
|
||||||
return got_data
|
return got_data
|
||||||
|
|
||||||
|
|
||||||
class Email(_BaseOption):
|
class Email(BaseOption):
|
||||||
expect_type = 'Email'
|
validator_key = 'email'
|
||||||
valid_type = 'email'
|
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
got_data = str(save_data)
|
got_data = str(save_data)
|
||||||
if not got_data:
|
if not got_data:
|
||||||
raise ValueError(f"{self.key} expected String data, got '{save_data}'")
|
raise ValueError(f"{self.key} expected String data, got '{save_data}'")
|
||||||
return got_data
|
return got_data
|
||||||
|
|
||||||
|
|
||||||
class Boolean(_BaseOption):
|
class Boolean(BaseOption):
|
||||||
expect_type = 'Boolean'
|
validator_key = 'boolean'
|
||||||
valid_type = 'boolean'
|
|
||||||
|
|
||||||
def display(self):
|
def display(self, **kwargs):
|
||||||
if self.value:
|
if self.value:
|
||||||
return '1 - On/True'
|
return '1 - On/True'
|
||||||
return '0 - Off/False'
|
return '0 - Off/False'
|
||||||
|
|
||||||
def export(self):
|
def serialize(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if not isinstance(save_data, bool):
|
if not isinstance(save_data, bool):
|
||||||
raise ValueError(f"{self.key} expected Boolean, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Boolean, got '{save_data}'")
|
||||||
return save_data
|
return save_data
|
||||||
|
|
||||||
|
|
||||||
class Color(_BaseOption):
|
class Color(BaseOption):
|
||||||
expect_type = 'Color'
|
validator_key = 'color'
|
||||||
valid_type = 'color'
|
|
||||||
|
|
||||||
def display(self):
|
def display(self, **kwargs):
|
||||||
return f'{self.value} - |{self.value}this|n'
|
return f'{self.value} - |{self.value}this|n'
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if not save_data or len(_ANSI(f'|{save_data}|n')) > 0:
|
if not save_data or len(_ANSI(f'|{save_data}|n')) > 0:
|
||||||
raise ValueError(f"{self.key} expected Color Code, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Color Code, got '{save_data}'")
|
||||||
return save_data
|
return save_data
|
||||||
|
|
||||||
|
|
||||||
class Timezone(_BaseOption):
|
class Timezone(BaseOption):
|
||||||
expect_type = 'Timezone'
|
validator_key = 'timezone'
|
||||||
valid_type = 'timezone'
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default(self):
|
def default(self):
|
||||||
return _TZ_DICT[self.default_value]
|
return _TZ_DICT[self.default_value]
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if save_data not in _TZ_DICT:
|
if save_data not in _TZ_DICT:
|
||||||
raise ValueError(f"{self.key} expected Timezone Data, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Timezone Data, got '{save_data}'")
|
||||||
return _TZ_DICT[save_data]
|
return _TZ_DICT[save_data]
|
||||||
|
|
||||||
def export(self):
|
def serialize(self):
|
||||||
return str(self.value_storage)
|
return str(self.value_storage)
|
||||||
|
|
||||||
|
|
||||||
class UnsignedInteger(_BaseOption):
|
class UnsignedInteger(BaseOption):
|
||||||
expect_type = 'Whole Number 0+'
|
validator_key = 'unsigned_integer'
|
||||||
valid_type = 'unsigned_integer'
|
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if isinstance(save_data, int) and save_data >= 0:
|
if isinstance(save_data, int) and save_data >= 0:
|
||||||
return save_data
|
return save_data
|
||||||
raise ValueError(f"{self.key} expected Whole Number 0+, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Whole Number 0+, got '{save_data}'")
|
||||||
|
|
||||||
|
|
||||||
class SignedInteger(_BaseOption):
|
class SignedInteger(BaseOption):
|
||||||
expect_type = 'Whole Number'
|
validator_key = 'signed_integer'
|
||||||
valid_type = 'signed_integer'
|
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if isinstance(save_data, int):
|
if isinstance(save_data, int):
|
||||||
return save_data
|
return save_data
|
||||||
raise ValueError(f"{self.key} expected Whole Number, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Whole Number, got '{save_data}'")
|
||||||
|
|
||||||
|
|
||||||
class PositiveInteger(_BaseOption):
|
class PositiveInteger(BaseOption):
|
||||||
expect_type = 'Whole Number 1+'
|
validator_key = 'positive_integer'
|
||||||
valid_type = 'positive_integer'
|
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if isinstance(save_data, int) and save_data > 0:
|
if isinstance(save_data, int) and save_data > 0:
|
||||||
return save_data
|
return save_data
|
||||||
raise ValueError(f"{self.key} expected Whole Number 1+, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Whole Number 1+, got '{save_data}'")
|
||||||
|
|
||||||
|
|
||||||
class Duration(_BaseOption):
|
class Duration(BaseOption):
|
||||||
expect_type = 'Duration'
|
validator_key = 'duration'
|
||||||
valid_type = 'duration'
|
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if isinstance(save_data, int):
|
if isinstance(save_data, int):
|
||||||
return _dt.timedelta(0, save_data, 0, 0, 0, 0, 0)
|
return _dt.timedelta(0, save_data, 0, 0, 0, 0, 0)
|
||||||
raise ValueError(f"{self.key} expected Timedelta in seconds, got '{save_data}'")
|
raise ValueError(f"{self.key} expected Timedelta in seconds, got '{save_data}'")
|
||||||
|
|
||||||
def export(self):
|
def serialize(self):
|
||||||
return self.value_storage.seconds
|
return self.value_storage.seconds
|
||||||
|
|
||||||
|
|
||||||
class Datetime(_BaseOption):
|
class Datetime(BaseOption):
|
||||||
expect_type = 'Datetime'
|
validator_key = 'datetime'
|
||||||
valid_type = 'datetime'
|
|
||||||
|
|
||||||
def valid_save(self, save_data):
|
def deserialize(self, save_data):
|
||||||
if isinstance(save_data, int):
|
if isinstance(save_data, int):
|
||||||
return _dt.datetime.utcfromtimestamp(save_data)
|
return _dt.datetime.utcfromtimestamp(save_data)
|
||||||
raise ValueError(f"{self.key} expected UTC Datetime in EPOCH format, got '{save_data}'")
|
raise ValueError(f"{self.key} expected UTC Datetime in EPOCH format, got '{save_data}'")
|
||||||
|
|
||||||
def export(self):
|
def serialize(self):
|
||||||
return int(self.value_storage.strftime('%s'))
|
return int(self.value_storage.strftime('%s'))
|
||||||
|
|
||||||
|
|
||||||
class Future(Datetime):
|
class Future(Datetime):
|
||||||
expect_type = 'Future Datetime'
|
validator_key = 'future'
|
||||||
valid_type = 'future'
|
|
||||||
|
|
||||||
|
|
||||||
class Lock(Text):
|
class Lock(Text):
|
||||||
expect_type = 'Lock String'
|
validator_key = 'lock'
|
||||||
valid_type = 'lock'
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,5 @@
|
||||||
from django.conf import settings
|
from evennia.utils.utils import string_partial_matching
|
||||||
from evennia.utils.utils import string_partial_matching, callables_from_module
|
from evennia.utils.containers import OPTION_CONTAINER
|
||||||
|
|
||||||
|
|
||||||
class OptionManager(object):
|
|
||||||
"""
|
|
||||||
Loads and stores the final list of OPTION CLASSES.
|
|
||||||
|
|
||||||
Can access these as properties or dictionary-contents.
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self.option_storage = {}
|
|
||||||
for module in settings.OPTIONCLASS_MODULES:
|
|
||||||
self.option_storage.update(callables_from_module(module))
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
return self.option_storage.get(item, None)
|
|
||||||
|
|
||||||
def __getattr__(self, item):
|
|
||||||
return self[item]
|
|
||||||
|
|
||||||
|
|
||||||
# Ensure that we have a Singleton that keeps all loaded Options.
|
|
||||||
OPTION_MANAGER = OptionManager()
|
|
||||||
|
|
||||||
|
|
||||||
class OptionHandler(object):
|
class OptionHandler(object):
|
||||||
|
|
@ -78,19 +56,17 @@ class OptionHandler(object):
|
||||||
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)
|
||||||
loaded_option = OPTION_MANAGER[option_def[1]](self, key, option_def[0], option_def[2], save_data)
|
loaded_option = OPTION_CONTAINER[option_def[1]](self, key, option_def[0], option_def[2], save_data)
|
||||||
self.options[key] = loaded_option
|
self.options[key] = loaded_option
|
||||||
return loaded_option
|
return loaded_option
|
||||||
|
|
||||||
def set(self, option, value, account):
|
def set(self, option, value):
|
||||||
"""
|
"""
|
||||||
Change an individual option.
|
Change an individual option.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
option (str): The key of an option that can be changed. Allows partial matching.
|
option (str): The key of an option that can be changed. Allows partial matching.
|
||||||
value (str): The value that should be checked, coerced, and stored.
|
value (str): The value that should be checked, coerced, and stored.
|
||||||
account (AccountDB): The Account performing the setting. Necessary due to other
|
|
||||||
option lookups like timezone.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
New value
|
New value
|
||||||
|
|
@ -104,4 +80,8 @@ 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)
|
||||||
return op.set(value, account)
|
op.value = value
|
||||||
|
return op.display()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
from django.conf import settings
|
|
||||||
from evennia.utils.utils import callables_from_module
|
|
||||||
|
|
||||||
|
|
||||||
class ValidHandler(object):
|
|
||||||
"""
|
|
||||||
Loads and stores the final list of VALIDATOR FUNCTIONS.
|
|
||||||
|
|
||||||
Can access these as properties or dictionary-contents.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.valid_storage = {}
|
|
||||||
for module in settings.VALIDFUNC_MODULES:
|
|
||||||
self.valid_storage.update(callables_from_module(module))
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
return self.valid_storage.get(item, None)
|
|
||||||
|
|
||||||
def __getattr__(self, item):
|
|
||||||
return self[item]
|
|
||||||
|
|
||||||
|
|
||||||
# Ensure that we have a Singleton of ValidHandler that is always loaded... and only needs to be loaded once.
|
|
||||||
VALID_HANDLER = ValidHandler()
|
|
||||||
|
|
@ -47,8 +47,8 @@ def datetime(entry, thing_name='Datetime', account=None, from_tz=None, **kwargs)
|
||||||
if not entry:
|
if not entry:
|
||||||
raise ValueError(f"No {thing_name} entered!")
|
raise ValueError(f"No {thing_name} entered!")
|
||||||
if not from_tz:
|
if not from_tz:
|
||||||
from_tz = _pytz['UTC']
|
from_tz = _pytz.UTC
|
||||||
utc = _pytz['UTC']
|
utc = _pytz.UTC
|
||||||
now = _dt.datetime.utcnow().replace(tzinfo=utc)
|
now = _dt.datetime.utcnow().replace(tzinfo=utc)
|
||||||
cur_year = now.strftime('%Y')
|
cur_year = now.strftime('%Y')
|
||||||
split_time = entry.split(' ')
|
split_time = entry.split(' ')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue