Ran black on sources

This commit is contained in:
Griatch 2020-04-12 12:19:15 +02:00
parent cc5aa91be1
commit 21d62e651a
19 changed files with 362 additions and 322 deletions

View file

@ -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",
]

View file

@ -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")

View file

@ -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"]

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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"))]