Run black reformatter on code

This commit is contained in:
Griatch 2022-02-08 13:03:52 +01:00
parent 4582eb4085
commit bd3e31bf3c
178 changed files with 4511 additions and 3385 deletions

View file

@ -78,13 +78,13 @@ class AccountChangeForm(UserChangeForm):
)
is_superuser = forms.BooleanField(
label = "Superuser status",
label="Superuser status",
required=False,
help_text="Superusers bypass all in-game locks and has all "
"permissions without explicitly assigning them. Usually "
"only one superuser (user #1) is needed and only a superuser "
"can create another superuser.<BR>"
"Only Superusers can change the user/group permissions below."
"permissions without explicitly assigning them. Usually "
"only one superuser (user #1) is needed and only a superuser "
"can create another superuser.<BR>"
"Only Superusers can change the user/group permissions below.",
)
def clean_username(self):
@ -165,11 +165,13 @@ class AccountAttributeInline(AttributeInline):
model = AccountDB.db_attributes.through
related_field = "accountdb"
class ObjectPuppetInline(admin.StackedInline):
"""
Inline creation of puppet-Object in Account.
"""
from .objects import ObjectCreateForm
verbose_name = "Puppeted Object"
@ -185,19 +187,26 @@ class ObjectPuppetInline(admin.StackedInline):
"fields": (
("db_key", "db_typeclass_path"),
("db_location", "db_home", "db_destination"),
"db_cmdset_storage",
"db_lock_storage",
"db_cmdset_storage",
"db_lock_storage",
),
"description": "Object currently puppeted by the account (note that this "
"will go away if account logs out or unpuppets)",
"will go away if account logs out or unpuppets)",
},
),
)
extra = 0
readonly_fields = ("db_key", "db_typeclass_path", "db_destination",
"db_location", "db_home", "db_account",
"db_cmdset_storage", "db_lock_storage")
readonly_fields = (
"db_key",
"db_typeclass_path",
"db_destination",
"db_location",
"db_home",
"db_account",
"db_cmdset_storage",
"db_lock_storage",
)
# disable adding/deleting this inline - read-only!
def has_add_permission(self, request, obj=None):
@ -213,7 +222,15 @@ class AccountAdmin(BaseUserAdmin):
This is the main creation screen for Users/accounts
"""
list_display = ("id", "username", "is_staff", "is_superuser", "db_typeclass_path", "db_date_created")
list_display = (
"id",
"username",
"is_staff",
"is_superuser",
"db_typeclass_path",
"db_date_created",
)
list_display_links = ("id", "username")
form = AccountChangeForm
add_form = AccountCreationForm
@ -277,6 +294,7 @@ class AccountAdmin(BaseUserAdmin):
from evennia.utils import dbserialize
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
"Copy & paste this string into an Attribute's `value` field to store this account there."
)
@ -289,8 +307,8 @@ class AccountAdmin(BaseUserAdmin):
return mark_safe(
", ".join(
'<a href="{url}">{name}</a>'.format(
url=reverse("admin:objects_objectdb_change", args=[obj.id]),
name=obj.db_key)
url=reverse("admin:objects_objectdb_change", args=[obj.id]), name=obj.db_key
)
for obj in ObjectDB.objects.filter(db_account=obj)
)
)
@ -316,9 +334,7 @@ class AccountAdmin(BaseUserAdmin):
form = super().get_form(request, obj, **kwargs)
disabled_fields = set()
if not request.user.is_superuser:
disabled_fields |= {
'is_superuser', 'user_permissions', 'user_groups'
}
disabled_fields |= {"is_superuser", "user_permissions", "user_groups"}
for field_name in disabled_fields:
if field_name in form.base_fields:
form.base_fields[field_name].disabled = True

View file

@ -27,28 +27,30 @@ class AttributeForm(forms.ModelForm):
"""
attr_key = forms.CharField(
label="Attribute Name", required=False,
help_text="The main identifier of the Attribute. For Nicks, this is the pattern-matching string."
label="Attribute Name",
required=False,
help_text="The main identifier of the Attribute. For Nicks, this is the pattern-matching string.",
)
attr_category = forms.CharField(
label="Category",
help_text="Categorization. Unset (default) gives a category of `None`, which is "
"is what is searched with e.g. `obj.db.attrname`. For 'nick'-type attributes, this is usually "
"'inputline' or 'channel'.",
required=False, max_length=128
"is what is searched with e.g. `obj.db.attrname`. For 'nick'-type attributes, this is usually "
"'inputline' or 'channel'.",
required=False,
max_length=128,
)
attr_value = PickledFormField(
label="Value",
help_text="Value to pickle/save. Db-objects are serialized as a list "
"containing `__packed_dbobj__` (they can't easily be added from here). Nicks "
"store their pattern-replacement here.",
required=False
required=False,
)
attr_type = forms.ChoiceField(
label="Type",
choices=[(None, "-"), ("nick", "nick")],
help_text="Unset for regular Attributes, 'nick' for Nick-replacement usage.",
required=False
required=False,
)
attr_lockstring = forms.CharField(
label="Locks",
@ -62,10 +64,10 @@ class AttributeForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
"""
If we have an Attribute, then we'll prepopulate our instance with the fields we'd expect it
to have based on the Attribute. attr_key, attr_category, attr_value, attr_type,
and attr_lockstring all refer to the corresponding Attribute fields. The initial data of the form fields will
similarly be populated.
If we have an Attribute, then we'll prepopulate our instance with the fields we'd expect it
to have based on the Attribute. attr_key, attr_category, attr_value, attr_type,
and attr_lockstring all refer to the corresponding Attribute fields. The initial data of the form fields will
similarly be populated.
"""
super().__init__(*args, **kwargs)

View file

@ -17,9 +17,11 @@ class MsgTagInline(TagInline):
Inline display for Msg-tags.
"""
model = Msg.db_tags.through
related_field = "msg"
class MsgForm(forms.ModelForm):
"""
Custom Msg form.
@ -35,7 +37,7 @@ class MsgForm(forms.ModelForm):
required=False,
widget=forms.Textarea(attrs={"cols": "100", "rows": "2"}),
help_text="Optional header for the message; it could be a title or "
"metadata depending on msg-use."
"metadata depending on msg-use.",
)
db_lock_storage = forms.CharField(
@ -48,7 +50,6 @@ class MsgForm(forms.ModelForm):
)
@admin.register(Msg)
class MsgAdmin(admin.ModelAdmin):
"""
@ -67,11 +68,19 @@ class MsgAdmin(admin.ModelAdmin):
)
list_display_links = ("id", "db_date_created", "start_of_message")
ordering = ["-db_date_created", "-id"]
search_fields = ["=id", "^db_date_created", "^db_message",
"^db_sender_accounts__db_key", "^db_sender_objects__db_key",
"^db_sender_scripts__db_key", "^db_sender_external",
"^db_receivers_accounts__db_key", "^db_receivers_objects__db_key",
"^db_receivers_scripts__db_key", "^db_receiver_external"]
search_fields = [
"=id",
"^db_date_created",
"^db_message",
"^db_sender_accounts__db_key",
"^db_sender_objects__db_key",
"^db_sender_scripts__db_key",
"^db_sender_external",
"^db_receivers_accounts__db_key",
"^db_receivers_objects__db_key",
"^db_receivers_scripts__db_key",
"^db_receiver_external",
]
readonly_fields = ["db_date_created", "serialized_string"]
save_as = True
save_on_top = True
@ -80,21 +89,36 @@ class MsgAdmin(admin.ModelAdmin):
raw_id_fields = (
"db_sender_accounts",
"db_sender_objects", "db_sender_scripts",
"db_receivers_accounts", "db_receivers_objects",
"db_receivers_scripts", "db_hide_from_accounts",
"db_hide_from_objects")
"db_sender_objects",
"db_sender_scripts",
"db_receivers_accounts",
"db_receivers_objects",
"db_receivers_scripts",
"db_hide_from_accounts",
"db_hide_from_objects",
)
fieldsets = (
(
None,
{
"fields": (
("db_sender_accounts", "db_sender_objects", "db_sender_scripts", "db_sender_external"),
("db_receivers_accounts", "db_receivers_objects", "db_receivers_scripts", "db_receiver_external"),
(
"db_sender_accounts",
"db_sender_objects",
"db_sender_scripts",
"db_sender_external",
),
(
"db_receivers_accounts",
"db_receivers_objects",
"db_receivers_scripts",
"db_receiver_external",
),
("db_hide_from_accounts", "db_hide_from_objects"),
"db_header",
"db_message", "serialized_string"
"db_message",
"serialized_string",
)
},
),
@ -104,12 +128,14 @@ class MsgAdmin(admin.ModelAdmin):
senders = [o for o in obj.senders if o]
if senders:
return senders[0]
sender.help_text = "If multiple, only the first is shown."
def receiver(self, obj):
receivers = [o for o in obj.receivers if o]
if receivers:
return receivers[0]
receiver.help_text = "If multiple, only the first is shown."
def start_of_message(self, obj):
@ -126,6 +152,7 @@ class MsgAdmin(admin.ModelAdmin):
"""
from evennia.utils import dbserialize
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
@ -144,7 +171,6 @@ class MsgAdmin(admin.ModelAdmin):
return super().get_form(request, obj, **kwargs)
class ChannelAttributeInline(AttributeInline):
"""
Inline display of Channel Attribute - experimental
@ -170,6 +196,7 @@ class ChannelForm(forms.ModelForm):
Form for accessing channels.
"""
class Meta:
model = ChannelDB
fields = "__all__"
@ -193,8 +220,14 @@ class ChannelAdmin(admin.ModelAdmin):
inlines = [ChannelTagInline, ChannelAttributeInline]
form = ChannelForm
list_display = ("id", "db_key", "no_of_subscribers", "db_lock_storage", "db_typeclass_path",
"db_date_created")
list_display = (
"id",
"db_key",
"no_of_subscribers",
"db_lock_storage",
"db_typeclass_path",
"db_date_created",
)
list_display_links = ("id", "db_key")
ordering = ["-db_date_created", "-id", "-db_key"]
search_fields = ["id", "db_key", "db_tags__db_key"]
@ -212,7 +245,7 @@ class ChannelAdmin(admin.ModelAdmin):
"db_lock_storage",
"db_account_subscriptions",
"db_object_subscriptions",
"serialized_string"
"serialized_string",
)
},
),
@ -244,6 +277,7 @@ class ChannelAdmin(admin.ModelAdmin):
"""
from evennia.utils import dbserialize
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (

View file

@ -30,7 +30,8 @@ class HelpEntryForm(forms.ModelForm):
widget=forms.Textarea(attrs={"cols": "100", "rows": "2"}),
help_text="Set lock to view:all() unless you want it to only show to certain users."
"<BR>Use the `edit:` limit if wanting to limit who can edit from in-game. By default it's "
"only limited to who can use the `sethelp` command (Builders).")
"only limited to who can use the `sethelp` command (Builders).",
)
@admin.register(HelpEntry)

View file

@ -63,9 +63,11 @@ class ObjectCreateForm(forms.ModelForm):
f"<BR>If you are creating a Character you usually need <B>{settings.BASE_CHARACTER_TYPECLASS}</B> "
"or a subclass of that. <BR>If your custom class is not found in the list, it may not be imported "
"into Evennia yet.",
choices=lambda: adminutils.get_and_load_typeclasses(parent=ObjectDB))
choices=lambda: adminutils.get_and_load_typeclasses(parent=ObjectDB),
)
db_lock_storage = forms.CharField( label="Locks",
db_lock_storage = forms.CharField(
label="Locks",
required=False,
widget=forms.Textarea(attrs={"cols": "100", "rows": "2"}),
help_text="In-game lock definition string. If not given, defaults will be used. "
@ -92,29 +94,32 @@ class ObjectCreateForm(forms.ModelForm):
label="Location",
required=False,
widget=ForeignKeyRawIdWidget(
ObjectDB._meta.get_field('db_location').remote_field, admin.site),
ObjectDB._meta.get_field("db_location").remote_field, admin.site
),
help_text="The (current) in-game location.<BR>"
"Usually a Room but can be<BR>"
"empty for un-puppeted Characters."
"Usually a Room but can be<BR>"
"empty for un-puppeted Characters.",
)
db_home = forms.ModelChoiceField(
ObjectDB.objects.all(),
label="Home",
required=False,
widget=ForeignKeyRawIdWidget(
ObjectDB._meta.get_field('db_location').remote_field, admin.site),
ObjectDB._meta.get_field("db_location").remote_field, admin.site
),
help_text="Fallback in-game location.<BR>"
"All objects should usually have<BR>"
"a home location."
)
"All objects should usually have<BR>"
"a home location.",
)
db_destination = forms.ModelChoiceField(
ObjectDB.objects.all(),
label="Destination",
required=False,
widget=ForeignKeyRawIdWidget(
ObjectDB._meta.get_field('db_destination').remote_field, admin.site),
help_text="Only used by Exits."
)
ObjectDB._meta.get_field("db_destination").remote_field, admin.site
),
help_text="Only used by Exits.",
)
def __init__(self, *args, **kwargs):
"""
@ -157,9 +162,10 @@ class ObjectEditForm(ObjectCreateForm):
label="Puppeting Account",
required=False,
widget=ForeignKeyRawIdWidget(
ObjectDB._meta.get_field('db_account').remote_field, admin.site),
ObjectDB._meta.get_field("db_account").remote_field, admin.site
),
help_text="An Account puppeting this Object (if any).<BR>Note that when a user logs "
"off/unpuppets, this<BR>field will be empty again. This is normal."
"off/unpuppets, this<BR>field will be empty again. This is normal.",
)
@ -171,10 +177,24 @@ class ObjectAdmin(admin.ModelAdmin):
"""
inlines = [ObjectTagInline, ObjectAttributeInline]
list_display = ("id", "db_key", "db_typeclass_path", "db_location", "db_destination", "db_account", "db_date_created")
list_display = (
"id",
"db_key",
"db_typeclass_path",
"db_location",
"db_destination",
"db_account",
"db_date_created",
)
list_display_links = ("id", "db_key")
ordering = ["-db_date_created", "-id"]
search_fields = ["=id", "^db_key", "db_typeclass_path", "^db_account__db_key", "^db_location__db_key"]
search_fields = [
"=id",
"^db_key",
"db_typeclass_path",
"^db_account__db_key",
"^db_location__db_key",
]
raw_id_fields = ("db_destination", "db_location", "db_home", "db_account")
readonly_fields = ("serialized_string", "link_button")
@ -197,7 +217,7 @@ class ObjectAdmin(admin.ModelAdmin):
("db_account", "link_button"),
"db_cmdset_storage",
"db_lock_storage",
"serialized_string"
"serialized_string",
)
},
),
@ -223,6 +243,7 @@ class ObjectAdmin(admin.ModelAdmin):
"""
from evennia.utils import dbserialize
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
@ -268,7 +289,7 @@ class ObjectAdmin(admin.ModelAdmin):
path(
"account-object-link/<int:pk>",
self.admin_site.admin_view(self.link_object_to_account),
name="object-account-link"
name="object-account-link",
)
]
return custom_urls + urls
@ -276,8 +297,9 @@ class ObjectAdmin(admin.ModelAdmin):
def link_button(self, obj):
return format_html(
'<a class="button" href="{}">Link to Account</a>&nbsp;',
reverse("admin:object-account-link", args=[obj.pk])
reverse("admin:object-account-link", args=[obj.pk]),
)
link_button.short_description = "Create attrs/locks for puppeting"
link_button.allow_tags = True
@ -305,21 +327,24 @@ class ObjectAdmin(admin.ModelAdmin):
lock = obj.locks.get("puppet")
lock += f" or pid({account.id})"
obj.locks.add(lock)
self.message_user(request,
"Did the following (where possible): "
f"Set Account.db._last_puppet = {obj}, "
f"Added {obj} to Account.db._playable_characters list, "
f"Added 'puppet:pid({account.id})' lock to {obj}.")
self.message_user(
request,
"Did the following (where possible): "
f"Set Account.db._last_puppet = {obj}, "
f"Added {obj} to Account.db._playable_characters list, "
f"Added 'puppet:pid({account.id})' lock to {obj}.",
)
else:
self.message_user(request, "Account must be connected for this action "
"(set Puppeting Account and save this page first).",
level=messages.ERROR)
self.message_user(
request,
"Account must be connected for this action "
"(set Puppeting Account and save this page first).",
level=messages.ERROR,
)
# stay on the same page
return HttpResponseRedirect(reverse("admin:objects_objectdb_change", args=[obj.pk]))
def save_model(self, request, obj, form, change):
"""
Model-save hook.

View file

@ -15,8 +15,7 @@ from . import utils as adminutils
class ScriptForm(forms.ModelForm):
db_key = forms.CharField(
label = "Name/Key",
help_text="Script identifier, shown in listings etc."
label="Name/Key", help_text="Script identifier, shown in listings etc."
)
db_typeclass_path = forms.ChoiceField(
@ -24,10 +23,12 @@ class ScriptForm(forms.ModelForm):
help_text="This is the Python-path to the class implementing the actual script functionality. "
"<BR>If your custom class is not found here, it may not be imported into Evennia yet.",
choices=lambda: adminutils.get_and_load_typeclasses(
parent=ScriptDB, excluded_parents=["evennia.prototypes.prototypes.DbPrototype"])
parent=ScriptDB, excluded_parents=["evennia.prototypes.prototypes.DbPrototype"]
),
)
db_lock_storage = forms.CharField( label="Locks",
db_lock_storage = forms.CharField(
label="Locks",
required=False,
widget=forms.Textarea(attrs={"cols": "100", "rows": "2"}),
help_text="In-game lock definition string. If not given, defaults will be used. "
@ -38,18 +39,14 @@ class ScriptForm(forms.ModelForm):
db_interval = forms.IntegerField(
label="Repeat Interval",
help_text="Optional timer component.<BR>How often to call the Script's<BR>`at_repeat` hook, in seconds."
"<BR>Set to 0 to disable."
"<BR>Set to 0 to disable.",
)
db_repeats = forms.IntegerField(
help_text="Only repeat this many times."
"<BR>Set to 0 to run indefinitely."
)
db_start_delay = forms.BooleanField(
help_text="Wait <B>Interval</B> seconds before first call."
help_text="Only repeat this many times." "<BR>Set to 0 to run indefinitely."
)
db_start_delay = forms.BooleanField(help_text="Wait <B>Interval</B> seconds before first call.")
db_persistent = forms.BooleanField(
label = "Survives reboot",
help_text="If unset, a server reboot will remove the timer."
label="Survives reboot", help_text="If unset, a server reboot will remove the timer."
)
@ -68,6 +65,7 @@ class ScriptAttributeInline(AttributeInline):
Inline attribute tags.
"""
model = ScriptDB.db_attributes.through
related_field = "scriptdb"
@ -108,8 +106,8 @@ class ScriptAdmin(admin.ModelAdmin):
("db_key", "db_typeclass_path"),
("db_interval", "db_repeats", "db_start_delay", "db_persistent"),
"db_obj",
"db_lock_storage",
"serialized_string"
"db_lock_storage",
"serialized_string",
)
},
),
@ -122,13 +120,13 @@ class ScriptAdmin(admin.ModelAdmin):
"""
from evennia.utils import dbserialize
return str(dbserialize.pack_dbobj(obj))
serialized_string.help_text = (
"Copy & paste this string into an Attribute's `value` field to store this script there."
)
def get_form(self, request, obj=None, **kwargs):
"""
Overrides help texts.

