skillbox/server/books/factories.py

370 lines
12 KiB
Python

import random
import factory
import wagtail_factories
from django.contrib.auth import get_user_model
from factory import CREATE_STRATEGY
from wagtail import blocks
from wagtail.models import Page, Site
from wagtail.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,
SurveyBlock,
VideoBlock,
)
from books.models import (
Book,
Chapter,
ContentBlock,
Module,
TextBlock,
Topic,
ModuleLevel,
ModuleCategory,
)
from core.factories import (
BasePageFactory,
DummyImageFactory,
fake,
fake_paragraph,
fake_title,
)
from core.logger import get_logger
from surveys.factories import SurveyFactory
from surveys.models import Survey
logger = get_logger(__name__)
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.django.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.django.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
class SurveyBlockFactory(wagtail_factories.StructBlockFactory):
class Meta:
model = SurveyBlock
class VideoBlockFactory(wagtail_factories.StructBlockFactory):
url = factory.LazyAttribute(lambda x: "https://www.youtube.com/watch?v=lO9d-AJai8Q")
class Meta:
model = VideoBlock
class ModuleLevelFactory(factory.django.DjangoModelFactory):
class Meta:
model = ModuleLevel
name = "1. Lehrjahr"
class ModuleTypeFactory(factory.django.DjangoModelFactory):
class Meta:
model = ModuleCategory
name = "Lernfeld 1"
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": factory.SubFactory(TextBlockFactory),
"basic_knowledge": factory.SubFactory(BasicKnowledgeBlockFactory),
"assignment": factory.SubFactory(AssignmentBlockFactory),
"image_block": factory.SubFactory(
wagtail_factories.ImageChooserBlockFactory
),
"image_url_block": factory.SubFactory(ImageUrlBlockFactory),
"link_block": factory.SubFactory(LinkBlockFactory),
"video_block": factory.SubFactory(VideoBlockFactory),
"solution": factory.SubFactory(TextBlockFactory),
"survey": factory.SubFactory(SurveyBlockFactory),
}
)
@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, use 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
elif block_type == "survey":
survey = Survey.objects.create(
title=value["title"], data=value["data"], module=module
)
kwargs[
"{}__{}__{}__{}".format(
stream_field_name, idx, block_type, "survey"
)
] = survey
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)