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 core.wagtail_utils import get_default_settings from books.blocks import 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' BASE_COMMUNICATION = 'base_communication' TASK = 'task' BASE_SOCIETY = 'base_society' BASE_INTERDISCIPLINARY = 'base_interdisciplinary' TYPE_CHOICES = ( (NORMAL, 'Normal'), (BASE_COMMUNICATION, 'Instrument Sprache & Kommunikation'), (TASK, 'Auftrag'), (BASE_SOCIETY, 'Instrument Gesellschaft'), (BASE_INTERDISCIPLINARY, 'Überfachliches 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')), ('video_block', VideoBlock()), ('document_block', DocumentBlock()), ('infogram_block', InfogramBlock()), ('genially_block', GeniallyBlock()), ('thinglink_block', ThinglinkBlock()), ('subtitle', SubtitleBlock()), ('instruction', InstructionBlock()), ('module_room_slug', ModuleRoomSlugBlock()) ] 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 = [] @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