View file

@ -20,9 +20,7 @@ class TagForm(forms.ModelForm):
"""
db_key = forms.CharField(
label="Key/Name", required=True, help_text="The main key identifier"
)
db_key = forms.CharField(label="Key/Name", required=True, help_text="The main key identifier")
db_category = forms.CharField(
label="Category",
help_text="Used for grouping tags. Unset (default) gives a category of None",
@ -32,15 +30,22 @@ class TagForm(forms.ModelForm):
label="Type",
choices=[(None, "-"), ("alias", "alias"), ("permission", "permission")],
help_text="Tags are used for different things. Unset for regular tags.",
required=False
required=False,
)
db_model = forms.ChoiceField(
label="Model" ,
label="Model",
required=False,
help_text = "Each Tag can only 'attach' to one type of entity.",
choices=([("objectdb", "objectdb"), ("accountdb", "accountdb"),
("scriptdb", "scriptdb"), ("channeldb", "channeldb"),
("helpentry", "helpentry"), ("msg", "msg")])
help_text="Each Tag can only 'attach' to one type of entity.",
choices=(
[
("objectdb", "objectdb"),
("accountdb", "accountdb"),
("scriptdb", "scriptdb"),
("channeldb", "channeldb"),
("helpentry", "helpentry"),
("msg", "msg"),
]
),
)
db_data = forms.CharField(
label="Data",
@ -77,7 +82,7 @@ class InlineTagForm(forms.ModelForm):
label="Type",
choices=[(None, "-"), ("alias", "alias"), ("permission", "permission")],
help_text="Tags are used for different things. Unset for regular tags.",
required=False
required=False,
)
tag_data = forms.CharField(
label="Data",
@ -91,10 +96,10 @@ class InlineTagForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
"""
If we have a tag, then we'll prepopulate our instance with the fields we'd expect it
to have based on the tag. tag_key, tag_category, tag_type, and tag_data all refer to
the corresponding tag fields. The initial data of the form fields will similarly be
populated.
If we have a tag, then we'll prepopulate our instance with the fields we'd expect it
to have based on the tag. tag_key, tag_category, tag_type, and tag_data all refer to
the corresponding tag fields. The initial data of the form fields will similarly be
populated.
"""
super().__init__(*args, **kwargs)
tagkey = None
@ -142,6 +147,7 @@ class TagFormSet(forms.BaseInlineFormSet):
Object, where the handler is an AliasHandler, PermissionsHandler, or TagHandler, based on the
type of tag.
"""
verbose_name = "Tag"
verbose_name_plural = "Tags"
@ -222,13 +228,6 @@ class TagAdmin(admin.ModelAdmin):
fieldsets = (
(
None,
{
"fields": (
("db_key", "db_category"),
("db_tagtype", "db_model"),
"db_data"
)
},
{"fields": (("db_key", "db_category"), ("db_tagtype", "db_model"), "db_data")},
),
)

