import graphene from basicknowledge.models import BasicKnowledge from books.models import ContentBlock from books.schema.interfaces.contentblock import ContentBlockInterface from books.utils import are_solutions_enabled_for from core.logger import get_logger from core.mixins import HiddenAndVisibleForMixin from graphene import relay from graphene_django import DjangoObjectType from notes.models import ContentBlockBookmark from rooms.models import ModuleRoomSlug logger = get_logger(__name__) class TextBlockNode(graphene.ObjectType): text = graphene.String() def resolve_text(root, info, **kwargs): return root["value"]["text"] class ContentNode(graphene.Union): class Meta: types = (TextBlockNode,) @classmethod def resolve_type(cls, instance, info): logger.info(instance) if instance["type"] == "text_block": return TextBlockNode def is_solution_and_hidden_for_user(type, user, module): return type == "solution" and not ( are_solutions_enabled_for(user, module) or user.is_teacher() ) class ContentBlockNode(DjangoObjectType, HiddenAndVisibleForMixin): mine = graphene.Boolean() bookmarks = graphene.List("notes.schema.ContentBlockBookmarkNode") original_creator = graphene.Field("users.schema.PublicUserNode") instrument_category = graphene.Field( "basicknowledge.queries.InstrumentCategoryNode" ) path = graphene.String() highlights = graphene.List("notes.schema.HighlightNode") class Meta: model = ContentBlock only_fields = [ "slug", "title", "type", "contents", "hidden_for", "visible_for", "user_created", ] filter_fields = [ "slug", "title", ] interfaces = ( relay.Node, ContentBlockInterface, ) convert_choices_to_enum = False def resolve_mine(parent, info, **kwargs): return parent.owner is not None and parent.owner.pk == info.context.user.pk @staticmethod def resolve_contents(self: ContentBlock, info, **kwargs): updated_raw_data = [] for content in self.contents.raw_data: # only show solutions to teachers and students for whom their teachers have them enabled if is_solution_and_hidden_for_user( content["type"], info.context.user, self.module ): logger.debug("Solution is hidden for this user") continue if content["type"] == "content_list_item": _values = [] for index, list_block in enumerate(content["value"]): if is_solution_and_hidden_for_user( list_block["type"], info.context.user, self.module ): logger.debug("Solution is hidden for this user") continue _values.append(process_module_room_slug_block(list_block)) content["value"] = _values content = process_module_room_slug_block(content) updated_raw_data.append(content) self.contents.raw_data = updated_raw_data return self.contents def resolve_bookmarks(self, info, **kwargs): return ContentBlockBookmark.objects.filter( user=info.context.user, content_block=self ) @staticmethod def resolve_instrument_category(root: ContentBlock, info, **kwargs): if root.type == ContentBlock.INSTRUMENT: for content in root.contents.raw_data: if ( content["type"] == "instrument" or content["type"] == "basic_knowledge" ): _id = content["value"]["basic_knowledge"] instrument = BasicKnowledge.objects.get(id=_id) category = instrument.new_type.category return category return None @staticmethod def resolve_path(root: ContentBlock, info, **kwargs): return root.route @staticmethod def resolve_highlights(root: ContentBlock, info, **kwargs): return root.highlights.filter(user=info.context.user) def process_module_room_slug_block(content): if content["type"] == "module_room_slug": try: module_room_slug = ModuleRoomSlug.objects.get( title=content["value"]["title"] ) content["value"] = { "title": content["value"]["title"], "slug": module_room_slug.slug, } except ModuleRoomSlug.DoesNotExist: pass return content