From 7ef59d2545d14f7a8db14294cb99b51e00eee819 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Wed, 1 Apr 2020 12:37:42 +0200 Subject: [PATCH] Improve import of lessons - Save references to term, lesson id and element number - Update existing lessons - Add logging --- aleksis/apps/untis/model_extensions.py | 4 + .../untis/util/mysql/importers/lessons.py | 134 ++++++++++++++---- 2 files changed, 110 insertions(+), 28 deletions(-) diff --git a/aleksis/apps/untis/model_extensions.py b/aleksis/apps/untis/model_extensions.py index b5b61bd..89ab7cb 100644 --- a/aleksis/apps/untis/model_extensions.py +++ b/aleksis/apps/untis/model_extensions.py @@ -11,3 +11,7 @@ core_models.Group.field(import_ref_untis=IntegerField()) chronos_models.Subject.field(import_ref_untis=IntegerField()) chronos_models.Room.field(import_ref_untis=IntegerField()) chronos_models.SupervisionArea.field(import_ref_untis=IntegerField()) +chronos_models.Lesson.field(lesson_id_untis=IntegerField()) +chronos_models.Lesson.field(element_id_untis=IntegerField()) +chronos_models.Lesson.field(term_untis=IntegerField()) +chronos_models.LessonPeriod.field(element_id_untis=IntegerField()) diff --git a/aleksis/apps/untis/util/mysql/importers/lessons.py b/aleksis/apps/untis/util/mysql/importers/lessons.py index bfe2b78..d754916 100644 --- a/aleksis/apps/untis/util/mysql/importers/lessons.py +++ b/aleksis/apps/untis/util/mysql/importers/lessons.py @@ -1,3 +1,5 @@ +import logging + from django.utils.translation import gettext as _ from aleksis.apps.chronos import models as chronos_models @@ -7,6 +9,19 @@ from aleksis.core.util import messages from .... import models as mysql_models from ..util import run_default_filter, untis_split_third, untis_date_to_date, get_term +logger = logging.getLogger(__name__) + + +def sync_m2m(new_items, m2m_qs): + for item in new_items: + if item not in m2m_qs.all(): + m2m_qs.add(item) + logger.info(" Many-to-many sync: item added") + for item in m2m_qs.all(): + if item not in new_items: + m2m_qs.remove(item) + logger.info(" Many-to-many sync: item removed") + def import_lessons( time_periods_ref, rooms_ref, subjects_ref, teachers_ref, classes_ref @@ -25,10 +40,7 @@ def import_lessons( if not lesson.lesson_tt: messages.warning( - None, - message=_("Skip lesson {} because there are missing times.").format( - lesson_id - ), + None, message=_(" Skip because missing times").format(lesson_id), ) continue @@ -67,6 +79,8 @@ def import_lessons( # All part lessons (courses) for i, el in enumerate(raw_lesson_data_2): + logger.info(" Lesson part {}".format(i)) + # Get plain ids teacher_id = int(el[0]) subject_id = int(el[2]) @@ -83,15 +97,9 @@ def import_lessons( subject = subjects_ref[subject_id] else: messages.warning( - None, - message=_( - "Skip lesson {}, element {} because there is missing a subject.".format( - lesson_id, i - ) - ), + None, message=_(" Skip because missing subject".format(i)), ) continue - # raise Exception("Subject needed.") # Get classes course_classes = [] @@ -100,43 +108,113 @@ def import_lessons( course_classes.append(c) # Build names and refs for course groups - short_name = "{}-{}".format( + group_short_name = "{}-{}".format( "".join([c.short_name for c in course_classes]), subject.abbrev ) - name = "{}: {}".format( + group_name = "{}: {}".format( ", ".join([c.short_name for c in course_classes]), subject.abbrev ) - import_ref = "{}-{}".format(lesson_id, i) + group_import_ref = -int("{}{}".format(lesson_id, i)) # Get or create course group course_group, created = core_models.Group.objects.get_or_create( - short_name=short_name, defaults={"name": name} + short_name=group_short_name, defaults={"name": group_name} ) - course_group.import_ref = import_ref - course_group.name = name - + course_group.import_ref_untis = group_import_ref + course_group.name = group_name course_group.save() course_group.parent_groups.set(course_classes) + if created: + logger.info(" Course group created") + # Create new lesson date_start = untis_date_to_date(term.datefrom) date_end = untis_date_to_date(term.dateto) - lesson = chronos_models.Lesson.objects.create( - subject=subject, date_start=date_start, date_end=date_end + + # Get old lesson + old_lesson_qs = chronos_models.Lesson.objects.filter( + lesson_id_untis=lesson_id, element_id_untis=i, term_untis=term.term_id ) - # Set groups - lesson.groups.set([course_group]) + if old_lesson_qs.exists(): + # Update existing lesson + logger.info(" Existing lesson found") + + old_lesson = old_lesson_qs[0] + + if ( + old_lesson.subject != subject + or old_lesson.date_start != date_start + or old_lesson.date_end != date_end + ): + old_lesson.subject = subject + old_lesson.date_start = date_start + old_lesson.date_end = date_end + old_lesson.save() + logger.info(" Subject, start date and end date updated") + lesson = old_lesson + else: + # Create new lesson + + lesson = chronos_models.Lesson.objects.create( + subject=subject, + date_start=date_start, + date_end=date_end, + lesson_id_untis=lesson_id, + element_id_untis=i, + term_untis=term.term_id, + ) + logger.info(" New lesson created") + + # Sync groups + groups = [course_group] + sync_m2m(groups, lesson.groups) - # Set teacher - if teacher: - lesson.teachers.set([teacher]) + # Sync teachers + teachers = [teacher] if teacher else [] + sync_m2m(teachers, lesson.teachers) # All times for this course + old_lesson_periods_qs = chronos_models.LessonPeriod.objects.filter( + lesson=lesson + ) + + # If length has changed, delete all lesson periods + if old_lesson_periods_qs.count() != len(time_periods): + old_lesson_periods_qs.delete() + logger.info(" Lesson periods deleted") + + # Sync time periods for j, time_period in enumerate(time_periods): - rooms = rooms_per_periods[j] + logger.info(" Import lesson period {}".format(time_period)) + # Get room if provided + rooms = rooms_per_periods[j] if i < len(rooms): - lesson.periods.add(time_period, through_defaults={"room": rooms[i]}) + room = rooms[i] else: - lesson.periods.add(time_period) + room = None + + # Check if an old lesson period is provided + old_lesson_period_qs = old_lesson_periods_qs.filter(element_id_untis=j) + if old_lesson_period_qs.exists(): + # Update old lesson period + + old_lesson_period = old_lesson_period_qs[0] + if ( + old_lesson_period.period != time_period + or old_lesson_period.room != room + ): + old_lesson_period.period = time_period + old_lesson_period.room = room + old_lesson_period.save() + logger.info(" Time period and room updated") + else: + # Create new lesson period + + lesson.periods.add( + time_period, + through_defaults={"room": room, "element_id_untis": j}, + ) + logger.info(" New time period added") -- GitLab