View file

@ -28,6 +28,4 @@ if settings.EVENNIA_ADMIN:
]
else:
# Just include the normal Django admin.
urlpatterns += [
path("", admin.site.urls)
]
urlpatterns += [path("", admin.site.urls)]

View file

@ -26,6 +26,7 @@ def get_and_load_typeclasses(parent=None, excluded_parents=None):
# this is necessary in order to have typeclasses imported and accessible
# in the inheritance tree.
import evennia
evennia._init()
# this return a dict (path: class}
@ -33,18 +34,27 @@ def get_and_load_typeclasses(parent=None, excluded_parents=None):
# filter out any excludes
excluded_parents = excluded_parents or []
tpaths = [path for path, tclass in tmap.items()
if not any(inherits_from(tclass, excl) for excl in excluded_parents)]
tpaths = [
path
for path, tclass in tmap.items()
if not any(inherits_from(tclass, excl) for excl in excluded_parents)
]
# sort so we get custom paths (not in evennia repo) first
tpaths = sorted(tpaths, key=lambda k: (1 if k.startswith("evennia.") else 0, k))
# the base models are not typeclasses so we filter them out
tpaths = [path for path in tpaths if path not in
("evennia.objects.models.ObjectDB",
"evennia.accounts.models.AccountDB",
"evennia.scripts.models.ScriptDB",
"evennia.comms.models.ChannelDB",)]
tpaths = [
path
for path in tpaths
if path
not in (
"evennia.objects.models.ObjectDB",
"evennia.accounts.models.AccountDB",
"evennia.scripts.models.ScriptDB",
"evennia.comms.models.ChannelDB",
)
]
# return on form excepted by ChoiceField
return [(path, path) for path in tpaths if path]
@ -66,6 +76,7 @@ def get_and_load_cmdsets(parent=None, excluded_parents=None):
"""
# we must do this to have cmdsets imported and accessible in the inheritance tree.
import evennia
evennia._init()
cmap = get_all_cmdsets(parent)

View file

@ -112,9 +112,11 @@ class AccountDBFilterSet(BaseTypeclassFilterSet):
class Meta:
model = AccountDB
fields = [fi for fi in (SHARED_FIELDS + ["username", "db_is_connected", "db_is_bot"])
if fi != 'db_key']
fields = [
fi
for fi in (SHARED_FIELDS + ["username", "db_is_connected", "db_is_bot"])
if fi != "db_key"
]
class ScriptDBFilterSet(BaseTypeclassFilterSet):
@ -140,8 +142,7 @@ class HelpFilterSet(FilterSet):
Filter for help entries
"""
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_key")
category = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_category")
alias = AliasFilter(lookup_expr="iexact")

