Ran black on sources
This commit is contained in:
parent
cc5aa91be1
commit
21d62e651a
19 changed files with 362 additions and 322 deletions
|
|
@ -33,6 +33,7 @@ class TagTypeFilter(CharFilter):
|
|||
"""
|
||||
This class lets you create different filters for tags of a specified db_tagtype.
|
||||
"""
|
||||
|
||||
tag_type = None
|
||||
|
||||
def filter(self, qs, value):
|
||||
|
|
@ -45,11 +46,13 @@ class TagTypeFilter(CharFilter):
|
|||
|
||||
class AliasFilter(TagTypeFilter):
|
||||
"""A filter for objects by their aliases (tags with a tagtype of 'alias'"""
|
||||
|
||||
tag_type = "alias"
|
||||
|
||||
|
||||
class PermissionFilter(TagTypeFilter):
|
||||
"""A filter for objects by their permissions (tags with a tagtype of 'permission'"""
|
||||
|
||||
tag_type = "permission"
|
||||
|
||||
|
||||
|
|
@ -58,6 +61,7 @@ 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"""
|
||||
|
||||
alias = AliasFilter(lookup_expr="iexact")
|
||||
permission = PermissionFilter(lookup_expr="iexact")
|
||||
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="db_key")
|
||||
|
|
@ -81,14 +85,20 @@ class BaseTypeclassFilterSet(FilterSet):
|
|||
|
||||
class ObjectDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for ObjectDB instances - characters, rooms, exits, etc"""
|
||||
|
||||
class Meta:
|
||||
model = ObjectDB
|
||||
fields = SHARED_FIELDS + ["db_location__db_key", "db_home__db_key", "db_location__id",
|
||||
"db_home__id"]
|
||||
fields = SHARED_FIELDS + [
|
||||
"db_location__db_key",
|
||||
"db_home__db_key",
|
||||
"db_location__id",
|
||||
"db_home__id",
|
||||
]
|
||||
|
||||
|
||||
class AccountDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for Account objects"""
|
||||
|
||||
name = CharFilter(lookup_expr="iexact", method="filter_name", field_name="username")
|
||||
|
||||
class Meta:
|
||||
|
|
@ -98,7 +108,16 @@ class AccountDBFilterSet(BaseTypeclassFilterSet):
|
|||
|
||||
class ScriptDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for Script objects"""
|
||||
|
||||
class Meta:
|
||||
model = ScriptDB
|
||||
fields = SHARED_FIELDS + ["db_desc", "db_obj__db_key", "db_obj__id", "db_account__id",
|
||||
"db_account__username", "db_is_active", "db_persistent", "db_interval"]
|
||||
fields = SHARED_FIELDS + [
|
||||
"db_desc",
|
||||
"db_obj__db_key",
|
||||
"db_obj__id",
|
||||
"db_account__id",
|
||||
"db_account__username",
|
||||
"db_is_active",
|
||||
"db_persistent",
|
||||
"db_interval",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class EvenniaPermission(permissions.BasePermission):
|
|||
Evennia's permission structure. Based on the action in a given
|
||||
view, we'll check a corresponding Evennia access/lock check.
|
||||
"""
|
||||
|
||||
# subclass this to change these permissions
|
||||
MINIMUM_LIST_PERMISSION = settings.REST_FRAMEWORK.get("DEFAULT_LIST_PERMISSION", "builder")
|
||||
MINIMUM_CREATE_PERMISSION = settings.REST_FRAMEWORK.get("DEFAULT_CREATE_PERMISSION", "builder")
|
||||
|
|
|
|||
|
|
@ -62,7 +62,15 @@ class TypeclassSerializerMixin(object):
|
|||
not have them render PK-related fields.
|
||||
"""
|
||||
|
||||
shared_fields = ["id", "db_key", "attributes", "db_typeclass_path", "aliases", "tags", "permissions"]
|
||||
shared_fields = [
|
||||
"id",
|
||||
"db_key",
|
||||
"attributes",
|
||||
"db_typeclass_path",
|
||||
"aliases",
|
||||
"tags",
|
||||
"permissions",
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get_tags(obj):
|
||||
|
|
@ -98,7 +106,9 @@ class TypeclassSerializerMixin(object):
|
|||
Returns:
|
||||
List of TagSerializer data
|
||||
"""
|
||||
return TagSerializer(obj.permissions.get(return_tagobj=True, return_list=True), many=True).data
|
||||
return TagSerializer(
|
||||
obj.permissions.get(return_tagobj=True, return_list=True), many=True
|
||||
).data
|
||||
|
||||
@staticmethod
|
||||
def get_attributes(obj):
|
||||
|
|
@ -136,7 +146,13 @@ class ObjectDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = DefaultObject
|
||||
fields = ["db_location", "db_home", "contents", "exits", "nicks"] + TypeclassSerializerMixin.shared_fields
|
||||
fields = [
|
||||
"db_location",
|
||||
"db_home",
|
||||
"contents",
|
||||
"exits",
|
||||
"nicks",
|
||||
] + TypeclassSerializerMixin.shared_fields
|
||||
read_only_fields = ["id"]
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -168,6 +184,7 @@ class ObjectDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
class AccountSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
||||
"""This uses the DefaultAccount object to have access to the sessions property"""
|
||||
|
||||
attributes = serializers.SerializerMethodField()
|
||||
nicks = serializers.SerializerMethodField()
|
||||
db_key = serializers.CharField(required=False)
|
||||
|
|
@ -202,6 +219,11 @@ class ScriptDBSerializer(TypeclassSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = ScriptDB
|
||||
fields = ["db_interval", "db_persistent", "db_start_delay",
|
||||
"db_is_active", "db_repeats"] + TypeclassSerializerMixin.shared_fields
|
||||
fields = [
|
||||
"db_interval",
|
||||
"db_persistent",
|
||||
"db_start_delay",
|
||||
"db_is_active",
|
||||
"db_repeats",
|
||||
] + TypeclassSerializerMixin.shared_fields
|
||||
read_only_fields = ["id"]
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@ urlpatterns = [
|
|||
]
|
||||
|
||||
|
||||
@override_settings(
|
||||
REST_API_ENABLED=True, ROOT_URLCONF=__name__, AUTH_USERNAME_VALIDATORS=[]
|
||||
)
|
||||
@override_settings(REST_API_ENABLED=True, ROOT_URLCONF=__name__, AUTH_USERNAME_VALIDATORS=[])
|
||||
class TestEvenniaRESTApi(EvenniaTest):
|
||||
client_class = APIClient
|
||||
maxDiff = None
|
||||
|
|
@ -37,27 +35,58 @@ class TestEvenniaRESTApi(EvenniaTest):
|
|||
|
||||
def get_view_details(self, action):
|
||||
"""Helper function for generating list of named tuples"""
|
||||
View = namedtuple("View", ["view_name", "obj", "list", "serializer", "create_data", "retrieve_data"])
|
||||
View = namedtuple(
|
||||
"View", ["view_name", "obj", "list", "serializer", "create_data", "retrieve_data"]
|
||||
)
|
||||
views = [
|
||||
View("object-%s" % action, self.obj1, [self.obj1, self.char1, self.exit, self.room1, self.room2, self.obj2,
|
||||
self.char2], serializers.ObjectDBSerializer,
|
||||
{"db_key": "object-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.obj1).data),
|
||||
View("character-%s" % action, self.char1, [self.char1, self.char2], serializers.ObjectDBSerializer,
|
||||
{"db_key": "character-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.char1).data),
|
||||
View("exit-%s" % action, self.exit, [self.exit], serializers.ObjectDBSerializer,
|
||||
{"db_key": "exit-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.exit).data),
|
||||
View("room-%s" % action, self.room1, [self.room1, self.room2], serializers.ObjectDBSerializer,
|
||||
{"db_key": "room-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.room1).data),
|
||||
View("script-%s" % action, self.script, [self.script], serializers.ScriptDBSerializer,
|
||||
{"db_key": "script-create-test-name"},
|
||||
serializers.ScriptDBSerializer(self.script).data),
|
||||
View("account-%s" % action, self.account2, [self.account, self.account2], serializers.AccountSerializer,
|
||||
{"username": "account-create-test-name"},
|
||||
serializers.AccountSerializer(self.account2).data),
|
||||
View(
|
||||
"object-%s" % action,
|
||||
self.obj1,
|
||||
[self.obj1, self.char1, self.exit, self.room1, self.room2, self.obj2, self.char2],
|
||||
serializers.ObjectDBSerializer,
|
||||
{"db_key": "object-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.obj1).data,
|
||||
),
|
||||
View(
|
||||
"character-%s" % action,
|
||||
self.char1,
|
||||
[self.char1, self.char2],
|
||||
serializers.ObjectDBSerializer,
|
||||
{"db_key": "character-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.char1).data,
|
||||
),
|
||||
View(
|
||||
"exit-%s" % action,
|
||||
self.exit,
|
||||
[self.exit],
|
||||
serializers.ObjectDBSerializer,
|
||||
{"db_key": "exit-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.exit).data,
|
||||
),
|
||||
View(
|
||||
"room-%s" % action,
|
||||
self.room1,
|
||||
[self.room1, self.room2],
|
||||
serializers.ObjectDBSerializer,
|
||||
{"db_key": "room-create-test-name"},
|
||||
serializers.ObjectDBSerializer(self.room1).data,
|
||||
),
|
||||
View(
|
||||
"script-%s" % action,
|
||||
self.script,
|
||||
[self.script],
|
||||
serializers.ScriptDBSerializer,
|
||||
{"db_key": "script-create-test-name"},
|
||||
serializers.ScriptDBSerializer(self.script).data,
|
||||
),
|
||||
View(
|
||||
"account-%s" % action,
|
||||
self.account2,
|
||||
[self.account, self.account2],
|
||||
serializers.AccountSerializer,
|
||||
{"username": "account-create-test-name"},
|
||||
serializers.AccountSerializer(self.account2).data,
|
||||
),
|
||||
]
|
||||
return views
|
||||
|
||||
|
|
@ -65,9 +94,7 @@ class TestEvenniaRESTApi(EvenniaTest):
|
|||
views = self.get_view_details("detail")
|
||||
for view in views:
|
||||
with self.subTest(msg="Testing {} retrieve".format(view.view_name)):
|
||||
view_url = reverse(
|
||||
"api:{}".format(view.view_name), kwargs={"pk": view.obj.pk}
|
||||
)
|
||||
view_url = reverse("api:{}".format(view.view_name), kwargs={"pk": view.obj.pk})
|
||||
response = self.client.get(view_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertDictEqual(response.data, view.retrieve_data)
|
||||
|
|
@ -76,9 +103,7 @@ class TestEvenniaRESTApi(EvenniaTest):
|
|||
views = self.get_view_details("detail")
|
||||
for view in views:
|
||||
with self.subTest(msg="Testing {} update".format(view.view_name)):
|
||||
view_url = reverse(
|
||||
"api:{}".format(view.view_name), kwargs={"pk": view.obj.pk}
|
||||
)
|
||||
view_url = reverse("api:{}".format(view.view_name), kwargs={"pk": view.obj.pk})
|
||||
# test both PUT (update) and PATCH (partial update) here
|
||||
for new_key, method in (("foobar", "put"), ("fizzbuzz", "patch")):
|
||||
field = "username" if "account" in view.view_name else "db_key"
|
||||
|
|
@ -93,9 +118,7 @@ class TestEvenniaRESTApi(EvenniaTest):
|
|||
views = self.get_view_details("detail")
|
||||
for view in views:
|
||||
with self.subTest(msg="Testing {} delete".format(view.view_name)):
|
||||
view_url = reverse(
|
||||
"api:{}".format(view.view_name), kwargs={"pk": view.obj.pk}
|
||||
)
|
||||
view_url = reverse("api:{}".format(view.view_name), kwargs={"pk": view.obj.pk})
|
||||
response = self.client.delete(view_url)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
with self.assertRaises(ObjectDoesNotExist):
|
||||
|
|
@ -108,7 +131,9 @@ class TestEvenniaRESTApi(EvenniaTest):
|
|||
view_url = reverse(f"api:{view.view_name}")
|
||||
response = self.client.get(view_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertCountEqual(response.data['results'], [view.serializer(obj).data for obj in view.list])
|
||||
self.assertCountEqual(
|
||||
response.data["results"], [view.serializer(obj).data for obj in view.list]
|
||||
)
|
||||
|
||||
def test_create(self):
|
||||
views = self.get_view_details("list")
|
||||
|
|
|
|||
|
|
@ -22,18 +22,18 @@ from evennia.web.api.views import (
|
|||
CharacterViewSet,
|
||||
ExitViewSet,
|
||||
RoomViewSet,
|
||||
ScriptDBViewSet
|
||||
ScriptDBViewSet,
|
||||
)
|
||||
|
||||
app_name = "api"
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
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", 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")
|
||||
|
||||
urlpatterns = router.urls
|
||||
|
|
|
|||
|
|
@ -14,7 +14,12 @@ 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.serializers import (
|
||||
ObjectDBSerializer,
|
||||
AccountSerializer,
|
||||
ScriptDBSerializer,
|
||||
AttributeSerializer,
|
||||
)
|
||||
from evennia.web.api.filters import ObjectDBFilterSet, AccountDBFilterSet, ScriptDBFilterSet
|
||||
from evennia.web.api.permissions import EvenniaPermission
|
||||
|
||||
|
|
@ -24,6 +29,7 @@ class TypeclassViewSetMixin(object):
|
|||
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.
|
||||
"""
|
||||
|
||||
# permission classes determine who is authorized to call the view
|
||||
permission_classes = [EvenniaPermission]
|
||||
# the filter backend allows for retrieval views to have filter arguments passed to it,
|
||||
|
|
@ -58,7 +64,10 @@ class TypeclassViewSetMixin(object):
|
|||
handler.add(key=key, value=value, category=category)
|
||||
else:
|
||||
handler.remove(key=key, category=category)
|
||||
return Response(AttributeSerializer(obj.db_attributes.all(), many=True).data, status=status.HTTP_200_OK)
|
||||
return Response(
|
||||
AttributeSerializer(obj.db_attributes.all(), many=True).data,
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
return Response(attr.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
|
|
@ -69,6 +78,7 @@ class ObjectDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
|||
instances. Serializers are similar to django forms, used for the
|
||||
transmitting of data (typically json).
|
||||
"""
|
||||
|
||||
serializer_class = ObjectDBSerializer
|
||||
queryset = ObjectDB.objects.all()
|
||||
filterset_class = ObjectDBFilterSet
|
||||
|
|
@ -79,21 +89,27 @@ class CharacterViewSet(ObjectDBViewSet):
|
|||
This overrides the queryset to only retrieve Character objects
|
||||
based on your DefaultCharacter typeclass path.
|
||||
"""
|
||||
queryset = DefaultCharacter.objects.typeclass_search(DefaultCharacter.path, include_children=True)
|
||||
|
||||
queryset = DefaultCharacter.objects.typeclass_search(
|
||||
DefaultCharacter.path, include_children=True
|
||||
)
|
||||
|
||||
|
||||
class RoomViewSet(ObjectDBViewSet):
|
||||
"""Viewset for Room objects"""
|
||||
|
||||
queryset = DefaultRoom.objects.typeclass_search(DefaultRoom.path, include_children=True)
|
||||
|
||||
|
||||
class ExitViewSet(ObjectDBViewSet):
|
||||
"""Viewset for Exit objects"""
|
||||
|
||||
queryset = DefaultExit.objects.typeclass_search(DefaultExit.path, include_children=True)
|
||||
|
||||
|
||||
class AccountDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
||||
"""Viewset for Account objects"""
|
||||
|
||||
serializer_class = AccountSerializer
|
||||
queryset = AccountDB.objects.all()
|
||||
filterset_class = AccountDBFilterSet
|
||||
|
|
@ -101,6 +117,7 @@ class AccountDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
|||
|
||||
class ScriptDBViewSet(TypeclassViewSetMixin, ModelViewSet):
|
||||
"""Viewset for Script objects"""
|
||||
|
||||
serializer_class = ScriptDBSerializer
|
||||
queryset = ScriptDB.objects.all()
|
||||
filterset_class = ScriptDBFilterSet
|
||||
|
|
|
|||
|
|
@ -24,4 +24,4 @@ urlpatterns = [
|
|||
]
|
||||
|
||||
if settings.REST_API_ENABLED:
|
||||
urlpatterns += [url(r'^api/', include("evennia.web.api.urls", namespace="api"))]
|
||||
urlpatterns += [url(r"^api/", include("evennia.web.api.urls", namespace="api"))]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue