import graphene from assignments.models import StudentSubmission from assignments.schema.types import AssignmentNode, StudentSubmissionNode from books.models import Chapter, ContentBlock, Module, RecentModule from books.schema.interfaces.module import ModuleInterface from books.schema.nodes.chapter import ChapterNode from books.schema.nodes.module_category import ModuleCategoryNode from books.schema.nodes.module_level import ModuleLevelNode from django.db.models import Q from graphene import relay from graphene_django import DjangoObjectType from graphene_django.filter import DjangoFilterConnectionField from notes.models import Highlight, ModuleBookmark from objectives.schema import ObjectiveGroupNode from surveys.models import Answer from surveys.schema import AnswerNode from wagtail.models import Page class ModuleNode(DjangoObjectType): class Meta: model = Module only_fields = [ "slug", "title", "meta_title", "teaser", "intro", "objective_groups", "assignments", "hero_image", "hero_source", "topic", "level", "category", ] filter_fields = { "slug": ["exact", "icontains", "in"], "title": ["exact", "icontains", "in"], } interfaces = (ModuleInterface,) chapters = graphene.List(ChapterNode) solutions_enabled = graphene.Boolean() bookmark = graphene.Field("notes.schema.ModuleBookmarkNode") my_submissions = graphene.List(StudentSubmissionNode) my_answers = graphene.List(AnswerNode) my_content_bookmarks = DjangoFilterConnectionField( "notes.schema.ContentBlockBookmarkNode" ) my_chapter_bookmarks = DjangoFilterConnectionField( "notes.schema.ChapterBookmarkNode" ) snapshots = graphene.List("books.schema.nodes.SnapshotNode") objective_groups = graphene.List(ObjectiveGroupNode) assignments = graphene.List(AssignmentNode) level = graphene.Field(ModuleLevelNode) category = graphene.Field(ModuleCategoryNode) language = graphene.String() highlights = graphene.List("notes.schema.HighlightNode") my_highlights = graphene.List( graphene.NonNull("notes.schema.HighlightNode"), required=True ) my_bookmarks = graphene.List("notes.schema.BookmarkNode") path = graphene.String() def resolve_chapters(self, info, **kwargs): return Chapter.get_by_parent(self) def resolve_topic(self, info, **kwargs): return self.get_parent().specific def resolve_solutions_enabled(self, info, **kwargs): school_class = info.context.user.selected_class return ( self.solutions_enabled_for.filter(pk=school_class.pk).exists() if school_class is not None else False ) def resolve_bookmark(self, info, **kwags): return ModuleBookmark.objects.filter( user=info.context.user, module=self ).first() def resolve_my_submissions(self, info, **kwargs): user = info.context.user return StudentSubmission.objects.filter(student=user, assignment__module=self) # we want: # StudentSubmission def resolve_my_answers(self, info, **kwargs): user = info.context.user return Answer.objects.filter(owner=user, survey__module=self) # Survey def resolve_my_content_bookmarks(self, info, **kwargs): user = info.context.user content_blocks = ContentBlock.objects.live().descendant_of(self) return ContentBlockBookmark.objects.filter( content_block__in=content_blocks, user=user ) # Bookmark Text # Bookmark Image etc # Bookmark Other # Note # def resolve_my_chapter_bookmarks(self, info, **kwargs): user = info.context.user chapters = Chapter.objects.live().descendant_of(self) return ChapterBookmark.objects.filter(chapter__in=chapters, user=user) @staticmethod def resolve_objective_groups(parent, info, **kwargs): return parent.objective_groups.all().prefetch_related("hidden_for") @staticmethod def resolve_snapshots(parent, info, **kwargs): user = info.context.user return parent.snapshots.filter( Q(creator=user) | Q(Q(creator__team=user.team) & Q(shared=True)) ) @staticmethod def resolve_assignments(parent: Module, info, **kwargs): return parent.assignments.all() @staticmethod def resolve_language(parent: Module, info, **kwargs): return parent.locale.language_code @staticmethod def resolve_highlights(root: Module, info, **kwargs): return root.highlights.filter(user=info.context.user) @staticmethod def resolve_my_highlights(root: Module, info, **kwargs): # todo: is this too expensive, query-wise pages = list(Page.objects.live().descendant_of(root)) + [root] highlights = Highlight.objects.filter(user=info.context.user).filter( page__in=pages ) return highlights @staticmethod def resolve_my_bookmarks(root: Module, info, **kwargs): from notes.models import ChapterBookmark, ContentBlockBookmark, ModuleBookmark module_bookmarks = ModuleBookmark.objects.filter( module=root, user=info.context.user ) chapters = Chapter.get_by_parent(root) chapter_bookmarks = ChapterBookmark.objects.filter( chapter__in=chapters, user=info.context.user ) content_blocks = ContentBlock.objects.descendant_of(root) content_block_bookmarks = ContentBlockBookmark.objects.filter( user=info.context.user, content_block__in=content_blocks ) return ( list(module_bookmarks) + list(chapter_bookmarks) + list(content_block_bookmarks) ) @staticmethod def resolve_path(root: Module, info, **kwargs): return root.route class RecentModuleNode(DjangoObjectType): class Meta: model = RecentModule interfaces = (relay.Node,)