Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • AlekSIS/official/AlekSIS-App-Untis
  • sunweaver/AlekSIS-App-Untis
  • cocguPpenda/AlekSIS-App-Untis
  • 0inraMfauri/AlekSIS-App-Untis
4 results
Show changes
Commits on Source (20)
......@@ -9,11 +9,28 @@ and this project adheres to `Semantic Versioning`_.
Unreleased
----------
Added
~~~~~
* Add fuzzy matching mode for searching course groups: If no 100 % match is found,
the importer will search a match by a subset of parent groups.
Changed
~~~~~~~
* Let untis_import_mysql management command default to ``current`` instead of all
to prevent accidental imports of old plans
* Use new change tracker from Chronos to trigger notifications
Fixed
~~~~~
* Search course groups not only by parent groups and subject, but also take
the teachers (group owners) into account
* Don't recreate lesson periods if they change, but just update them.
`2.1.3`_ - 2022-02-06
---------------------
Fixed
~~~~~
......@@ -182,3 +199,4 @@ Fixed
.. _2.1: https://edugit.org/Teckids/AlekSIS/AlekSIS-App-Untis/-/tags/2.1
.. _2.1.1: https://edugit.org/Teckids/AlekSIS/AlekSIS-App-Untis/-/tags/2.1.1
.. _2.1.2: https://edugit.org/Teckids/AlekSIS/AlekSIS-App-Untis/-/tags/2.1.2
.. _2.1.3: https://edugit.org/Teckids/AlekSIS/AlekSIS-App-Untis/-/tags/2.1.3
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-06 16:50+0100\n"
"POT-Creation-Date: 2022-03-23 11:34+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -116,6 +116,14 @@ msgid "Build or search course groups for every course instead of setting classes
msgstr ""
#: aleksis/apps/untis/preferences.py:99
msgid "Match course groups by a subset of parent groups if no 100% match is found"
msgstr ""
#: aleksis/apps/untis/preferences.py:100
msgid "Works only if 'Use course groups' is activated."
msgstr ""
#: aleksis/apps/untis/preferences.py:108
msgid "Ignore incomplete substitutions"
msgstr ""
......@@ -131,6 +139,6 @@ msgstr ""
msgid " Skip because missing subject"
msgstr ""
#: aleksis/apps/untis/util/mysql/importers/lessons.py:280
#: aleksis/apps/untis/util/mysql/importers/lessons.py:314
msgid "Deleted by Untis import"
msgstr ""
......@@ -7,11 +7,10 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-06 16:50+0100\n"
"POT-Creation-Date: 2022-03-23 11:34+0100\n"
"PO-Revision-Date: 2022-02-06 15:56+0000\n"
"Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
"Language-Team: German <https://translate.edugit.org/projects/aleksis/"
"aleksis-app-untis/de/>\n"
"Language-Team: German <https://translate.edugit.org/projects/aleksis/aleksis-app-untis/de/>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
......@@ -117,6 +116,14 @@ msgid "Build or search course groups for every course instead of setting classes
msgstr "Baut oder findet Kursgruppen für jeden Kurs anstatt die Klassengruppen zu setzen."
#: aleksis/apps/untis/preferences.py:99
msgid "Match course groups by a subset of parent groups if no 100% match is found"
msgstr ""
#: aleksis/apps/untis/preferences.py:100
msgid "Works only if 'Use course groups' is activated."
msgstr ""
#: aleksis/apps/untis/preferences.py:108
msgid "Ignore incomplete substitutions"
msgstr "Unvollständige Vertretungen ignorieren"
......@@ -132,7 +139,7 @@ msgstr " Wird wegen fehlender Zeiten übersprungen"
msgid " Skip because missing subject"
msgstr " Wird wegen fehlendem Fach übersprungen"
#: aleksis/apps/untis/util/mysql/importers/lessons.py:280
#: aleksis/apps/untis/util/mysql/importers/lessons.py:314
msgid "Deleted by Untis import"
msgstr "Gelöscht durch Untis-Import"
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-06 16:50+0100\n"
"POT-Creation-Date: 2022-03-23 11:34+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -116,6 +116,14 @@ msgid "Build or search course groups for every course instead of setting classes
msgstr ""
#: aleksis/apps/untis/preferences.py:99
msgid "Match course groups by a subset of parent groups if no 100% match is found"
msgstr ""
#: aleksis/apps/untis/preferences.py:100
msgid "Works only if 'Use course groups' is activated."
msgstr ""
#: aleksis/apps/untis/preferences.py:108
msgid "Ignore incomplete substitutions"
msgstr ""
......@@ -131,6 +139,6 @@ msgstr ""
msgid " Skip because missing subject"
msgstr ""
#: aleksis/apps/untis/util/mysql/importers/lessons.py:280
#: aleksis/apps/untis/util/mysql/importers/lessons.py:314
msgid "Deleted by Untis import"
msgstr ""
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-06 16:50+0100\n"
"POT-Creation-Date: 2022-03-23 11:34+0100\n"
"PO-Revision-Date: 2020-08-25 17:42+0000\n"
"Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
"Language-Team: Latin <https://translate.edugit.org/projects/aleksis/aleksis-app-untis/la/>\n"
......@@ -116,6 +116,14 @@ msgid "Build or search course groups for every course instead of setting classes
msgstr ""
#: aleksis/apps/untis/preferences.py:99
msgid "Match course groups by a subset of parent groups if no 100% match is found"
msgstr ""
#: aleksis/apps/untis/preferences.py:100
msgid "Works only if 'Use course groups' is activated."
msgstr ""
#: aleksis/apps/untis/preferences.py:108
msgid "Ignore incomplete substitutions"
msgstr ""
......@@ -131,7 +139,7 @@ msgstr ""
msgid " Skip because missing subject"
msgstr ""
#: aleksis/apps/untis/util/mysql/importers/lessons.py:280
#: aleksis/apps/untis/util/mysql/importers/lessons.py:314
msgid "Deleted by Untis import"
msgstr ""
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-06 16:50+0100\n"
"POT-Creation-Date: 2022-03-23 11:34+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -115,6 +115,14 @@ msgid "Build or search course groups for every course instead of setting classes
msgstr ""
#: aleksis/apps/untis/preferences.py:99
msgid "Match course groups by a subset of parent groups if no 100% match is found"
msgstr ""
#: aleksis/apps/untis/preferences.py:100
msgid "Works only if 'Use course groups' is activated."
msgstr ""
#: aleksis/apps/untis/preferences.py:108
msgid "Ignore incomplete substitutions"
msgstr ""
......@@ -130,6 +138,6 @@ msgstr ""
msgid " Skip because missing subject"
msgstr ""
#: aleksis/apps/untis/util/mysql/importers/lessons.py:280
#: aleksis/apps/untis/util/mysql/importers/lessons.py:314
msgid "Deleted by Untis import"
msgstr ""
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-06 16:50+0100\n"
"POT-Creation-Date: 2022-03-23 11:34+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -115,6 +115,14 @@ msgid "Build or search course groups for every course instead of setting classes
msgstr ""
#: aleksis/apps/untis/preferences.py:99
msgid "Match course groups by a subset of parent groups if no 100% match is found"
msgstr ""
#: aleksis/apps/untis/preferences.py:100
msgid "Works only if 'Use course groups' is activated."
msgstr ""
#: aleksis/apps/untis/preferences.py:108
msgid "Ignore incomplete substitutions"
msgstr ""
......@@ -130,6 +138,6 @@ msgstr ""
msgid " Skip because missing subject"
msgstr ""
#: aleksis/apps/untis/util/mysql/importers/lessons.py:280
#: aleksis/apps/untis/util/mysql/importers/lessons.py:314
msgid "Deleted by Untis import"
msgstr ""
......@@ -91,6 +91,15 @@ class UseCourseGroups(BooleanPreference):
)
@site_preferences_registry.register
class CourseGroupsFuzzyMatching(BooleanPreference):
section = untis_mysql
name = "course_groups_fuzzy_matching"
default = False
verbose_name = _("Match course groups by a subset of parent groups if no 100% match is found")
help_text = _("Works only if 'Use course groups' is activated.")
@site_preferences_registry.register
class IgnoreIncompleteSubstitutions(BooleanPreference):
section = untis_mysql
......
......@@ -124,22 +124,54 @@ def import_lessons(
# Negative import_ref denotes a course group
group_import_ref = -int("{}{}".format(lesson_id, i))
# Search by parent groups and subject
# Search by parent groups, teachers/owners and subject
qs = core_models.Group.objects.filter(
parent_groups__in=[c.id for c in course_classes],
subject_id=subject.id,
owners__in=[t.id for t in teachers],
).filter(Q(school_term__isnull=True) | Q(school_term=validity_range.school_term))
# Check if found groups match
match = False
for found_group in qs:
if compare_m2m(course_classes, found_group.parent_groups.all()):
if compare_m2m(course_classes, found_group.parent_groups.all()) and compare_m2m(
teachers, found_group.owners.all()
):
match = True
course_group = found_group
logger.info(
" Course group found by searching by parent groups and subject"
" Course group found by searching by parent groups, "
"teachers (owners) and subject"
)
if (
not match
and get_site_preferences()["untis_mysql__course_groups_fuzzy_matching"]
):
if qs.count() != 1:
logger.warning(
" Course group not found by searching by parent groups, "
"teachers (owners) and subject (fuzzy matching mode)"
)
else:
for found_group in qs:
if compare_m2m(teachers, found_group.owners.all()):
if match:
logger.warning(
" More than one course group found "
"by searching by parent groups, "
"teachers (owners) and subject (fuzzy matching mode)"
)
match = False
course_group = None
else:
match = True
course_group = found_group
logger.info(
" Course group found by searching by parent groups, "
"teachers (owners) and subject (fuzzy matching mode)"
)
changed = False
if not match:
# No matching group found
......@@ -236,10 +268,7 @@ def import_lessons(
# 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")
existing_lesson_period_pks = []
# Sync time periods
for j, time_period in enumerate(time_periods):
......@@ -253,24 +282,29 @@ def import_lessons(
room = None
# Check if an old lesson period is provided
old_lesson_period_qs = old_lesson_periods_qs.filter(element_id_untis=j)
old_lesson_period_qs = old_lesson_periods_qs.filter(period=time_period)
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")
lesson_period = old_lesson_period_qs[0]
if lesson_period.room != room or lesson_period.element_id_untis != j:
lesson_period.element_id_untis = j
lesson_period.room = room
lesson_period.save()
logger.info(" Untis reference and room updated")
else:
# Create new lesson period
chronos_models.LessonPeriod.objects.create(
lesson_period = chronos_models.LessonPeriod.objects.create(
lesson=lesson, period=time_period, room=room, element_id_untis=j
)
logger.info(" New time period added")
logger.info(" New lesson period added")
existing_lesson_period_pks.append(lesson_period.pk)
# delete all no-longer existing lesson periods
old_lesson_periods_qs.exclude(pk__in=existing_lesson_period_pks).delete()
logger.info(" Old lesson periods deleted")
current_teacher_id = teacher_id
for lesson in chronos_models.Lesson.objects.filter(validity=validity_range):
......
......@@ -5,6 +5,7 @@ from django.db.models import QuerySet
import reversion
from tqdm import tqdm
from aleksis.apps.chronos.util.change_tracker import TimetableDataChangeTracker
from aleksis.apps.untis.util.mysql.importers.terms import import_terms
from aleksis.apps.untis.util.mysql.util import TQDM_DEFAULTS
......@@ -35,6 +36,8 @@ def untis_import_mysql(terms: Optional[QuerySet] = None, version: Optional[int]
with reversion.create_revision(atomic=True):
reversion.set_comment(f"Untis import for validity range {validity_range}")
tracker = TimetableDataChangeTracker()
# Common data for Chronos
subjects_ref = import_subjects(validity_range)
rooms_ref = import_rooms(validity_range)
......
......@@ -31,7 +31,7 @@ author = "The AlekSIS Team"
# The short X.Y version
version = "2.1"
# The full version, including alpha/beta/rc tags
release = "2.1.3.dev0"
release = "2.1.4.dev0"
# -- General configuration ---------------------------------------------------
......
[tool.poetry]
name = "AlekSIS-App-Untis"
version = "2.1.3.dev0"
version = "2.1.4.dev0"
packages = [
{ include = "aleksis" }
]
......@@ -41,11 +41,11 @@ python = "^3.9"
mysqlclient = "^2.0.0"
tqdm = "^4.44.1"
defusedxml = "^0.7.0"
aleksis-core = "^2.0"
aleksis-app-chronos = "^2.0"
aleksis-core = "^2.8"
aleksis-app-chronos = "^2.3"
[tool.poetry.dev-dependencies]
aleksis-builddeps = "^6"
aleksis-builddeps = "*"
[tool.poetry.plugins."aleksis.app"]
untis = "aleksis.apps.untis.apps:UntisConfig"
......