skillbox/server/notes/schema.py

208 lines
5.6 KiB
Python

import json
import uuid
import graphene
from basicknowledge.models import BasicKnowledge
from basicknowledge.queries import InstrumentNode
from books.schema.nodes import ContentBlockNode, ModuleNode
from books.schema.nodes.chapter import ChapterNode
from core.logger import get_logger
from graphene import relay
from graphene_django import DjangoObjectType
from notes.models import (
ChapterBookmark,
ContentBlockBookmark,
Highlight,
InstrumentBookmark,
ModuleBookmark,
Note,
)
logger = get_logger(__name__)
content_dict = {
'assignment': 'Auftrag',
'basic_knowledge': '',
'survey': 'Übung',
'image_block': 'Bild',
'link_block': 'Link',
'solution': 'Lösung',
'video_block': 'Video',
'document_block': 'Dokument',
'infogram_block': 'Infografik',
'genially_block': 'Infografik',
'thinglink_block': 'Infografik',
'subtitle': 'Titel',
'instruction': 'Anweisung',
'cms_document_block': 'Dokument',
}
from collections import deque
def find_content_bfs(data, target_id):
"""
breadth-first search to find an object by its ID in a nested dictionary structure
"""
# Initialize a queue with the initial data list
queue = deque(data)
# Traverse through the data using BFS
while queue:
current = queue.popleft()
# Check if the current dictionary has the target_id
if current.get("id", "") == target_id:
return current
# If 'value' in current and it is a list, extend the queue with the items in 'value'
if isinstance(current.get("value"), list):
queue.extend(current["value"])
return None # If no matching ID is found
def find_content(content_list, bookmark):
content = find_content_bfs(content_list, str(bookmark.uuid))
if not content:
logger.warn(f"Content not found: {bookmark.uuid}")
return ''
if content['type'] in ['text_block', 'subtitle', 'solution', 'section_title']:
return content['value'].get('text', '')
if content['type'] in ['basic_knowledge']:
description = content['value'].get('description', '')
if not description:
try:
return BasicKnowledge.objects.get(pk=content['value']['basic_knowledge']).title
except BasicKnowledge.DoesNotExist:
return ''
return description
if content_dict.get(content['type'], '') == "":
logger.warn(f"Content type not found: {content['type']}")
return content_dict.get(content['type'], '')
class NoteNode(DjangoObjectType):
pk = graphene.Int()
class Meta:
model = Note
fields = "__all__"
interfaces = (relay.Node,)
def resolve_pk(self, *args, **kwargs):
return self.id
class ContentBlockBookmarkNode(DjangoObjectType):
uuid = graphene.UUID()
note = graphene.Field(NoteNode)
path = graphene.String()
content = graphene.String()
class Meta:
model = ContentBlockBookmark
fields = "__all__"
filter_fields = []
interfaces = (relay.Node,)
@staticmethod
def resolve_path(root: ContentBlockBookmark, info, **kwargs):
return root.content_block.route
@staticmethod
def resolve_content(root: ContentBlockBookmark, info, **kwargs):
contents = root.content_block.contents.raw_data
return find_content(contents, root)
class ModuleBookmarkNode(DjangoObjectType):
note = graphene.Field(NoteNode)
path = graphene.String()
content = graphene.String()
class Meta:
model = ModuleBookmark
fields = "__all__"
@staticmethod
def resolve_path(root: ModuleBookmark, info, **kwargs):
return root.module.route
@staticmethod
def resolve_content(root: ModuleBookmark, info, **kwargs):
return root.module.intro
class ChapterBookmarkNode(DjangoObjectType):
note = graphene.Field(NoteNode)
path = graphene.String()
content = graphene.String()
class Meta:
model = ChapterBookmark
fields = "__all__"
filter_fields = []
interfaces = (relay.Node,)
@staticmethod
def resolve_path(root: ChapterBookmark, info, **kwargs):
return root.chapter.route
@staticmethod
def resolve_content(root: ChapterBookmark, info, **kwargs):
return root.chapter.description
class InstrumentBookmarkNode(DjangoObjectType):
uuid = graphene.UUID()
note = graphene.Field(NoteNode)
path = graphene.String(required=True)
content = graphene.String()
class Meta:
model = InstrumentBookmark
fields = "__all__"
filter_fields = []
interfaces = (relay.Node,)
@staticmethod
def resolve_path(root: InstrumentBookmark, info, **kwargs):
return root.instrument.route
@staticmethod
def resolve_content(root: InstrumentBookmark, info, **kwargs):
contents = root.instrument.contents.raw_data
return find_content(contents, root)
class BookmarkNode(graphene.Union):
class Meta:
types = (
ContentBlockBookmarkNode,
ModuleBookmarkNode,
ChapterBookmarkNode,
InstrumentBookmarkNode,
)
class HighlightableNode(graphene.Union):
class Meta:
types = (ContentBlockNode, InstrumentNode, ModuleNode, ChapterNode)
class HighlightNode(DjangoObjectType):
page = graphene.Field(HighlightableNode, required=True)
class Meta:
model = Highlight
fields = "__all__"
filter_fields = []
interfaces = (relay.Node,)
@staticmethod
def resolve_page(root: Highlight, *args, **kwargs):
return root.page.specific