skillbox/server/books/factories.py

211 lines
8.2 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
from wagtail.core.rich_text import RichText
from assignments.models import Assignment
from books.blocks import BasicKnowledgeBlock, ImageUrlBlock, LinkBlock, AssignmentBlock, VideoBlock
from books.models import Book, Topic, Module, Chapter, ContentBlock, TextBlock
from core.factories import BasePageFactory, fake, DummyImageFactory, 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 BasicKnowledgeBlockFactory(wagtail_factories.StructBlockFactory):
description = factory.LazyAttribute(fake_paragraph)
url = factory.LazyAttribute(lambda x: fake.uri())
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:
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:
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)