skillbox/server/books/models/snapshot.py

122 lines
4.5 KiB
Python

from django.contrib.auth import get_user_model
from django.db import models
from django.db.models import Q
from books.models import Chapter, ContentBlock, ContentBlockSnapshot
from objectives.models import ObjectiveSnapshot
class ChapterSnapshot(models.Model):
"""
Captures the state of a chapter at the time when the snapshot was taken, for the school class that was selected
for the user creating the snapshot
"""
chapter = models.ForeignKey(
'books.Chapter',
related_name='chapter_snapshots',
on_delete=models.PROTECT
)
snapshot = models.ForeignKey(
'books.Snapshot',
related_name='chapter_snapshots',
on_delete=models.CASCADE
)
title_hidden = models.BooleanField(default=False)
description_hidden = models.BooleanField(default=False)
class ObjectiveGroupSnapshot(models.Model):
objective_group = models.ForeignKey(
'objectives.ObjectiveGroup',
on_delete=models.CASCADE
)
snapshot = models.ForeignKey(
'books.Snapshot',
related_name='objective_group_snapshots',
on_delete=models.CASCADE
)
hidden = models.BooleanField(default=False)
class SnapshotManager(models.Manager):
def create_snapshot(self, module, school_class, user, *args, **kwargs):
snapshot = self.create(module=module, creator=user, *args, **kwargs)
chapters = Chapter.get_by_parent(module)
for chapter in chapters:
ChapterSnapshot.objects.create(
chapter=chapter,
snapshot=snapshot,
title_hidden=chapter.title_hidden_for.filter(id=school_class.id).exists(),
description_hidden=chapter.description_hidden_for.filter(id=school_class.id).exists()
)
base_qs = ContentBlock.get_by_parent(chapter).filter(contentblocksnapshot__isnull=True)
for content_block in base_qs.filter(user_created=False):
if content_block.hidden_for.filter(id=school_class.id).exists():
snapshot.hidden_content_blocks.add(content_block)
for content_block in base_qs.filter(Q(user_created=True) & Q(owner=user)):
new_content_block = ContentBlockSnapshot(
hidden=False, # todo
snapshot=snapshot,
contents=content_block.contents,
type=content_block.type,
title=content_block.title
)
content_block.add_sibling(instance=new_content_block, pos='right')
revision = new_content_block.save_revision()
revision.publish()
new_content_block.save()
for objective_group in module.objective_groups.all():
ObjectiveGroupSnapshot.objects.create(
objective_group=objective_group,
snapshot=snapshot,
hidden=objective_group.hidden_for.filter(id=school_class.id).exists(),
)
base_qs = objective_group.objectives.filter(objectivesnapshot__isnull=True)
for objective in base_qs.filter(owner__isnull=True):
if objective.hidden_for.filter(id=school_class.id).exists():
snapshot.hidden_objectives.add(objective)
for objective in base_qs.filter(owner=user):
ObjectiveSnapshot.objects.create(
hidden=False, # todo
snapshot=snapshot,
text=objective.text,
group=objective_group,
order=objective.order
)
return snapshot
class Snapshot(models.Model):
module = models.ForeignKey(
'books.Module',
on_delete=models.PROTECT,
related_name='snapshots'
)
chapters = models.ManyToManyField(
'books.Chapter',
through=ChapterSnapshot
)
hidden_content_blocks = models.ManyToManyField(
'books.ContentBlock',
related_name='hidden_for_snapshots'
)
created = models.DateTimeField(auto_now_add=True)
creator = models.ForeignKey(get_user_model(), on_delete=models.SET_NULL, null=True)
shared = models.BooleanField(default=False)
objective_groups = models.ManyToManyField(
'objectives.ObjectiveGroup',
through=ObjectiveGroupSnapshot
)
hidden_objectives = models.ManyToManyField(
'objectives.Objective',
related_name='hidden_for_snapshots'
)
objects = SnapshotManager()
def __str__(self):
return f'Snapshot {self.id}'