210 lines
7.4 KiB
Python
210 lines
7.4 KiB
Python
import graphene
|
|
from django.core.exceptions import PermissionDenied
|
|
from graphene import relay
|
|
from graphql_relay import to_global_id
|
|
|
|
from api.utils import get_object
|
|
from rooms.inputs import UpdateRoomArgument, AddRoomArgument, AddRoomEntryArgument, UpdateRoomEntryArgument
|
|
from rooms.models import Comment, Room, RoomEntry
|
|
from rooms.schema import CommentNode, RoomNode, RoomEntryNode
|
|
from rooms.serializers import RoomSerializer, RoomEntrySerializer
|
|
from users.models import SchoolClass, SchoolClassMember
|
|
|
|
|
|
class MutateRoom(relay.ClientIDMutation):
|
|
errors = graphene.List(graphene.String)
|
|
room = graphene.Field(RoomNode)
|
|
|
|
@classmethod
|
|
def mutate_and_get_payload(cls, *args, **kwargs):
|
|
room_data = kwargs.get('room')
|
|
school_class = get_object(SchoolClass, room_data.get('school_class').get('id'))
|
|
room_data['school_class'] = school_class.id
|
|
if room_data.get('id') is not None:
|
|
room = get_object(Room, room_data['id'])
|
|
serializer = RoomSerializer(room, data=room_data)
|
|
else:
|
|
serializer = RoomSerializer(data=room_data)
|
|
if serializer.is_valid():
|
|
serializer.save()
|
|
return cls(room=serializer.instance, errors=None)
|
|
|
|
return cls(room=None, errors=['{}: {}'.format(key, value) for key, value in serializer.errors.items()])
|
|
|
|
|
|
class AddRoom(MutateRoom):
|
|
class Input:
|
|
room = graphene.Argument(AddRoomArgument) # NB: can't be named AddRoomInput, otherwise graphene complains
|
|
|
|
@classmethod
|
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
|
user = info.context.user
|
|
if not user.is_teacher():
|
|
return cls(room=None, errors=['not allowed'])
|
|
|
|
room_data = kwargs.get('room')
|
|
school_class_id = user.selected_class.id
|
|
room_data['school_class'] = school_class_id
|
|
serializer = RoomSerializer(data=room_data)
|
|
if serializer.is_valid():
|
|
serializer.save()
|
|
return cls(room=serializer.instance)
|
|
|
|
return cls(room=None, errors=['{}: {}'.format(key, value) for key, value in serializer.errors.items()])
|
|
|
|
|
|
class UpdateRoom(MutateRoom):
|
|
class Input:
|
|
room = graphene.Argument(UpdateRoomArgument) # NB: can't be named ChangeRoomInput, otherwise graphene complains
|
|
|
|
|
|
class DeleteRoom(relay.ClientIDMutation):
|
|
class Input:
|
|
id = graphene.ID(required=True)
|
|
|
|
success = graphene.Boolean()
|
|
errors = graphene.List(graphene.String)
|
|
|
|
@classmethod
|
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
|
id = kwargs.get('id')
|
|
room = get_object(Room, id)
|
|
user = info.context.user
|
|
if not user.has_perm('users.can_manage_school_class_content'):
|
|
raise PermissionDenied('Missing permissions')
|
|
if room.school_class not in user.school_classes.all():
|
|
raise PermissionDenied('Permission denied: Incorrect school classes')
|
|
room.delete()
|
|
return cls(success=True)
|
|
|
|
|
|
class MutateRoomEntry(relay.ClientIDMutation):
|
|
room_entry = graphene.Field(RoomEntryNode)
|
|
errors = graphene.List(graphene.String)
|
|
|
|
@classmethod
|
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
|
room_entry_data = kwargs.get('room_entry')
|
|
room = None
|
|
room_slug = room_entry_data.get('room_slug')
|
|
|
|
if room_slug is not None:
|
|
room = Room.objects.get(slug=room_slug)
|
|
room_entry_data['room'] = room.id
|
|
|
|
if room_entry_data.get('slug') is not None:
|
|
serializer = cls.update_room_entry(info, room_entry_data)
|
|
else:
|
|
serializer = cls.add_room_entry(info, room_entry_data, room)
|
|
|
|
if serializer.is_valid():
|
|
serializer.save()
|
|
|
|
return cls(room_entry=serializer.instance)
|
|
|
|
return cls(room_entry=None, errors=['{}: {}'.format(key, value) for key, value in serializer.errors.items()])
|
|
|
|
@classmethod
|
|
def update_room_entry(cls, info, room_entry_data):
|
|
instance = RoomEntry.objects.get(slug=room_entry_data.get('slug'))
|
|
|
|
if not instance.room.school_class.is_user_in_schoolclass(info.context.user):
|
|
raise Exception('You are in the wrong class')
|
|
|
|
if instance.author.pk != info.context.user.pk:
|
|
raise Exception('You are not the author')
|
|
|
|
return RoomEntrySerializer(instance, data=room_entry_data, partial=True)
|
|
|
|
@classmethod
|
|
def add_room_entry(cls, info, room_entry_data, room):
|
|
if not room or not room.school_class.is_user_in_schoolclass(info.context.user):
|
|
raise PermissionDenied('You are in the wrong class')
|
|
|
|
room_entry_data['author'] = info.context.user.pk
|
|
return RoomEntrySerializer(data=room_entry_data)
|
|
|
|
|
|
class AddRoomEntry(MutateRoomEntry):
|
|
class Input:
|
|
room_entry = graphene.Argument(AddRoomEntryArgument)
|
|
|
|
|
|
class UpdateRoomEntry(MutateRoomEntry):
|
|
class Input:
|
|
room_entry = graphene.Argument(UpdateRoomEntryArgument)
|
|
|
|
|
|
class DeleteRoomEntry(relay.ClientIDMutation):
|
|
class Input:
|
|
slug = graphene.String(required=True)
|
|
|
|
success = graphene.Boolean()
|
|
room_slug = graphene.String()
|
|
room_id = graphene.ID()
|
|
errors = graphene.List(graphene.String)
|
|
|
|
@classmethod
|
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
|
slug = kwargs.get('slug')
|
|
room_entry = RoomEntry.objects.get(slug=slug)
|
|
if room_entry.author.pk != info.context.user.pk:
|
|
raise Exception('You are not the owner of this room entry')
|
|
room_id = to_global_id('RoomNode', room_entry.room.pk)
|
|
room_slug = room_entry.room.slug
|
|
room_entry.delete()
|
|
return cls(success=True, room_id=room_id, room_slug=room_slug)
|
|
|
|
|
|
class UpdateRoomVisibility(relay.ClientIDMutation):
|
|
class Input:
|
|
id = graphene.ID(required=True)
|
|
restricted = graphene.Boolean(required=True)
|
|
|
|
success = graphene.Boolean()
|
|
room = graphene.Field(RoomNode)
|
|
|
|
@classmethod
|
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
|
id = kwargs.get('id')
|
|
restricted = kwargs.get('restricted')
|
|
user = info.context.user
|
|
room = get_object(Room, id)
|
|
if not user.is_teacher() or not SchoolClassMember.objects.filter(active=True, user=user,
|
|
school_class=room.school_class).exists():
|
|
raise Exception('You are not permitted to do this')
|
|
room.restricted = restricted
|
|
room.save()
|
|
return cls(success=True, room=room)
|
|
|
|
|
|
class AddComment(relay.ClientIDMutation):
|
|
class Input:
|
|
comment = graphene.String(required=True)
|
|
room_entry = graphene.ID(required=True)
|
|
|
|
success = graphene.Boolean()
|
|
comment = graphene.Field(CommentNode)
|
|
|
|
@classmethod
|
|
def mutate_and_get_payload(cls, root, info, **args):
|
|
room_entry_id = args.get('room_entry')
|
|
text = args.get('comment')
|
|
user = info.context.user
|
|
|
|
room_entry = get_object(RoomEntry, room_entry_id)
|
|
comment = Comment.objects.create(text=text, room_entry=room_entry, owner=user)
|
|
|
|
return cls(success=True, comment=comment)
|
|
|
|
|
|
class RoomMutations:
|
|
update_room = UpdateRoom.Field()
|
|
add_room = AddRoom.Field()
|
|
delete_room = DeleteRoom.Field()
|
|
add_room_entry = AddRoomEntry.Field()
|
|
delete_room_entry = DeleteRoomEntry.Field()
|
|
update_room_entry = UpdateRoomEntry.Field()
|
|
add_comment = AddComment.Field()
|
|
update_room_visibility = UpdateRoomVisibility.Field()
|