import random import factory import wagtail_factories from django.contrib.auth import get_user_model from factory import CREATE_STRATEGY from wagtail.core import blocks from wagtail.core.models import Page, Site from wagtail.core.rich_text import RichText from assignments.models import Assignment from basicknowledge.models import BasicKnowledge, INTERDISCIPLINARY, InstrumentType, LANGUAGE_COMMUNICATION, SOCIETY from books.blocks import AssignmentBlock, BasicKnowledgeBlock, ImageUrlBlock, LinkBlock, VideoBlock from books.models import Book, Chapter, ContentBlock, Module, TextBlock, Topic from core.factories import BasePageFactory, DummyImageFactory, fake, fake_paragraph, fake_title class BookFactory(BasePageFactory): class Meta: model = Book @staticmethod def create_default_structure(): site = wagtail_factories.SiteFactory.create(is_default_site=True) Page.objects.get(title='Root').delete() book = BookFactory.create(parent=site.root_page, title='A book') topic = TopicFactory.create(parent=book, order=1, title='A topic') module = ModuleFactory.create(parent=topic, title="A module", meta_title="Modul 1", teaser="Whatever", intro="
Hello
") chapter = ChapterFactory.create(parent=module, title="A chapter") content_block = ContentBlockFactory.create(parent=chapter, module=module, title="A content block", type="task", contents=[]) return book, topic, module, chapter, content_block class TopicFactory(BasePageFactory): class Meta: model = Topic order = 0 teaser = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(8, 12))) description = factory.LazyAttribute(lambda x: fake.text(max_nb_chars=200)) class ModuleFactory(BasePageFactory): class Meta: model = Module meta_title = factory.LazyAttribute(lambda x: fake.text(max_nb_chars=20)) teaser = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(8, 12))) intro = factory.LazyAttribute(lambda x: fake.text(max_nb_chars=200)) hero_image = factory.SubFactory(DummyImageFactory) class ChapterFactory(BasePageFactory): class Meta: model = Chapter class TextBlockFactory(wagtail_factories.StructBlockFactory): text = factory.LazyAttribute(fake_paragraph) class Meta: model = TextBlock class InstrumentTypeFactory(factory.DjangoModelFactory): class Meta: model = InstrumentType category = factory.Iterator([LANGUAGE_COMMUNICATION, SOCIETY, INTERDISCIPLINARY]) name = factory.LazyAttribute(lambda x: fake.text(max_nb_chars=20)) class InstrumentFactory(BasePageFactory): title = factory.LazyAttribute(fake_title) old_type = factory.Iterator([LANGUAGE_COMMUNICATION, SOCIETY, INTERDISCIPLINARY]) new_type = factory.SubFactory(InstrumentTypeFactory) class Meta: model = BasicKnowledge @classmethod def _create(cls, model_class, *args, **kwargs): kwargs['parent'] = Site.objects.get(is_default_site=True).root_page return super()._create(model_class, *args, **kwargs) class BasicKnowledgeBlockFactory(wagtail_factories.StructBlockFactory): description = factory.LazyAttribute(fake_paragraph) basic_knowledge = factory.SubFactory(InstrumentFactory) class Meta: model = BasicKnowledgeBlock class ImageUrlBlockFactory(wagtail_factories.StructBlockFactory): title = fake_title() url = factory.LazyAttribute(lambda x: 'https://picsum.photos/600/400/?random') class Meta: model = ImageUrlBlock class LinkBlockFactory(wagtail_factories.StructBlockFactory): text = fake_title() url = factory.LazyAttribute(lambda x: 'https://picsum.photos/600/400/?random') class Meta: model = LinkBlock class AssignmentBlockFactory(wagtail_factories.StructBlockFactory): class Meta: model = AssignmentBlock @classmethod def _build(cls, model_class, *args, **kwargs): block = model_class() return blocks.StructValue( block, # todo: build in a more generic fashion [ (name, kwargs['assignment']) for name, child_block in block.child_blocks.items() ], ) class VideoBlockFactory(wagtail_factories.StructBlockFactory): url = factory.LazyAttribute(lambda x: 'https://www.youtube.com/watch?v=lO9d-AJai8Q') class Meta: model = VideoBlock block_types = ['text_block', 'basic_knowledge', 'student_entry', 'image_url_block', 'solution'] class ContentBlockFactory(BasePageFactory): class Meta: model = ContentBlock type = factory.LazyAttribute(lambda x: random.choice(['normal', 'base_communication', 'task', 'base_society'])) contents = wagtail_factories.StreamFieldFactory({ 'text_block': TextBlockFactory, 'basic_knowledge': BasicKnowledgeBlockFactory, 'assignment': AssignmentBlockFactory, 'image_block': wagtail_factories.ImageChooserBlockFactory, 'image_url_block': ImageUrlBlockFactory, 'link_block': LinkBlockFactory, 'video_block': VideoBlockFactory, 'solution': TextBlockFactory }) @classmethod def stream_field_magic(cls, module, kwargs, stream_field_name): if stream_field_name in kwargs: """ stream_field_name is most likely 'contents' this means: if there is a property named contents, us the defined ones in this block. otherwise, go into the other block and randomize the contents """ for idx, resource in enumerate(kwargs[stream_field_name]): value = resource['value'] block_type = resource['type'] if block_type == 'assignment': user = get_user_model().objects.first() assignment = Assignment.objects.create( title=value['title'], assignment=value['assignment'], owner=user, module=module ) kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, 'assignment')] = assignment else: for jdx, field in enumerate(value): if block_type == 'text_block': kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = RichText( value[field]) elif block_type == 'solution': kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = RichText( value[field]) elif block_type == 'basic_knowledge': if field == 'description': kwargs[ '{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = RichText( value[field]) else: kwargs[ '{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = 'https://google.ch' elif block_type == 'image_url_block': kwargs[ '{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = value[field] else: kwargs[ '{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = value[field] del kwargs[stream_field_name] else: # random contents from generator for i in range(0, random.randint(3, 7)): block_type = random.choice(block_types) if block_type == 'text_block': kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'text_block', 'text')] = RichText( fake_paragraph()) elif block_type == 'basic_knowledge': kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'basic_knowledge', 'description')] = RichText( fake_paragraph()) elif block_type == 'assignment': kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'assignment', 'task_text')] = RichText( fake_paragraph()) elif block_type == 'image_url_block': kwargs[ '{}__{}__{}__{}'.format(stream_field_name, i, 'image_url_block', 'title')] = fake_paragraph() kwargs[ '{}__{}__{}__{}'.format(stream_field_name, i, 'image_url_block', 'url')] = 'https://picsum.photos/400/?random={}'.format( ''.join(random.choice('abcdefghiklmn') for _ in range(6))) elif block_type == 'solution': kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'solution', 'text')] = RichText( fake_paragraph()) @classmethod def create(cls, module, **kwargs): cls.stream_field_magic(module, kwargs, 'contents') return cls._generate(CREATE_STRATEGY, kwargs)