Add get_all_cmdsets` helper inspired by work by user trhr in unmerged PR

This commit is contained in:
Griatch 2021-05-21 15:22:35 +02:00
parent 8e78d0be87
commit 15ae6e0a19
4 changed files with 73 additions and 8 deletions

View file

@ -820,7 +820,7 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
testing which colors your client support
Usage:
color ansi||xterm256
color ansi | xterm256
Prints a color map along with in-mud color codes to use to produce
them. It also tests what is supported in your client. Choices are

View file

@ -2338,16 +2338,16 @@ def get_all_typeclasses(parent=None):
List available typeclasses from all available modules.
Args:
parent (str, optional): If given, only return typeclasses inheriting (at any distance)
from this parent.
parent (str, optional): If given, only return typeclasses inheriting
(at any distance) from this parent.
Returns:
dict: On the form `{"typeclass.path": typeclass, ...}`
Notes:
This will dynamically retrieve all abstract django models inheriting at any distance
from the TypedObject base (aka a Typeclass) so it will work fine with any custom
classes being added.
This will dynamically retrieve all abstract django models inheriting at
any distance from the TypedObject base (aka a Typeclass) so it will
work fine with any custom classes being added.
"""
from evennia.typeclasses.models import TypedObject
@ -2366,6 +2366,34 @@ def get_all_typeclasses(parent=None):
return typeclasses
def get_all_cmdsets(parent=None):
"""
List available cmdsets from all available modules.
Args:
parent (str, optional): If given, only return cmdsets inheriting (at
any distance) from this parent.
Returns:
dict: On the form {"cmdset.path": cmdset, ...}
Notes:
This will dynamically retrieve all abstract django models inheriting at
any distance from the CmdSet base so it will work fine with any custom
classes being added.
"""
from evennia.commands.cmdset import CmdSet
base_cmdset = class_from_module(parent) if parent else CmdSet
cmdsets = {
"{}.{}".format(subclass.__module__, subclass.__name__): subclass
for subclass in base_cmdset.__subclasses__()
}
return cmdsets
def interactive(func):
"""
Decorator to make a method pausable with `yield(seconds)`

View file

@ -79,6 +79,15 @@ class ObjectCreateForm(forms.ModelForm):
required=False,
widget=forms.TextInput(attrs={"size": "78"}),
)
# This is not working well because it will not properly allow an empty choice, and will
# also not work well for comma-separated storage without more work. Notably, it's also
# a bit hard to visualize.
# db_cmdset_storage = forms.MultipleChoiceField(
# label="CmdSet",
# required=False,
# choices=adminutils.get_and_load_typeclasses(parent=ObjectDB))
db_location = forms.ModelChoiceField(
ObjectDB.objects.all(),
label="Location",

View file

@ -4,7 +4,7 @@ Helper utils for admin views.
"""
import importlib
from evennia.utils.utils import get_all_typeclasses, inherits_from
from evennia.utils.utils import get_all_typeclasses, inherits_from, get_all_cmdsets
def get_and_load_typeclasses(parent=None, excluded_parents=None):
@ -46,6 +46,34 @@ def get_and_load_typeclasses(parent=None, excluded_parents=None):
"evennia.scripts.models.ScriptDB",
"evennia.comms.models.ChannelDB",)]
# return on form exceptedaccepted by ChoiceField
# return on form excepted by ChoiceField
return [(path, path) for path in tpaths if path]
def get_and_load_cmdsets(parent=None, excluded_parents=None):
"""
Get all cmdsets available or as children based on a parent cmdset. We need
to initialize things here to make sure as much as possible is loaded in the
admin process. This is intended to be used with forms.ChoiceField.
Args:
parent (str, optional): Python-path to the parent cmdset, if any.
excluded_parents (list): A list of cmset-paths to exclude from the result.
Returns:
list: A list of (str, str), the way ChoiceField wants it.
"""
# we must do this to have cmdsets imported and accessible in the inheritance tree.
import evennia
evennia._init()
cmap = get_all_cmdsets(parent)
excluded_parents = excluded_parents or []
cpaths = [path for path in cmap if not any(path == excluded for excluded in excluded_parents)]
cpaths = sorted(cpaths, key=lambda k: (1 if k.startswith("evennia.") else 0, k))
# return on form expected by ChoiceField
return [("", "-")] + [(path, path) for path in cpaths if path]