import graphene from django.db.models import Q from graphene import relay, ObjectType from graphene_django import DjangoObjectType from books.models.snapshot import Snapshot from ..interfaces import ChapterInterface from ..interfaces.contentblock import ContentBlockInterface from ...models import ContentBlock class SnapshotContentBlock: def __init__(self, content_block, snapshot): self.id = content_block.id self.pk = content_block.pk self.title = content_block.title self.contents = content_block.contents self.type = content_block.type self.hidden = snapshot.hidden_content_blocks.filter(id=content_block.id).exists() or ( hasattr(content_block, 'contentblocksnapshot') and content_block.contentblocksnapshot.hidden ) class SnapshotChapter: def __init__(self, chapter, snapshot, description_hidden=False, title_hidden=False): self.id = chapter.id self.pk = chapter.pk self.title = chapter.title self.description = chapter.description self.title_hidden = title_hidden self.description_hidden = description_hidden self.content_blocks = [] base_qs = ContentBlock.get_by_parent(chapter) default_content = Q(Q(user_created=False) & Q(contentblocksnapshot__snapshot__isnull=True)) this_snapshot = Q(contentblocksnapshot__snapshot=snapshot) self.content_blocks = [ SnapshotContentBlock( content_block=content_block, snapshot=snapshot ) for content_block in base_qs.filter(default_content | this_snapshot) ] # all from module without owner # all with snapshotcontentblock with this snapshot class SnapshotObjective: def __init__(self, objective, snapshot): self.id = objective.id self.text = objective.text self.hidden = snapshot.hidden_objectives.filter(id=objective.id).exists() or ( hasattr(objective, 'objectivesnapshot') and objective.objectivesnapshot.hidden ) class SnapshotObjectiveGroup: def __init__(self, objective_group, hidden, snapshot): self.title = objective_group.title self.display_title = objective_group.get_title_display() self.hidden = hidden self.id = objective_group.id base_qs = objective_group.objectives default = Q(Q(owner__isnull=True) & Q(objectivesnapshot__snapshot__isnull=True)) this_snapshot = Q(objectivesnapshot__snapshot=snapshot) self.objectives = [ SnapshotObjective( objective=objective, snapshot=snapshot ) for objective in base_qs.filter(default | this_snapshot) ] class SnapshotContentBlockNode(ObjectType): class Meta: interfaces = (relay.Node, ContentBlockInterface,) hidden = graphene.Boolean() class SnapshotChapterNode(ObjectType): class Meta: interfaces = (relay.Node, ChapterInterface,) content_blocks = graphene.List(SnapshotContentBlockNode) description_hidden = graphene.Boolean() title_hidden = graphene.Boolean() class SnapshotChangesNode(ObjectType): hidden_objectives = graphene.Int(required=True) new_objectives = graphene.Int(required=True) hidden_content_blocks = graphene.Int(required=True) new_content_blocks = graphene.Int(required=True) class SnapshotObjectiveNode(ObjectType): class Meta: interfaces = (relay.Node,) hidden = graphene.Boolean(required=True) text = graphene.String(required=True) class SnapshotObjectiveGroupNode(ObjectType): class Meta: interfaces = (relay.Node,) title = graphene.String(required=True) hidden = graphene.Boolean(required=True) display_title = graphene.String(required=True) objectives = graphene.List(SnapshotObjectiveNode, required=True) class SnapshotNode(DjangoObjectType): title = graphene.String() chapters = graphene.List(SnapshotChapterNode) meta_title = graphene.String() hero_image = graphene.String() changes = graphene.Field(SnapshotChangesNode) mine = graphene.Boolean() shared = graphene.Boolean(required=True) creator = graphene.String(required=True) objective_groups = graphene.List(SnapshotObjectiveGroupNode) class Meta: model = Snapshot interfaces = (relay.Node,) @staticmethod def resolve_chapters(parent, info, **kwargs): return [ SnapshotChapter( chapter_snapshot.chapter, snapshot=parent, title_hidden=chapter_snapshot.title_hidden, description_hidden=chapter_snapshot.description_hidden ) for chapter_snapshot in parent.chapters.through.objects.filter(snapshot=parent) ] @staticmethod def resolve_title(parent: Snapshot, info, **kwargs): return f'Snapshot {parent.id}' @staticmethod def resolve_meta_title(parent, info, **kwargs): return parent.module.meta_title @staticmethod def resolve_hero_image(parent, info, **kwargs): if parent.module.hero_image: return parent.module.hero_image.file.url return '' @staticmethod def resolve_changes(parent, info, **kwargs): return { 'hidden_objectives': parent.hidden_objectives.count(), 'new_objectives': parent.custom_objectives.filter(hidden=False).count(), 'hidden_content_blocks': parent.hidden_content_blocks.count(), 'new_content_blocks': parent.custom_content_blocks.filter(hidden=False).count() } @staticmethod def resolve_mine(parent, info, **kwargs): return parent.creator == info.context.user @staticmethod def resolve_creator(parent, info, **kwargs): return f'{parent.creator.first_name} {parent.creator.last_name}' if parent.creator else '' @staticmethod def resolve_objective_groups(parent, info, **kwargs): return [ SnapshotObjectiveGroup( objective_group=objective_group_snapshot.objective_group, hidden=objective_group_snapshot.hidden, snapshot=parent ) for objective_group_snapshot in parent.objective_groups.through.objects.filter(snapshot=parent) ]