162 lines
6.8 KiB
Python
162 lines
6.8 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 core.logger import get_logger
|
|
from objectives.models import ObjectiveSnapshot
|
|
from users.models import User, SchoolClass
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
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=content_block.is_hidden_for_class(school_class),
|
|
snapshot=snapshot,
|
|
contents=content_block.contents,
|
|
type=content_block.type,
|
|
title=content_block.title,
|
|
original_creator=content_block.owner
|
|
)
|
|
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=objective.is_hidden_for_class(school_class=school_class),
|
|
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,
|
|
related_name='+'
|
|
)
|
|
hidden_objectives = models.ManyToManyField(
|
|
'objectives.Objective',
|
|
related_name='hidden_for_snapshots'
|
|
)
|
|
title = models.CharField(max_length=255, blank=True, null=True)
|
|
|
|
objects = SnapshotManager()
|
|
|
|
def __str__(self):
|
|
return f'Snapshot {self.id}'
|
|
|
|
def reset(self, user: User, selected_class: SchoolClass):
|
|
for chapter in Chapter.get_by_parent(self.module):
|
|
qs = ContentBlock.get_by_parent(chapter)
|
|
default_content = Q(user_created=False)
|
|
no_snapshot = Q(contentblocksnapshot__isnull=True)
|
|
owner_user = Q(owner=user)
|
|
logger.info(f'resetting hidden properties for chapter {chapter.id}')
|
|
chapter.title_hidden_for.remove(selected_class)
|
|
chapter.description_hidden_for.remove(selected_class)
|
|
|
|
for content_block in qs.filter(default_content & no_snapshot):
|
|
content_block.hidden_for.remove(selected_class)
|
|
for content_block in qs.filter(owner_user):
|
|
content_block.visible_for.remove(selected_class)
|
|
|
|
def apply(self, user: User, selected_class: SchoolClass):
|
|
for content_block in self.hidden_content_blocks.all():
|
|
content_block.hidden_for.add(selected_class)
|
|
for custom_content_block in self.custom_content_blocks.all():
|
|
custom_content_block.to_regular_content_block(owner=user, school_class=selected_class)
|
|
for chapter_snapshot in ChapterSnapshot.objects.filter(snapshot=self):
|
|
chapter = chapter_snapshot.chapter
|
|
if chapter_snapshot.title_hidden:
|
|
chapter.title_hidden_for.add(selected_class)
|
|
if chapter_snapshot.description_hidden:
|
|
chapter.description_hidden_for.add(selected_class)
|
|
for objective_group_snapshot in self.objective_groups.through.objects.all():
|
|
if objective_group_snapshot.hidden:
|
|
objective_group_snapshot.objective_group.hidden_for.add(selected_class)
|
|
for objective in self.hidden_objectives.all():
|
|
objective.hidden_for.add(selected_class)
|
|
for custom_objective in self.custom_objectives.all():
|
|
custom_objective.to_regular_objective(owner=user, school_class=selected_class)
|