skillbox/server/books/management/commands/migrate_objective_snapshots.py

215 lines
10 KiB
Python

import json
from logging import getLogger
from django.core.management import BaseCommand
from books.management.commands.migrate_objectives_to_content import create_chapter_from_objective_group, \
create_content_block_from_objective, create_text_in_content_block, create_content_block_snapshot_from_objective, \
create_chapter_snapshot_from_objective_group, create_content_block_contents
from books.models import Chapter, ObjectiveGroupSnapshot, ContentBlockSnapshot, Snapshot, ChapterSnapshot
from books.models import ContentBlock
from books.models import Module
from objectives.models import Objective, ObjectiveSnapshot, ObjectiveGroup
logger = getLogger(__name__)
class Command(BaseCommand):
def handle(self, *args, **options):
"""
This command must be run after the migration of objectives to content blocks.
Migrate objective snapshots to content blocks
- Verlagsinhalte - deafult content blocks are referced in the snapshot by foreign key
Man muss unterscheiden zwischen, snapshots die nur Verlagslernziele sichtbar und unsichtbar machen.
Und solchen die auch benutzerdefinierte Lernziele sichtbar und unsichtbar machen.
Es gibt keine custom objective groups!
Es gibt keine hidden custom objective_groups
Case1:
- 100% Verlagslernziele, 100% Verlagsgruppe, nicht neue content blocks erstellen, nichts hidden... migration muss nichts machen.
Case2:
- 100% Verlagslernziele, 100% Verlagsgruppe, hidden gruppe, nur verlagsinhalt gruppe verstecken
Case3:
- Bestende gruppe mit benutzerdefinierten lernzielen, - custom content_block snapshot erstellen.
- Einzelne verslagslernziele sind versteckt. - custom content_block snapshot erstellen.
--- user created setzen bei custom content snapshot.
"""
prefix = "SNAP "
ContentBlock.objects.filter(title__startswith=prefix).delete()
Chapter.objects.filter(title__startswith=prefix).delete()
ContentBlockSnapshot.objects.filter(title__startswith=prefix).delete()
ChapterSnapshot.objects.filter(chapter__title__startswith=prefix).delete()
analyze()
count = 0
case1_count = 0
case2_count = 0
case3_count = 0
createed_content_blocks = 0
visible_objectives_by_ids = {}
snapshot_counter = 0
for module in Module.objects.all(): # .filter(title__contains="Politik mitbestimmen"):
for snapshot in Snapshot.objects.filter(module=module):
group_counter = snapshot.objective_groups.through.objects.filter(objective_group__module=module,
snapshot=snapshot).count()
print(
f"{snapshot_counter} Snapshot id: {snapshot.id} Module: {module.title} {group_counter} groups {snapshot.creator} {snapshot.title}")
snapshot_counter += 1
for objective_group_snapshot in snapshot.objective_groups.through.objects.filter(
objective_group__module=module, snapshot=snapshot):
header = f"{count} {module.title:50} {objective_group_snapshot.objective_group.get_title_display():25} {str(snapshot.creator):40} {objective_group_snapshot.hidden} "
count += 1
objective_group = objective_group_snapshot.objective_group
hidden_default_objectives = snapshot.hidden_objectives.filter(
group=objective_group)
visible_custom_objectives = snapshot.custom_objectives.filter(snapshot=snapshot, hidden=False,
group=objective_group_snapshot.objective_group)
group_is_hidden = objective_group_snapshot.hidden
info = f"{hidden_default_objectives.count()} {visible_custom_objectives.count()}"
if (not hidden_default_objectives and not visible_custom_objectives and not group_is_hidden):
# print(f"{info} Case 1 - skip")
case1_count += 1
break
if not hidden_default_objectives and not visible_custom_objectives and group_is_hidden:
print(header + f"Case 2 - {info} hide default content group")
case2_count += 1
content_block = get_content_block_by_objective_group(objective_group_snapshot,
module, False, None)
snapshot.hidden_content_blocks.add(content_block.id)
snapshot.save()
if hidden_default_objectives or visible_custom_objectives:
print(header + f"Case 3 - {info} create custom content blocks")
case3_count += 1
# Verlags Lernziele
default_objectives = Objective.objects.filter(group=objective_group,
group__module=module,
owner__isnull=True,
objectivesnapshot__isnull=True)
visible_default_objectives = [objective for objective in default_objectives if
objective.id not in hidden_default_objectives.values_list("id",
flat=True)]
# Benutzerdefinierte Lernziele
visible_custom_objectives = list(snapshot.custom_objectives.filter(hidden=False))
visible_objectives = visible_default_objectives + visible_custom_objectives
# filter for unique texts in objectives
# TODO: I don't know why there are duplicated objectives
objectives_by_texts = {}
for objective in visible_objectives:
if objective.text not in objectives_by_texts:
objectives_by_texts[objective.text] = objective
visible_objectives = list(objectives_by_texts.values())
if visible_objectives:
# make combinations of objectives unique by text, this prevents generation of many duplicated content blocks
visible_objectives_hash = hash(
[objective.text for objective in visible_objectives].__str__())
visible_objectives_by_ids[visible_objectives_hash] = visible_objectives
for objectives in visible_objectives_by_ids.values():
print("")
for objective in objectives:
print(f" Objective: {objective.group} {objective} owner:{objective.owner}")
print("-")
print(f" visible_objectives_by_ids: {len(visible_objectives_by_ids.items())}")
# create custom content blocks with the objectives
created_content_blocks = 0
chapter = module.get_first_child()
if "Lernziele" not in chapter.title:
raise Exception(f"Chapter does not contain 'Lernziele' first title is {chapter.title}")
#
# Owner des custom blocks festlegen
custom_content_block_snapshot = create_content_block_snapshot_from_objective(
objective_group, chapter, snapshot,
owner=snapshot.creator,
prefix="SNAP ")
#
objectives = list(visible_objectives_by_ids.values())[0]
create_text_in_content_block(objectives, custom_content_block_snapshot, get_or_create=True)
created_content_blocks += 1
snapshot.save()
print()
print(f"Skipped {case1_count} Case 1")
print(f"Hidden default content groups {case2_count} Case 2")
print(f"Created new content {case3_count} Case 3")
def get_content_block_by_objective_group(objective_group_snapshot, module, user_created: bool, user):
# TODO: review qustion, is it necessary to filter for module
content_block = ContentBlock.objects.filter(
title__contains=objective_group_snapshot.objective_group.get_title_display(),
user_created=user_created, owner=user).descendant_of(module)
if content_block.count() > 1:
return content_block.first()
return content_block.first()
def get_visible_default_objectives():
default_objectives = Objective.objects.filter(group=ObjectiveGroup, group__module=module, owner__isnull=True)
visible_objectives = list(default_objectives)
visible_objectives_ids = [objective.id for objective in visible_objectives]
# Verlags Lernziele
for hidden_objective in snapshot.hidden_objectives.all():
visible_objectives = [objective for objective in visible_objectives if
hidden_objective.id not in visible_objectives_ids]
return visible_objectives
def get_content_block_by_objectives(objectives, module, user_created=False, user=None):
contents = create_content_block_contents(objectives)
content_block_qs = ContentBlock.objects.filter(
owner=user,
user_created=user_created,
contents=contents)
if content_block_qs.exists():
return content_block_qs.first()
else:
raise Exception("Content block does not exist ")
#
# print(f"created_content_blocks: {createed_content_blocks}")
def analyze():
print(f"""
OjectiveGroups: {ObjectiveGroup.objects.count()}
Objectives: {Objective.objects.count()}
ObjectiveGroupSnapshots: {ObjectiveGroupSnapshot.objects.count()}
ObjectivesSnapshots: {ObjectiveSnapshot.objects.count()}
ObjectiveGroups: {ObjectiveGroup.objects.filter(objectivegroupsnapshot__isnull=True).count()}
Objectives: {Objective.objects.filter(objectivesnapshot__isnull=True).count()}
Snapshot: {Snapshot.objects.count()}
""")