skillbox/server/books/factories.py

248 lines
9.8 KiB
Python

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, INTERDISCIPLINARY_LABEL, InstrumentCategory, \
InstrumentType, \
LANGUAGE_COMMUNICATION, LANGUAGE_COMMUNICATION_LABEL, SOCIETY, SOCIETY_LABEL
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="<p>Hello</p>")
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 InstrumentCategoryFactory(factory.DjangoModelFactory):
class Meta:
model = InstrumentCategory
django_get_or_create = ('name',)
name = factory.Iterator([LANGUAGE_COMMUNICATION_LABEL, SOCIETY_LABEL, INTERDISCIPLINARY_LABEL])
foreground = factory.Iterator(['FF0000', 'FFFFFF', '000000'])
background = factory.Iterator(['FF0000', 'FFFFFF', '000000'])
class InstrumentTypeFactory(factory.DjangoModelFactory):
class Meta:
model = InstrumentType
category = factory.SubFactory(InstrumentCategoryFactory)
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', 'instrument', 'task',]))
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)