mirror of
https://github.com/evennia/evennia.git
synced 2026-03-31 04:57:16 +02:00
Add helpentry api
This commit is contained in:
parent
8b834a6016
commit
231deab392
5 changed files with 199 additions and 44 deletions
|
|
@ -5,6 +5,7 @@ that is retrieved in GET requests. By default, Django Rest Framework uses the
|
|||
documentation specifically regarding DRF integration.
|
||||
|
||||
https://django-filter.readthedocs.io/en/latest/guide/rest_framework.html
|
||||
|
||||
"""
|
||||
from typing import Union
|
||||
from django.db.models import Q
|
||||
|
|
@ -25,6 +26,7 @@ def get_tag_query(tag_type: Union[str, None], key: str) -> Q:
|
|||
|
||||
Returns:
|
||||
A Q object that for searching by this tag type and name
|
||||
|
||||
"""
|
||||
return Q(db_tags__db_tagtype=tag_type) & Q(db_tags__db_key__iexact=key)
|
||||
|
||||
|
|
@ -32,6 +34,7 @@ def get_tag_query(tag_type: Union[str, None], key: str) -> Q:
|
|||
class TagTypeFilter(CharFilter):
|
||||
"""
|
||||
This class lets you create different filters for tags of a specified db_tagtype.
|
||||
|
||||
"""
|
||||
|
||||
tag_type = None
|
||||
|
|
@ -60,11 +63,14 @@ SHARED_FIELDS = ["db_key", "db_typeclass_path", "db_tags__db_key", "db_tags__db_
|
|||
|
||||
|
||||
class BaseTypeclassFilterSet(FilterSet):
|
||||
"""A parent class with filters for aliases and permissions"""
|
||||
"""
|
||||
A parent class with filters for aliases and permissions
|
||||
|
||||
"""
|
||||
|
||||
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_key")
|
||||
alias = AliasFilter(lookup_expr="iexact")
|
||||
permission = PermissionFilter(lookup_expr="iexact")
|
||||
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_key")
|
||||
|
||||
@staticmethod
|
||||
def filter_name(queryset, name, value):
|
||||
|
|
@ -84,7 +90,10 @@ class BaseTypeclassFilterSet(FilterSet):
|
|||
|
||||
|
||||
class ObjectDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for ObjectDB instances - characters, rooms, exits, etc"""
|
||||
"""
|
||||
This adds filters for ObjectDB instances - characters, rooms, exits, etc
|
||||
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = ObjectDB
|
||||
|
|
@ -103,7 +112,9 @@ class AccountDBFilterSet(BaseTypeclassFilterSet):
|
|||
|
||||
class Meta:
|
||||
model = AccountDB
|
||||
fields = SHARED_FIELDS + ["username", "db_is_connected", "db_is_bot"]
|
||||
fields = [fi for fi in (SHARED_FIELDS + ["username", "db_is_connected", "db_is_bot"])
|
||||
if fi != 'db_key']
|
||||
|
||||
|
||||
|
||||
class ScriptDBFilterSet(BaseTypeclassFilterSet):
|
||||
|
|
@ -121,3 +132,16 @@ class ScriptDBFilterSet(BaseTypeclassFilterSet):
|
|||
"db_persistent",
|
||||
"db_interval",
|
||||
]
|
||||
|
||||
|
||||
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")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ those decisions in the hands of clients, and are more focused on converting
|
|||
data from the server to JSON (serialization) for a response, and validating
|
||||
and converting JSON data sent from clients to our enpoints into python objects,
|
||||
often django model instances, that we can use (deserialization).
|
||||
|
||||
"""
|
||||
|
||||
from rest_framework import serializers
|
||||
|
|
@ -16,9 +17,14 @@ from evennia.accounts.accounts import DefaultAccount
|
|||
from evennia.scripts.models import ScriptDB
|
||||
from evennia.typeclasses.attributes import Attribute
|
||||
from evennia.typeclasses.tags import Tag
|
||||
from evennia.help.models import HelpEntry
|
||||
|
||||
|
||||
class AttributeSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
Serialize Attribute views.
|
||||
|
||||
"""
|
||||
value_display = serializers.SerializerMethodField(source="value")
|
||||
db_value = serializers.CharField(write_only=True, required=False)
|
||||
|
||||
|
|
@ -35,6 +41,7 @@ class AttributeSerializer(serializers.ModelSerializer):
|
|||
|
||||
Returns:
|
||||
The Attribute's value in string format
|
||||
|
||||
"""
|
||||
if obj.db_strvalue:
|
||||
return obj.db_strvalue
|
||||
|
|
@ -53,13 +60,17 @@ class SimpleObjectDBSerializer(serializers.ModelSerializer):
|
|||
fields = ["id", "db_key"]
|
||||
|
||||
|
||||
class TypeclassSerializerMixin(object):
|
||||
"""Mixin that contains types shared by typeclasses. A note about tags, aliases, and permissions. You
|
||||
might note that the methods and fields are defined here, but they're included explicitly in each child
|
||||
class. What gives? It's a DRF error: serializer method fields which are inherited do not resolve correctly
|
||||
in child classes, and as of this current version (3.11) you must have them in the child classes explicitly
|
||||
to avoid field errors. Similarly, the child classes must contain the attribute serializer explicitly to
|
||||
not have them render PK-related fields.
|
||||
class TypeclassSerializerMixin:
|
||||
"""
|
||||
Mixin that contains types shared by typeclasses. A note about tags,
|
||||
aliases, and permissions. You might note that the methods and fields are
|
||||
defined here, but they're included explicitly in each child class. What
|
||||
gives? It's a DRF error: serializer method fields which are inherited do
|
||||
not resolve correctly in child classes, and as of this current version
|
||||
(3.11) you must have them in the child classes explicitly to avoid field
|
||||
errors. Similarly, the child classes must contain the attribute serializer
|
||||
explicitly to not have them render PK-related fields.
|
||||
|
||||
"""
|
||||
|
||||
shared_fields = [
|
||||
|
|
@ -135,7 +146,24 @@ class TypeclassSerializerMixin(object):
|
|||
return AttributeSerializer(obj.nicks.all(), many=True).data
|
||||
|
||||
|
||||
class TypeclassListSerializerMixin:
|
||||
"""
|
||||
Shortened serializer for list views.
|
||||
|
||||
"""
|
||||
shared_fields = [
|
||||
"id",
|
||||
"db_key",
|
||||
"db_typeclass_path",
|
||||
]
|
||||
|
||||
|
||||
class ObjectDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
Serializing Objects.
|
||||
|
||||
"""
|
||||
|
||||
attributes = serializers.SerializerMethodField()
|
||||
nicks = serializers.SerializerMethodField()
|
||||
contents = serializers.SerializerMethodField()
|
||||
|
|
@ -182,8 +210,25 @@ class ObjectDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
return SimpleObjectDBSerializer(non_exits, many=True).data
|
||||
|
||||
|
||||
class ObjectListSerializer(TypeclassListSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
Shortened representation for listings.]
|
||||
|
||||
"""
|
||||
class Meta:
|
||||
model = DefaultObject
|
||||
fields = [
|
||||
"db_location",
|
||||
"db_home",
|
||||
] + TypeclassListSerializerMixin.shared_fields
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
class AccountSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
||||
"""This uses the DefaultAccount object to have access to the sessions property"""
|
||||
"""
|
||||
This uses the DefaultAccount object to have access to the sessions property
|
||||
|
||||
"""
|
||||
|
||||
attributes = serializers.SerializerMethodField()
|
||||
nicks = serializers.SerializerMethodField()
|
||||
|
|
@ -211,7 +256,23 @@ class AccountSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
class AccountListSerializer(TypeclassListSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
A shortened form for listing.
|
||||
|
||||
"""
|
||||
class Meta:
|
||||
model = DefaultAccount
|
||||
fields = ["username"] + [
|
||||
fi for fi in TypeclassListSerializerMixin.shared_fields if fi != "db_key"]
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
class ScriptDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
Serializing Account.
|
||||
|
||||
"""
|
||||
attributes = serializers.SerializerMethodField()
|
||||
tags = serializers.SerializerMethodField()
|
||||
aliases = serializers.SerializerMethodField()
|
||||
|
|
@ -227,3 +288,47 @@ class ScriptDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
"db_repeats",
|
||||
] + TypeclassSerializerMixin.shared_fields
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
class ScriptListSerializer(TypeclassListSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
Shortened form for listing.
|
||||
|
||||
"""
|
||||
class Meta:
|
||||
model = ScriptDB
|
||||
fields = [
|
||||
"db_interval",
|
||||
"db_persistent",
|
||||
"db_start_delay",
|
||||
"db_is_active",
|
||||
"db_repeats",
|
||||
] + TypeclassListSerializerMixin.shared_fields
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
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"
|
||||
]
|
||||
|
||||
class HelpListSerializer(TypeclassListSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
Shortened form for listings.
|
||||
|
||||
"""
|
||||
class Meta:
|
||||
model = HelpEntry
|
||||
fields = [
|
||||
"id", "db_key", "db_help_category", "db_date_created",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
"""Tests for the REST API"""
|
||||
"""
|
||||
Tests for the REST API.
|
||||
|
||||
"""
|
||||
from evennia.utils.test_resources import EvenniaTest
|
||||
from evennia.web.api import serializers
|
||||
from rest_framework.test import APIClient
|
||||
|
|
|
|||
|
|
@ -22,25 +22,19 @@ from django.views.generic import TemplateView
|
|||
from rest_framework.schemas import get_schema_view
|
||||
|
||||
from evennia.web.api.root import APIRootRouter
|
||||
from evennia.web.api.views import (
|
||||
ObjectDBViewSet,
|
||||
AccountDBViewSet,
|
||||
CharacterViewSet,
|
||||
ExitViewSet,
|
||||
RoomViewSet,
|
||||
ScriptDBViewSet,
|
||||
)
|
||||
from evennia.web.api import views
|
||||
|
||||
app_name = "api"
|
||||
|
||||
router = APIRootRouter()
|
||||
router.trailing_slash = "/?"
|
||||
router.register(r"accounts", AccountDBViewSet, basename="account")
|
||||
router.register(r"objects", ObjectDBViewSet, basename="object")
|
||||
router.register(r"characters", CharacterViewSet, basename="character")
|
||||
router.register(r"exits", ExitViewSet, basename="exit")
|
||||
router.register(r"rooms", RoomViewSet, basename="room")
|
||||
router.register(r"scripts", ScriptDBViewSet, basename="script")
|
||||
router.register(r"accounts", views.AccountDBViewSet, basename="account")
|
||||
router.register(r"objects", views.ObjectDBViewSet, basename="object")
|
||||
router.register(r"characters", views.CharacterViewSet, basename="character")
|
||||
router.register(r"exits", views.ExitViewSet, basename="exit")
|
||||
router.register(r"rooms", views.RoomViewSet, basename="room")
|
||||
router.register(r"scripts", views.ScriptDBViewSet, basename="script")
|
||||
router.register(r"helpentries", views.HelpViewSet, basename="script")
|
||||
|
||||
urlpatterns = router.urls
|
||||
|
||||
|
|
|
|||
|
|
@ -15,17 +15,29 @@ from evennia.objects.models import ObjectDB
|
|||
from evennia.objects.objects import DefaultCharacter, DefaultExit, DefaultRoom
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.scripts.models import ScriptDB
|
||||
from evennia.web.api.serializers import (
|
||||
ObjectDBSerializer,
|
||||
AccountSerializer,
|
||||
ScriptDBSerializer,
|
||||
AttributeSerializer,
|
||||
)
|
||||
from evennia.web.api.filters import ObjectDBFilterSet, AccountDBFilterSet, ScriptDBFilterSet
|
||||
from evennia.help.models import HelpEntry
|
||||
from evennia.web.api import serializers
|
||||
from evennia.web.api import filters
|
||||
from evennia.web.api.permissions import EvenniaPermission
|
||||
|
||||
|
||||
class TypeclassViewSetMixin:
|
||||
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 hasattr(self, "list_serializer_class"):
|
||||
return self.list_serializer_class
|
||||
return self.serializer_class
|
||||
|
||||
|
||||
class TypeclassViewSetMixin(GeneralViewSetMixin):
|
||||
"""
|
||||
This mixin adds some shared functionality to each viewset of a typeclass. They all use the same
|
||||
permission classes and filter backend. You can override any of these in your own viewsets.
|
||||
|
|
@ -53,7 +65,7 @@ class TypeclassViewSetMixin:
|
|||
it if no db_value is provided.
|
||||
|
||||
"""
|
||||
attr = AttributeSerializer(data=request.data)
|
||||
attr = serializers.AttributeSerializer(data=request.data)
|
||||
obj = self.get_object()
|
||||
if attr.is_valid(raise_exception=True):
|
||||
key = attr.validated_data["db_key"]
|
||||
|
|
@ -69,7 +81,7 @@ class TypeclassViewSetMixin:
|
|||
else:
|
||||
handler.remove(key=key, category=category)
|
||||
return Response(
|
||||
AttributeSerializer(obj.db_attributes.all(), many=True).data,
|
||||
serializers.AttributeSerializer(obj.db_attributes.all(), many=True).data,
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
return Response(attr.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -86,9 +98,10 @@ class ObjectDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
|||
# instances. Serializers are similar to django forms, used for the
|
||||
# transmitting of data (typically json).
|
||||
|
||||
serializer_class = ObjectDBSerializer
|
||||
serializer_class = serializers.ObjectDBSerializer
|
||||
queryset = ObjectDB.objects.all()
|
||||
filterset_class = ObjectDBFilterSet
|
||||
filterset_class = filters.ObjectDBFilterSet
|
||||
list_serializer_class = serializers.ObjectListSerializer
|
||||
|
||||
|
||||
class CharacterViewSet(ObjectDBViewSet):
|
||||
|
|
@ -96,10 +109,10 @@ 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
|
||||
)
|
||||
list_serializer_class = serializers.ObjectListSerializer
|
||||
|
||||
|
||||
class RoomViewSet(ObjectDBViewSet):
|
||||
|
|
@ -109,6 +122,7 @@ class RoomViewSet(ObjectDBViewSet):
|
|||
"""
|
||||
|
||||
queryset = DefaultRoom.objects.typeclass_search(DefaultRoom.path, include_children=True)
|
||||
list_serializer_class = serializers.ObjectListSerializer
|
||||
|
||||
|
||||
class ExitViewSet(ObjectDBViewSet):
|
||||
|
|
@ -119,6 +133,7 @@ class ExitViewSet(ObjectDBViewSet):
|
|||
"""
|
||||
|
||||
queryset = DefaultExit.objects.typeclass_search(DefaultExit.path, include_children=True)
|
||||
list_serializer_class = serializers.ObjectListSerializer
|
||||
|
||||
|
||||
class AccountDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
||||
|
|
@ -127,9 +142,10 @@ class AccountDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
|||
|
||||
"""
|
||||
|
||||
serializer_class = AccountSerializer
|
||||
serializer_class = serializers.AccountSerializer
|
||||
queryset = AccountDB.objects.all()
|
||||
filterset_class = AccountDBFilterSet
|
||||
filterset_class = filters.AccountDBFilterSet
|
||||
list_serializer_class = serializers.AccountListSerializer
|
||||
|
||||
|
||||
class ScriptDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
||||
|
|
@ -139,6 +155,19 @@ class ScriptDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
|||
|
||||
"""
|
||||
|
||||
serializer_class = ScriptDBSerializer
|
||||
serializer_class = serializers.ScriptDBSerializer
|
||||
queryset = ScriptDB.objects.all()
|
||||
filterset_class = ScriptDBFilterSet
|
||||
filterset_class = filters.ScriptDBFilterSet
|
||||
list_serializer_class = serializers.ScriptListSerializer
|
||||
|
||||
|
||||
class HelpViewSet(GeneralViewSetMixin, ModelViewSet):
|
||||
"""
|
||||
Database-stored help entries.
|
||||
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
|
||||
list_serializer_class = serializers.HelpListSerializer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue