import graphene from graphene import relay from api.types import FailureNode, SuccessNode from api.utils import get_object from books.models import Module, ContentBlock, Chapter from books.models.snapshot import Snapshot from books.schema.nodes import SnapshotNode, ModuleNode from users.models import SchoolClass class NotOwner(graphene.ObjectType): class Meta: interfaces = (FailureNode,) class Success(graphene.ObjectType): class Meta: interfaces = (SuccessNode,) NotOwnerFailure = NotOwner(reason="Not the owner") DeleteSnapshotSuccess = Success(message='Snapshot deleted successfully') class UpdateSnapshotResult(graphene.Union): class Meta: types = (SnapshotNode, NotOwner,) class DeleteSnapshotResult(graphene.Union): class Meta: types = (Success, NotOwner,) class CreateSnapshot(relay.ClientIDMutation): class Input: module = graphene.String(required=True) selected_class = graphene.ID(required=True) snapshot = graphene.Field(SnapshotNode) success = graphene.Boolean() @classmethod def mutate_and_get_payload(cls, root, info, **args): module_slug = args.get('module') module = Module.objects.get(slug=module_slug) user = info.context.user # todo: check user # raise NotImplementedError('Permissions') selected_class_id = args.get('selected_class') selected_class = get_object(SchoolClass, selected_class_id) snapshot = Snapshot.objects.create_snapshot(module, selected_class, user) return cls(snapshot=snapshot, success=True) class UpdateSnapshot(relay.ClientIDMutation): class Input: id = graphene.ID(required=True) title = graphene.String() snapshot = graphene.Field(UpdateSnapshotResult) @classmethod def mutate_and_get_payload(cls, root, info, **args): id = args.get('id') title = args.get('title') user = info.context.user snapshot = get_object(Snapshot, id) if snapshot.creator != user: return cls(snapshot=NotOwnerFailure) if title is not None: snapshot.title = title snapshot.save() return cls(snapshot=snapshot) class DeleteSnapshot(relay.ClientIDMutation): class Input: id = graphene.ID(required=True) result = graphene.Field(DeleteSnapshotResult) @classmethod def mutate_and_get_payload(cls, root, info, **args): id = args.get('id') user = info.context.user snapshot = get_object(Snapshot, id) if snapshot.creator != user: return cls(result=NotOwnerFailure) snapshot.delete() return cls(result=DeleteSnapshotSuccess) class ApplySnapshot(relay.ClientIDMutation): class Input: snapshot = graphene.ID(required=True) selected_class = graphene.ID(required=True) success = graphene.Boolean() module = graphene.Field(ModuleNode) @classmethod def mutate_and_get_payload(cls, root, info, **args): snapshot_id = args.get('snapshot') snapshot = get_object(Snapshot, snapshot_id) user = info.context.user selected_class_id = args.get('selected_class') selected_class = get_object(SchoolClass, selected_class_id) # permission check if not selected_class.users.filter(username=user.username).exists() or not user.is_teacher(): raise PermissionError('Not allowed') # reset everything snapshot.reset(user, selected_class) # apply snapshot snapshot.apply(user, selected_class) return cls(success=True, module=snapshot.module) class ShareSnapshot(relay.ClientIDMutation): class Input: snapshot = graphene.ID(required=True) shared = graphene.Boolean(required=True) success = graphene.Boolean(required=True) snapshot = graphene.Field(SnapshotNode) @classmethod def mutate_and_get_payload(cls, root, info, **args): snapshot_id = args.get('snapshot') shared = args.get('shared') user = info.context.user snapshot = get_object(Snapshot, snapshot_id) if snapshot.creator != user: raise PermissionError('Not permitted') snapshot.shared = shared snapshot.save() return cls(success=True, snapshot=snapshot)