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 (1)
import pkg_resources
try:
__version__ = pkg_resources.get_distribution('BiscuIT-App-Untis').version
__version__ = pkg_resources.get_distribution("BiscuIT-App-Untis").version
except Exception:
__version__ = 'unknown'
__version__ = "unknown"
default_app_config = 'biscuit.apps.untis.apps.UntisConfig'
default_app_config = "biscuit.apps.untis.apps.UntisConfig"
......@@ -2,5 +2,5 @@ from biscuit.core.util.apps import AppConfig
class UntisConfig(AppConfig):
name = 'biscuit.apps.untis'
verbose_name = 'BiscuIT - Untis interface'
name = "biscuit.apps.untis"
verbose_name = "BiscuIT - Untis interface"
......@@ -3,4 +3,4 @@ from django.utils.translation import ugettext_lazy as _
class UntisUploadForm(forms.Form):
untis_xml = forms.FileField(label=_('Untis XML export'))
untis_xml = forms.FileField(label=_("Untis XML export"))
......@@ -6,10 +6,9 @@ from ...util import untis_import_xml
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('untis_xml_path', help=_(
'Path to Untis XML export file'))
parser.add_argument("untis_xml_path", help=_("Path to Untis XML export file"))
def handle(self, *args, **options):
untis_xml = open(options['untis_xml_path'], 'rb')
untis_xml = open(options["untis_xml_path"], "rb")
untis_import_xml(None, untis_xml)
from django.utils.translation import ugettext_lazy as _
MENUS = {
'DATA_MANAGEMENT_MENU': [
"DATA_MANAGEMENT_MENU": [
{
'name': _('Units import'),
'url': 'untis_import',
'validators': ['menu_generator.validators.is_authenticated', 'menu_generator.validators.is_superuser', 'biscuit.core.util.core_helpers.has_person'],
"name": _("Units import"),
"url": "untis_import",
"validators": [
"menu_generator.validators.is_authenticated",
"menu_generator.validators.is_superuser",
"biscuit.core.util.core_helpers.has_person",
],
}
]
}
......@@ -2,7 +2,6 @@ from django.urls import path
from . import views
urlpatterns = [
path('import', views.untis_import, name='untis_import'),
path("import", views.untis_import, name="untis_import"),
]
from datetime import date, time, timedelta
from typing import BinaryIO, Optional, Union
from xml.dom import minidom, Node
from xml.dom import Node, minidom
from django.http import HttpRequest
from django.utils.translation import ugettext as _
from biscuit.apps.chronos.models import Subject, TimePeriod, Room, Lesson
from biscuit.apps.chronos.models import Lesson, Room, Subject, TimePeriod
from biscuit.core.models import Group, Person
from biscuit.core.util import messages
......@@ -23,7 +23,7 @@ def get_child_node_id(node: Node, tag: str) -> Optional[str]:
tag_nodes = node.getElementsByTagName(tag)
if len(tag_nodes) == 1:
return tag_nodes[0].attributes['id'].value
return tag_nodes[0].attributes["id"].value
else:
return None
......@@ -31,120 +31,146 @@ def get_child_node_id(node: Node, tag: str) -> Optional[str]:
def untis_import_xml(request: HttpRequest, untis_xml: Union[BinaryIO, str]) -> None:
dom = minidom.parse(untis_xml)
subjects = dom.getElementsByTagName('subject')
subjects = dom.getElementsByTagName("subject")
for subject_node in subjects:
abbrev = subject_node.attributes['id'].value[3:]
name = get_child_node_text(subject_node, 'longname')
colour_fg = get_child_node_text(subject_node, 'forecolor')
colour_bg = get_child_node_text(subject_node, 'backcolor')
abbrev = subject_node.attributes["id"].value[3:]
name = get_child_node_text(subject_node, "longname")
colour_fg = get_child_node_text(subject_node, "forecolor")
colour_bg = get_child_node_text(subject_node, "backcolor")
Subject.objects.update_or_create(abbrev=abbrev, defaults={
'name': name, 'colour_fg': colour_fg, 'colour_bg': colour_bg})
Subject.objects.update_or_create(
abbrev=abbrev,
defaults={"name": name, "colour_fg": colour_fg, "colour_bg": colour_bg},
)
periods = dom.getElementsByTagName('timeperiod')
periods = dom.getElementsByTagName("timeperiod")
for period_node in periods:
weekday = int(get_child_node_text(period_node, 'day'))
period = int(get_child_node_text(period_node, 'period'))
starttime = get_child_node_text(period_node, 'starttime')
endtime = get_child_node_text(period_node, 'endtime')
weekday = int(get_child_node_text(period_node, "day"))
period = int(get_child_node_text(period_node, "period"))
starttime = get_child_node_text(period_node, "starttime")
endtime = get_child_node_text(period_node, "endtime")
time_start = time(int(starttime[:2]), int(starttime[2:]))
time_end = time(int(endtime[:2]), int(endtime[2:]))
TimePeriod.objects.update_or_create(weekday=weekday, period=period, defaults={
'time_start': time_start, 'time_end': time_end})
TimePeriod.objects.update_or_create(
weekday=weekday,
period=period,
defaults={"time_start": time_start, "time_end": time_end},
)
rooms = dom.getElementsByTagName('room')
rooms = dom.getElementsByTagName("room")
for room_node in rooms:
short_name = room_node.attributes['id'].value[3:]
name = get_child_node_text(room_node, 'longname')
short_name = room_node.attributes["id"].value[3:]
name = get_child_node_text(room_node, "longname")
Room.objects.update_or_create(short_name=short_name, defaults={
'name': name})
Room.objects.update_or_create(short_name=short_name, defaults={"name": name})
classes = dom.getElementsByTagName('class')
classes = dom.getElementsByTagName("class")
for class_node in classes:
short_name = class_node.attributes['id'].value[3:]
name = _('Class %s') % short_name
class_teacher_short_name = get_child_node_id(
class_node, 'class_teacher')[3:]
short_name = class_node.attributes["id"].value[3:]
name = _("Class %s") % short_name
class_teacher_short_name = get_child_node_id(class_node, "class_teacher")[3:]
class_, created = Group.objects.update_or_create(short_name=short_name, defaults={
'name': name})
class_, created = Group.objects.update_or_create(
short_name=short_name, defaults={"name": name}
)
try:
# Teachers need to come from another source, e.g. SchILD-NRW
class_.owners.set([Person.objects.get(
short_name=class_teacher_short_name)])
class_.owners.set([Person.objects.get(short_name=class_teacher_short_name)])
class_.save()
except Person.DoesNotExist:
messages.warning(request, _('Could not set class teacher of %(class)s to %(teacher)s.') % {
'class': short_name, 'teacher': class_teacher_short_name})
messages.warning(
request,
_("Could not set class teacher of %(class)s to %(teacher)s.")
% {"class": short_name, "teacher": class_teacher_short_name},
)
# Set all existing lessons that overlap to end today
today = date.today()
Lesson.objects.filter(
date_end__gt=today
).update(
date_end=today
)
Lesson.objects.filter(date_end__gt=today).update(date_end=today)
lessons = dom.getElementsByTagName('lesson')
lessons = dom.getElementsByTagName("lesson")
for lesson_node in lessons:
subject_abbrev = get_child_node_id(lesson_node, 'lesson_subject')[3:]
teacher_short_name = get_child_node_id(
lesson_node, 'lesson_teacher')[3:]
group_short_names = [v.strip() for v in get_child_node_id(
lesson_node, 'lesson_classes').split('CL_') if v.strip()]
effectivebegindate = get_child_node_text(
lesson_node, 'effectivebegindate')
effectiveenddate = get_child_node_text(lesson_node, 'effectiveenddate')
times = lesson_node.getElementsByTagName('time')
subject_abbrev = get_child_node_id(lesson_node, "lesson_subject")[3:]
teacher_short_name = get_child_node_id(lesson_node, "lesson_teacher")[3:]
group_short_names = [
v.strip()
for v in get_child_node_id(lesson_node, "lesson_classes").split("CL_")
if v.strip()
]
effectivebegindate = get_child_node_text(lesson_node, "effectivebegindate")
effectiveenddate = get_child_node_text(lesson_node, "effectiveenddate")
times = lesson_node.getElementsByTagName("time")
time_periods = []
for time_node in times:
day = int(get_child_node_text(time_node, 'assigned_day'))
period = int(get_child_node_text(time_node, 'assigned_period'))
day = int(get_child_node_text(time_node, "assigned_day"))
period = int(get_child_node_text(time_node, "assigned_period"))
room_id = get_child_node_id(time_node, 'assigned_room')
room_id = get_child_node_id(time_node, "assigned_room")
room = room_id[3:] if room_id else None
time_periods.append((day, period, room))
subject = Subject.objects.get(abbrev=subject_abbrev)
periods = [(TimePeriod.objects.get(
weekday=v[0], period=v[1]), Room.objects.get(short_name=v[2]) if v[2] else None) for v in time_periods]
date_start = date(int(effectivebegindate[:4]), int(effectivebegindate[4:6]), int(
effectivebegindate[6:])) if effectivebegindate else None
date_end = date(int(effectiveenddate[:4]), int(effectiveenddate[4:6]), int(
effectiveenddate[6:])) if effectiveenddate else None
periods = [
(
TimePeriod.objects.get(weekday=v[0], period=v[1]),
Room.objects.get(short_name=v[2]) if v[2] else None,
)
for v in time_periods
]
date_start = (
date(
int(effectivebegindate[:4]),
int(effectivebegindate[4:6]),
int(effectivebegindate[6:]),
)
if effectivebegindate
else None
)
date_end = (
date(
int(effectiveenddate[:4]),
int(effectiveenddate[4:6]),
int(effectiveenddate[6:]),
)
if effectiveenddate
else None
)
# Coerce effective start date to not be before tomorrow
if date_start and date_start <= today:
date_start = today + timedelta(days=1)
try:
groups = [Group.objects.get(short_name=v)
for v in group_short_names]
groups = [Group.objects.get(short_name=v) for v in group_short_names]
except Group.DoesNotExist:
messages.error(request, _('Invalid list of classes: %s') %
', '.join(group_short_names))
messages.error(
request, _("Invalid list of classes: %s") % ", ".join(group_short_names)
)
continue
try:
teachers = [Person.objects.get(short_name=teacher_short_name)]
except Person.DoesNotExist:
messages.error(request, _(
'Failed to import lesson: Teacher %s does not exist.') % teacher_short_name)
messages.error(
request,
_("Failed to import lesson: Teacher %s does not exist.")
% teacher_short_name,
)
continue
lesson = Lesson.objects.create(
subject=subject, date_start=date_start, date_end=date_end)
subject=subject, date_start=date_start, date_end=date_end
)
lesson.groups.set(groups)
lesson.teachers.set(teachers)
for period in periods:
lesson.periods.add(period[0], through_defaults={'room': period[1]})
lesson.periods.add(period[0], through_defaults={"room": period[1]})
lesson.save()
......@@ -2,11 +2,11 @@ from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from biscuit.core.decorators import admin_required
from .forms import UntisUploadForm
from .util import untis_import_xml
from biscuit.core.decorators import admin_required
@login_required
@admin_required
......@@ -15,12 +15,12 @@ def untis_import(request: HttpRequest) -> HttpResponse:
upload_form = UntisUploadForm()
if request.method == 'POST':
if request.method == "POST":
upload_form = UntisUploadForm(request.POST, request.FILES)
if upload_form.is_valid():
untis_import_xml(request, request.FILES['untis_xml'])
untis_import_xml(request, request.FILES["untis_xml"])
context['upload_form'] = upload_form
context["upload_form"] = upload_form
return render(request, 'untis/untis_import.html', context)
return render(request, "untis/untis_import.html", context)