View file

@ -11,7 +11,9 @@ class EvenniaAPIRoot(routers.APIRootView):
Root of the Evennia API tree.
"""
pass
class APIRootRouter(routers.DefaultRouter):
APIRootView = EvenniaAPIRoot

View file

@ -25,6 +25,7 @@ class AttributeSerializer(serializers.ModelSerializer):
Serialize Attribute views.
"""
value_display = serializers.SerializerMethodField(source="value")
db_value = serializers.CharField(write_only=True, required=False)
@ -151,6 +152,7 @@ class TypeclassListSerializerMixin:
Shortened serializer for list views.
"""
shared_fields = [
"id",
"db_key",
@ -215,6 +217,7 @@ class ObjectListSerializer(TypeclassListSerializerMixin, serializers.ModelSerial
Shortened representation for listings.]
"""
class Meta:
model = DefaultObject
fields = [
@ -261,10 +264,12 @@ class AccountListSerializer(TypeclassListSerializerMixin, serializers.ModelSeria
A shortened form for listing.
"""
class Meta:
model = DefaultAccount
fields = ["username"] + [
fi for fi in TypeclassListSerializerMixin.shared_fields if fi != "db_key"]
fi for fi in TypeclassListSerializerMixin.shared_fields if fi != "db_key"
]
read_only_fields = ["id"]
@ -273,6 +278,7 @@ class ScriptDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
Serializing Account.
"""
attributes = serializers.SerializerMethodField()
tags = serializers.SerializerMethodField()
aliases = serializers.SerializerMethodField()
@ -295,6 +301,7 @@ class ScriptListSerializer(TypeclassListSerializerMixin, serializers.ModelSerial
Shortened form for listing.
"""
class Meta:
model = ScriptDB
fields = [
@ -312,25 +319,36 @@ class HelpSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
Serializers Help entries (not a typeclass).
"""
tags = serializers.SerializerMethodField()
aliases = serializers.SerializerMethodField()
class Meta:
model = HelpEntry
fields = [
"id", "db_key", "db_help_category", "db_entrytext", "db_date_created",
"tags", "aliases"
"id",
"db_key",
"db_help_category",
"db_entrytext",
"db_date_created",
"tags",
"aliases",
]
read_only_fields = ["id"]
class HelpListSerializer(TypeclassListSerializerMixin, serializers.ModelSerializer):
"""
Shortened form for listings.
"""
class Meta:
model = HelpEntry
fields = [
"id", "db_key", "db_help_category", "db_date_created",
"id",
"db_key",
"db_help_category",
"db_date_created",
]
read_only_fields = ["id"]

View file

@ -38,7 +38,16 @@ class TestEvenniaRESTApi(BaseEvenniaTest):
def get_view_details(self, action):
"""Helper function for generating list of named tuples"""
View = namedtuple(
"View", ["view_name", "obj", "list", "serializer", "list_serializer", "create_data", "retrieve_data"]
"View",
[
"view_name",
"obj",
"list",
"serializer",
"list_serializer",
"create_data",
"retrieve_data",
],
)
views = [
View(

View file

@ -40,18 +40,17 @@ urlpatterns = router.urls
urlpatterns += [
# openapi schema
path('openapi',
get_schema_view(
title="Evennia API",
description="Evennia OpenAPI Schema",
version="1.0"),
name='openapi',
path(
"openapi",
get_schema_view(title="Evennia API", description="Evennia OpenAPI Schema", version="1.0"),
name="openapi",
),
# redoc auto-doc (based on openapi schema)
path('redoc/',
TemplateView.as_view(
template_name="rest_framework/redoc.html" ,
extra_context={'schema_url': 'api:openapi'}),
name='redoc'
)
path(
"redoc/",
TemplateView.as_view(
template_name="rest_framework/redoc.html", extra_context={"schema_url": "api:openapi"}
),
name="redoc",
),
]

View file

@ -26,12 +26,13 @@ class GeneralViewSetMixin:
Mixin for both typeclass- and non-typeclass entities.
"""
def get_serializer_class(self):
"""
Allow different serializers for certain actions.
"""
if self.action == 'list':
if self.action == "list":
if hasattr(self, "list_serializer_class"):
return self.list_serializer_class
return self.serializer_class
@ -93,6 +94,7 @@ class ObjectDBViewSet(TypeclassViewSetMixin, ModelViewSet):
(rooms, exits, characters etc).
"""
# An example of a basic viewset for all ObjectDB instances. It declares the
# serializer to use for both retrieving and changing/creating/deleting
# instances. Serializers are similar to django forms, used for the
@ -109,6 +111,7 @@ class CharacterViewSet(ObjectDBViewSet):
Characters are a type of Object commonly used as player avatars in-game.
"""
queryset = DefaultCharacter.objects.typeclass_search(
DefaultCharacter.path, include_children=True
)
@ -167,6 +170,7 @@ class HelpViewSet(GeneralViewSetMixin, ModelViewSet):
Note that command auto-help and file-based help entries are not accessible this way.
"""
serializer_class = serializers.HelpSerializer
queryset = HelpEntry.objects.all()
filterset_class = filters.HelpFilterSet

View file

@ -17,7 +17,8 @@ class EvenniaAdminApp(apps.AdminConfig):
This is imported in INSTALLED_APPS instead of django.contrib.admin.
"""
default_site = 'evennia.web.utils.adminsite.EvenniaAdminSite'
default_site = "evennia.web.utils.adminsite.EvenniaAdminSite"
class EvenniaAdminSite(admin.AdminSite):
@ -26,10 +27,21 @@ class EvenniaAdminSite(admin.AdminSite):
admin.register in the admin/ folder, this is what is being registered to.
"""
site_header = "Evennia web admin"
app_order = ["accounts", "objects", "scripts", "comms", "help",
"typeclasses", "server", "sites", "flatpages", "auth"]
app_order = [
"accounts",
"objects",
"scripts",
"comms",
"help",
"typeclasses",
"server",
"sites",
"flatpages",
"auth",
]
def get_app_list(self, request):
app_list = super().get_app_list(request)

View file

@ -9,8 +9,10 @@ class TestGeneralContext(TestCase):
@patch("evennia.web.utils.general_context.GAME_NAME", "test_name")
@patch("evennia.web.utils.general_context.GAME_SLOGAN", "test_game_slogan")
@patch("evennia.web.utils.general_context.WEBSOCKET_CLIENT_ENABLED",
"websocket_client_enabled_testvalue")
@patch(
"evennia.web.utils.general_context.WEBSOCKET_CLIENT_ENABLED",
"websocket_client_enabled_testvalue",
)
@patch("evennia.web.utils.general_context.WEBCLIENT_ENABLED", "webclient_enabled_testvalue")
@patch("evennia.web.utils.general_context.WEBSOCKET_PORT", "websocket_client_port_testvalue")
@patch("evennia.web.utils.general_context.WEBSOCKET_URL", "websocket_client_url_testvalue")
@ -39,7 +41,7 @@ class TestGeneralContext(TestCase):
"websocket_port": "websocket_client_port_testvalue",
"websocket_url": "websocket_client_url_testvalue",
"rest_api_enabled": True,
"server_hostname": 'localhost',
"server_hostname": "localhost",
"ssh_enabled": False,
"ssh_ports": False,
"telnet_enabled": True,

View file

@ -7,6 +7,4 @@ from . import views
app_name = "webclient"
urlpatterns = [
path("", views.webclient, name="index")
]
urlpatterns = [path("", views.webclient, name="index")]

View file

@ -52,8 +52,9 @@ class AccountForm(UserCreationForm):
"""
# The model/typeclass this form creates
model = class_from_module(settings.BASE_ACCOUNT_TYPECLASS,
fallback=settings.FALLBACK_ACCOUNT_TYPECLASS)
model = class_from_module(
settings.BASE_ACCOUNT_TYPECLASS, fallback=settings.FALLBACK_ACCOUNT_TYPECLASS
)
# The fields to display on the form, in the given order
fields = ("username", "email")
@ -88,8 +89,9 @@ class ObjectForm(EvenniaForm, ModelForm):
"""
# The model/typeclass this form creates
model = class_from_module(settings.BASE_OBJECT_TYPECLASS,
fallback=settings.FALLBACK_OBJECT_TYPECLASS)
model = class_from_module(
settings.BASE_OBJECT_TYPECLASS, fallback=settings.FALLBACK_OBJECT_TYPECLASS
)
# The fields to display on the form, in the given order
fields = ("db_key",)
@ -142,8 +144,9 @@ class CharacterForm(ObjectForm):
"""
# Get the correct object model
model = class_from_module(settings.BASE_CHARACTER_TYPECLASS,
fallback=settings.FALLBACK_CHARACTER_TYPECLASS)
model = class_from_module(
settings.BASE_CHARACTER_TYPECLASS, fallback=settings.FALLBACK_CHARACTER_TYPECLASS
)
# Allow entry of the 'key' field
fields = ("db_key",)

View file

@ -129,8 +129,9 @@ class ChannelDetailTest(EvenniaWebTest):
def setUp(self):
super().setUp()
klass = class_from_module(self.channel_typeclass,
fallback=settings.FALLBACK_CHANNEL_TYPECLASS)
klass = class_from_module(
self.channel_typeclass, fallback=settings.FALLBACK_CHANNEL_TYPECLASS
)
# Create a channel
klass.create("demo")
@ -144,13 +145,10 @@ class HelpListTest(EvenniaWebTest):
HELP_ENTRY_DICTS = [
{
"key": "unit test file entry",
"category": "General",
"text": "cache test file entry text"
}
{"key": "unit test file entry", "category": "General", "text": "cache test file entry text"}
]
class HelpDetailTest(EvenniaWebTest):
url_name = "help-entry-detail"
@ -158,31 +156,30 @@ class HelpDetailTest(EvenniaWebTest):
super().setUp()
# create a db help entry
create_help_entry('unit test db entry', 'unit test db entry text', category="General")
create_help_entry("unit test db entry", "unit test db entry text", category="General")
def get_kwargs(self):
return {"category": slugify("general"),
"topic": slugify('unit test db entry')}
return {"category": slugify("general"), "topic": slugify("unit test db entry")}
def test_view(self):
response = self.client.get(reverse(self.url_name, kwargs=self.get_kwargs()), follow=True)
self.assertEqual(response.context["entry_text"], 'unit test db entry text')
self.assertEqual(response.context["entry_text"], "unit test db entry text")
def test_object_cache(self):
# clear file help entries, use local HELP_ENTRY_DICTS to recreate new entries
global _FILE_HELP_ENTRIES
if _FILE_HELP_ENTRIES is None:
from evennia.help.filehelp import FILE_HELP_ENTRIES as _FILE_HELP_ENTRIES
help_module = 'evennia.web.website.tests'
help_module = "evennia.web.website.tests"
self.file_help_store = _FILE_HELP_ENTRIES.__init__(help_file_modules=[help_module])
# request access to an entry
response = self.client.get(reverse(self.url_name, kwargs=self.get_kwargs()), follow=True)
self.assertEqual(response.context["entry_text"], 'unit test db entry text')
self.assertEqual(response.context["entry_text"], "unit test db entry text")
# request a second entry, verifing the cached object is not provided on a new topic request
entry_two_args = {"category": slugify("general"), "topic": slugify('unit test file entry')}
entry_two_args = {"category": slugify("general"), "topic": slugify("unit test file entry")}
response = self.client.get(reverse(self.url_name, kwargs=entry_two_args), follow=True)
self.assertEqual(response.context["entry_text"], 'cache test file entry text')
self.assertEqual(response.context["entry_text"], "cache test file entry text")
class HelpLockedDetailTest(EvenniaWebTest):
@ -192,24 +189,27 @@ class HelpLockedDetailTest(EvenniaWebTest):
super().setUp()
# create a db entry with a lock
self.db_help_entry = create_help_entry('unit test locked topic', 'unit test locked entrytext',
category="General", locks='read:perm(Developer)')
self.db_help_entry = create_help_entry(
"unit test locked topic",
"unit test locked entrytext",
category="General",
locks="read:perm(Developer)",
)
def get_kwargs(self):
return {"category": slugify("general"),
"topic": slugify('unit test locked topic')}
return {"category": slugify("general"), "topic": slugify("unit test locked topic")}
def test_locked_entry(self):
# request access to an entry for permission the account does not have
response = self.client.get(reverse(self.url_name, kwargs=self.get_kwargs()), follow=True)
self.assertEqual(response.context["entry_text"], 'Failed to find entry.')
self.assertEqual(response.context["entry_text"], "Failed to find entry.")
def test_lock_with_perm(self):
# log TestAccount in, grant permission required, read the entry
self.login()
self.account.permissions.add("Developer")
response = self.client.get(reverse(self.url_name, kwargs=self.get_kwargs()), follow=True)
self.assertEqual(response.context["entry_text"], 'unit test locked entrytext')
self.assertEqual(response.context["entry_text"], "unit test locked entrytext")
class CharacterCreateView(EvenniaWebTest):

View file

@ -5,53 +5,51 @@ This redirects to website sub-pages.
from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from .views import (
index, errors, accounts, help as helpviews, channels, characters)
from .views import index, errors, accounts, help as helpviews, channels, characters
urlpatterns = [
# website front page
path("", index.EvenniaIndexView.as_view(), name="index"),
# errors
path(r"tbi/", errors.to_be_implemented, name="to_be_implemented"),
# User Authentication (makes login/logout url names available)
path("auth/register", accounts.AccountCreateView.as_view(), name="register"),
path("auth/", include("django.contrib.auth.urls")),
# Help Topics
path("help/", helpviews.HelpListView.as_view(), name="help"),
path(r"help/<str:category>/<str:topic>/",
helpviews.HelpDetailView.as_view(),
name="help-entry-detail"),
path(
r"help/<str:category>/<str:topic>/",
helpviews.HelpDetailView.as_view(),
name="help-entry-detail",
),
# Channels
path("channels/", channels.ChannelListView.as_view(), name="channels"),
path("channels/<str:slug>/",
channels.ChannelDetailView.as_view(),
name="channel-detail"),
path("channels/<str:slug>/", channels.ChannelDetailView.as_view(), name="channel-detail"),
# Character management
path("characters/", characters.CharacterListView.as_view(), name="characters"),
path("characters/create/",
characters.CharacterCreateView.as_view(),
name="character-create"),
path("characters/manage/",
characters.CharacterManageView.as_view(),
name="character-manage"),
path("characters/detail/<str:slug>/<int:pk>/",
characters.CharacterDetailView.as_view(),
name="character-detail"),
path("characters/puppet/<str:slug>/<int:pk>/",
characters.CharacterPuppetView.as_view(),
name="character-puppet"),
path("characters/update/<str:slug>/<int:pk>/",
characters.CharacterUpdateView.as_view(),
name="character-update"),
path("characters/delete/<str:slug>/<int:pk>/",
characters.CharacterDeleteView.as_view(),
name="character-delete"),
path("characters/create/", characters.CharacterCreateView.as_view(), name="character-create"),
path("characters/manage/", characters.CharacterManageView.as_view(), name="character-manage"),
path(
"characters/detail/<str:slug>/<int:pk>/",
characters.CharacterDetailView.as_view(),
name="character-detail",
),
path(
"characters/puppet/<str:slug>/<int:pk>/",
characters.CharacterPuppetView.as_view(),
name="character-puppet",
),
path(
"characters/update/<str:slug>/<int:pk>/",
characters.CharacterUpdateView.as_view(),
name="character-update",
),
path(
"characters/delete/<str:slug>/<int:pk>/",
characters.CharacterDeleteView.as_view(),
name="character-delete",
),
]
@ -59,15 +57,18 @@ urlpatterns = [
# is not recommended and is usually unnecessary).
if settings.SERVE_MEDIA:
from django import views as django_views
urlpatterns.extend(
[
path("media/<str:path>",
django_views.static.serve,
{"document_root": settings.MEDIA_ROOT},
path(
"media/<str:path>",
django_views.static.serve,
{"document_root": settings.MEDIA_ROOT},
),
path("static/<str:path>",
django_views.static.serve,
{"document_root": settings.STATIC_ROOT},
path(
"static/<str:path>",
django_views.static.serve,
{"document_root": settings.STATIC_ROOT},
),
]
)

View file

@ -24,8 +24,9 @@ class AccountMixin(TypeclassMixin):
"""
# -- Django constructs --
model = class_from_module(settings.BASE_ACCOUNT_TYPECLASS,
fallback=settings.FALLBACK_ACCOUNT_TYPECLASS)
model = class_from_module(
settings.BASE_ACCOUNT_TYPECLASS, fallback=settings.FALLBACK_ACCOUNT_TYPECLASS
)
form_class = forms.AccountForm
@ -73,4 +74,3 @@ class AccountCreateView(AccountMixin, EvenniaCreateView):
# Redirect the user to the login page
return HttpResponseRedirect(self.success_url)

View file

@ -25,8 +25,9 @@ class ChannelMixin(TypeclassMixin):
"""
# -- Django constructs --
model = class_from_module(settings.BASE_CHANNEL_TYPECLASS,
fallback=settings.FALLBACK_CHANNEL_TYPECLASS)
model = class_from_module(
settings.BASE_CHANNEL_TYPECLASS, fallback=settings.FALLBACK_CHANNEL_TYPECLASS
)
# -- Evennia constructs --
page_title = "Channels"
@ -175,5 +176,3 @@ class ChannelDetailView(ChannelMixin, ObjectDetailView):
)
return obj

View file

@ -28,8 +28,9 @@ class CharacterMixin(TypeclassMixin):
"""
# -- Django constructs --
model = class_from_module(settings.BASE_CHARACTER_TYPECLASS,
fallback=settings.FALLBACK_CHARACTER_TYPECLASS)
model = class_from_module(
settings.BASE_CHARACTER_TYPECLASS, fallback=settings.FALLBACK_CHARACTER_TYPECLASS
)
form_class = forms.CharacterForm
success_url = reverse_lazy("character-manage")
@ -199,6 +200,7 @@ class CharacterDeleteView(CharacterMixin, ObjectDeleteView):
ObjectDeleteView) can delete a character they own.
"""
# using the character form fails there
form_class = forms.EvenniaForm
@ -251,4 +253,3 @@ class CharacterCreateView(CharacterMixin, ObjectCreateView):
# Call the Django "form failed" hook
messages.error(self.request, "Your character could not be created.")
return self.form_invalid(form)

View file

@ -5,6 +5,7 @@ Error views.
from django.shortcuts import render
def to_be_implemented(request):
"""
A notice letting the user know that this particular feature hasn't been

View file

@ -33,12 +33,12 @@ def get_help_category(help_entry, slugify_cat=True):
Returns:
help_category (str): The category for the help entry.
"""
help_category = getattr(help_entry, 'help_category', None)
help_category = getattr(help_entry, "help_category", None)
if not help_category:
help_category = getattr(help_entry, 'db_help_category', DEFAULT_HELP_CATEGORY)
help_category = getattr(help_entry, "db_help_category", DEFAULT_HELP_CATEGORY)
# if one does not exist, create a category for ease of use with web views html templates
if not hasattr(help_entry, 'web_help_category'):
setattr(help_entry, 'web_help_category', slugify(help_category))
if not hasattr(help_entry, "web_help_category"):
setattr(help_entry, "web_help_category", slugify(help_category))
help_category = help_category.lower()
return slugify(help_category) if slugify_cat else help_category
@ -52,13 +52,13 @@ def get_help_topic(help_entry):
Returns:
help_topic (str): The topic of the help entry. Default is 'unknown_topic'.
"""
help_topic = getattr(help_entry, 'key', None)
help_topic = getattr(help_entry, "key", None)
# if object has no key, assume it is a db help entry.
if not help_topic:
help_topic = getattr(help_entry, 'db_key', 'unknown_topic')
help_topic = getattr(help_entry, "db_key", "unknown_topic")
# if one does not exist, create a key for ease of use with web views html templates
if not hasattr(help_entry, 'web_help_key'):
setattr(help_entry, 'web_help_key', slugify(help_topic))
if not hasattr(help_entry, "web_help_key"):
setattr(help_entry, "web_help_key", slugify(help_topic))
return help_topic.lower()
@ -79,9 +79,9 @@ def can_read_topic(cmd_or_topic, account):
`can_list_topic` is also returning False.
"""
if inherits_from(cmd_or_topic, "evennia.commands.command.Command"):
return cmd_or_topic.auto_help and cmd_or_topic.access(account, 'read', default=True)
return cmd_or_topic.auto_help and cmd_or_topic.access(account, "read", default=True)
else:
return cmd_or_topic.access(account, 'read', default=True)
return cmd_or_topic.access(account, "read", default=True)
def collect_topics(account):
@ -99,7 +99,7 @@ def collect_topics(account):
# collect commands of account and all puppets
# skip a command if an entry is recorded with the same topics, category and help entry
cmd_help_topics = []
if not str(account) == 'AnonymousUser':
if not str(account) == "AnonymousUser":
# create list of account and account's puppets
puppets = account.db._playable_characters + [account]
# add the account's and puppets' commands to cmd_help_topics list
@ -112,7 +112,7 @@ def collect_topics(account):
# also check the 'cmd:' lock here
for cmd in cmdset:
# skip the command if the puppet does not have access
if not cmd.access(puppet, 'cmd'):
if not cmd.access(puppet, "cmd"):
continue
# skip the command if the puppet does not have read access
if not can_read_topic(cmd, puppet):
@ -121,10 +121,11 @@ def collect_topics(account):
entry_exists = False
for verify_cmd in cmd_help_topics:
if (
verify_cmd.key and cmd.key and
verify_cmd.help_category == cmd.help_category and
verify_cmd.__doc__ == cmd.__doc__
):
verify_cmd.key
and cmd.key
and verify_cmd.help_category == cmd.help_category
and verify_cmd.__doc__ == cmd.__doc__
):
entry_exists = True
break
if entry_exists:
@ -148,15 +149,14 @@ def collect_topics(account):
# Collect commands into a dictionary, read access verified at puppet level
cmd_help_topics = {
cmd.auto_help_display_key
if hasattr(cmd, "auto_help_display_key") else cmd.key: cmd
cmd.auto_help_display_key if hasattr(cmd, "auto_help_display_key") else cmd.key: cmd
for cmd in cmd_help_topics
}
return cmd_help_topics, db_help_topics, file_help_topics
class HelpMixin():
class HelpMixin:
"""
This is a "mixin", a modifier of sorts.
@ -224,7 +224,7 @@ class HelpDetailView(HelpMixin, DetailView):
# Makes sure the page has a sensible title.
obj = self.get_object()
topic = get_help_topic(obj)
return f'{topic} detail'
return f"{topic} detail"
def get_context_data(self, **kwargs):
"""
@ -272,7 +272,7 @@ class HelpDetailView(HelpMixin, DetailView):
context["topic_previous"] = None
# Get the help entry text
text = 'Failed to find entry.'
text = "Failed to find entry."
if inherits_from(obj, "evennia.commands.command.Command"):
text = obj.__doc__
elif inherits_from(obj, "evennia.help.models.HelpEntry"):
@ -297,8 +297,8 @@ class HelpDetailView(HelpMixin, DetailView):
"""
if hasattr(self, 'obj'):
return getattr(self, 'obj', None)
if hasattr(self, "obj"):
return getattr(self, "obj", None)
# Get the queryset for the help entries the user can access
if not queryset:
@ -323,9 +323,7 @@ class HelpDetailView(HelpMixin, DetailView):
# Check if this object was requested in a valid manner
if not obj:
return HttpResponseBadRequest(
f"No ({category}/{topic})s found matching the query."
)
return HttpResponseBadRequest(f"No ({category}/{topic})s found matching the query.")
else:
# cache the object if one was found
self.obj = obj

View file

@ -29,14 +29,17 @@ def _gamestats():
nobjs = ObjectDB.objects.count()
nobjs = nobjs or 1 # fix zero-div error with empty database
Character = class_from_module(settings.BASE_CHARACTER_TYPECLASS,
fallback=settings.FALLBACK_CHARACTER_TYPECLASS)
Character = class_from_module(
settings.BASE_CHARACTER_TYPECLASS, fallback=settings.FALLBACK_CHARACTER_TYPECLASS
)
nchars = Character.objects.all_family().count()
Room = class_from_module(settings.BASE_ROOM_TYPECLASS,
fallback=settings.FALLBACK_ROOM_TYPECLASS)
Room = class_from_module(
settings.BASE_ROOM_TYPECLASS, fallback=settings.FALLBACK_ROOM_TYPECLASS
)
nrooms = Room.objects.all_family().count()
Exit = class_from_module(settings.BASE_EXIT_TYPECLASS,
fallback=settings.FALLBACK_EXIT_TYPECLASS)
Exit = class_from_module(
settings.BASE_EXIT_TYPECLASS, fallback=settings.FALLBACK_EXIT_TYPECLASS
)
nexits = Exit.objects.all_family().count()
nothers = nobjs - nchars - nrooms - nexits

View file

@ -11,8 +11,7 @@ from django.core.exceptions import PermissionDenied
from django.contrib import messages
from evennia.utils import class_from_module
from django.utils.text import slugify
from .mixins import (
EvenniaCreateView, EvenniaDeleteView, EvenniaUpdateView, EvenniaDetailView)
from .mixins import EvenniaCreateView, EvenniaDeleteView, EvenniaUpdateView, EvenniaDetailView
class ObjectDetailView(EvenniaDetailView):
@ -35,8 +34,9 @@ class ObjectDetailView(EvenniaDetailView):
#
# So when you extend it, this line should look simple, like:
# model = Object
model = class_from_module(settings.BASE_OBJECT_TYPECLASS,
fallback=settings.FALLBACK_OBJECT_TYPECLASS)
model = class_from_module(
settings.BASE_OBJECT_TYPECLASS, fallback=settings.FALLBACK_OBJECT_TYPECLASS
)
# What HTML template you wish to use to display this page.
template_name = "website/object_detail.html"
@ -139,8 +139,9 @@ class ObjectCreateView(LoginRequiredMixin, EvenniaCreateView):
"""
model = class_from_module(settings.BASE_OBJECT_TYPECLASS,
fallback=settings.FALLBACK_OBJECT_TYPECLASS)
model = class_from_module(
settings.BASE_OBJECT_TYPECLASS, fallback=settings.FALLBACK_OBJECT_TYPECLASS
)
class ObjectDeleteView(LoginRequiredMixin, ObjectDetailView, EvenniaDeleteView):
@ -155,8 +156,9 @@ class ObjectDeleteView(LoginRequiredMixin, ObjectDetailView, EvenniaDeleteView):
"""
# -- Django constructs --
model = class_from_module(settings.BASE_OBJECT_TYPECLASS,
fallback=settings.FALLBACK_OBJECT_TYPECLASS)
model = class_from_module(
settings.BASE_OBJECT_TYPECLASS, fallback=settings.FALLBACK_OBJECT_TYPECLASS
)
template_name = "website/object_confirm_delete.html"
# -- Evennia constructs --
@ -178,8 +180,9 @@ class ObjectUpdateView(LoginRequiredMixin, ObjectDetailView, EvenniaUpdateView):
"""
# -- Django constructs --
model = class_from_module(settings.BASE_OBJECT_TYPECLASS,
fallback=settings.FALLBACK_OBJECT_TYPECLASS)
model = class_from_module(
settings.BASE_OBJECT_TYPECLASS, fallback=settings.FALLBACK_OBJECT_TYPECLASS
)
# -- Evennia constructs --
access_type = "edit"