import graphene from django.db.models import Q from graphene import relay 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 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 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) # reset everything for chapter in Chapter.get_by_parent(snapshot.module): cb_qs = ContentBlock.get_by_parent(chapter) without_owner = Q(owner__isnull=True) no_snapshot = Q(contentblocksnapshot__isnull=True) owner_user = Q(owner=user) for cb in cb_qs.filter(without_owner & no_snapshot): cb.hidden_for.remove(selected_class) for cb in cb_qs.filter(owner_user): cb.visible_for.remove(selected_class) # apply snapshot if not selected_class.users.filter(username=user.username).exists() or not user.is_teacher(): raise PermissionError('Not allowed') for content_block in snapshot.hidden_content_blocks.all(): content_block.hidden_for.add(selected_class) for custom_content_block in snapshot.custom_content_blocks.all(): custom_content_block.to_regular_content_block(user, selected_class) for chapter_snapshot in snapshot.chapters.through.objects.all(): chapter = chapter_snapshot.chapter if chapter_snapshot.title_hidden: chapter.title_hidden_for.add(selected_class) if chapter_snapshot.description_hidden: chapter.description_hidden_for.add(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)