import logging from django.db import models from wagtail.admin.edit_handlers import ( FieldPanel, TabbedInterface, ObjectList, StreamFieldPanel, ) from wagtail.core.blocks import StreamBlock from wagtail.core.fields import StreamField from wagtail.images.blocks import ImageChooserBlock from books.managers import ContentBlockManager from core.wagtail_utils import get_default_settings from books.blocks import ( CMSDocumentBlock, SolutionBlock, TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, DocumentBlock, ImageUrlBlock, AssignmentBlock, InfogramBlock, GeniallyBlock, SubtitleBlock, SurveyBlock, ModuleRoomSlugBlock, ThinglinkBlock, InstructionBlock, ) from books.utils import get_type_and_value from core.wagtail_utils import StrictHierarchyPage from notes.models import ContentBlockBookmark from surveys.models import Survey from users.models import SchoolClass, User logger = logging.getLogger(__name__) class ContentBlock(StrictHierarchyPage): class Meta: verbose_name = "Inhaltsblock" verbose_name_plural = "Inhaltsblöcke" NORMAL = "normal" TASK = "task" INSTRUMENT = "instrument" TYPE_CHOICES = ( (NORMAL, "Normal"), (TASK, "Auftrag"), (INSTRUMENT, "Instrument"), ) # blocks without owner are visible by default, need to be hidden for each class hidden_for = models.ManyToManyField( SchoolClass, related_name="hidden_content_blocks" ) # blocks with owner are hidden by default, need to be shown for each class visible_for = models.ManyToManyField( SchoolClass, related_name="visible_content_blocks" ) user_created = models.BooleanField(default=False) original_creator = models.ForeignKey( User, null=True, blank=True, default=None, on_delete=models.SET_NULL ) bookmarks = models.ManyToManyField( User, through=ContentBlockBookmark, related_name="bookmarked_content_blocks" ) content_blocks = [ ("text_block", TextBlock()), ("basic_knowledge", BasicKnowledgeBlock()), ("assignment", AssignmentBlock()), ("survey", SurveyBlock()), ("image_block", ImageChooserBlock()), ("image_url_block", ImageUrlBlock()), ("link_block", LinkBlock()), # ('solution', TextBlock(icon='tick')), ("solution", SolutionBlock()), ("video_block", VideoBlock()), ("document_block", DocumentBlock()), ("infogram_block", InfogramBlock()), ("genially_block", GeniallyBlock()), ("thinglink_block", ThinglinkBlock()), ("subtitle", SubtitleBlock()), ("instruction", InstructionBlock()), ("module_room_slug", ModuleRoomSlugBlock()), # ('cms_document_block', DocumentChooserBlock(label='CMS Document')) ("cms_document_block", CMSDocumentBlock()), ] content_list_item = StreamBlock(content_blocks) contents = StreamField( content_blocks + [("content_list_item", content_list_item)], null=True, blank=True, ) type = models.CharField( max_length=100, choices=TYPE_CHOICES, default=NORMAL) content_panels = [ FieldPanel("title", classname="full title"), FieldPanel("type"), StreamFieldPanel("contents"), ] # edit_handler = TabbedInterface( [ObjectList(content_panels, heading="Content"), get_default_settings()] ) parent_page_types = ["books.Chapter"] subpage_types = [] # prevent these fields from being copied exclude_fields_in_copy = ["bookmarks"] objects = ContentBlockManager() @property def module(self): return self.get_parent().get_parent().specific def is_hidden_for_class(self, school_class): return ( not self.user_created and self.hidden_for.filter(id=school_class.id).exists() ) or ( self.user_created and not self.visible_for.filter(id=school_class.id).exists() ) def save(self, *args, **kwargs): for data in self.contents.raw_data: block_type, value = get_type_and_value(data) if block_type == "survey": module = self.module survey = value["survey_id"] if isinstance(survey, int): survey = Survey.objects.get(pk=survey) if survey.module != module: survey.module = module survey.save() super().save(*args, **kwargs) class ContentBlockSnapshot(ContentBlock): hidden = models.BooleanField(default=False) snapshot = models.ForeignKey( "books.snapshot", on_delete=models.SET_NULL, null=True, related_name="custom_content_blocks", ) def to_regular_content_block(self, owner, school_class): cb = ContentBlock( contents=self.contents, type=self.type, title=self.title, owner=owner, original_creator=self.original_creator, user_created=True, ) self.add_sibling(instance=cb, pos="right") # some wagtail magic revision = cb.save_revision() revision.publish() cb.visible_for.add(school_class) cb.save() return cb