diff --git a/biscuit/apps/chronos/migrations/0001_initial.py b/biscuit/apps/chronos/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..0bd9a91cd6a06f44118fd2f1eabb5a16006645ae --- /dev/null +++ b/biscuit/apps/chronos/migrations/0001_initial.py @@ -0,0 +1,45 @@ +# Generated by Django 2.0 on 2018-03-22 17:07 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Class', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=10)), + ('text1', models.CharField(max_length=200)), + ('text2', models.CharField(max_length=200)), + ], + ), + migrations.CreateModel( + name='Room', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('shortcode', models.CharField(max_length=10)), + ('name', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='Teacher', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('shortcode', models.CharField(max_length=10)), + ('first_name', models.CharField(max_length=100)), + ('name', models.CharField(max_length=100)), + ], + ), + migrations.AddField( + model_name='class', + name='room', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='timetable.Room'), + ), + ] diff --git a/biscuit/apps/chronos/models.py b/biscuit/apps/chronos/models.py index 71a836239075aa6e6e4ecb700e9c42c95c022d91..09889fffd56372c41c7f2919185143852fa1af5c 100644 --- a/biscuit/apps/chronos/models.py +++ b/biscuit/apps/chronos/models.py @@ -1,3 +1,21 @@ from django.db import models + # Create your models here. + +class Teacher(models.Model): + shortcode = models.CharField(max_length=10) + first_name = models.CharField(max_length=100) + name = models.CharField(max_length=100) + + +class Room(models.Model): + shortcode = models.CharField(max_length=10) + name = models.CharField(max_length=100) + + +class Class(models.Model): + name = models.CharField(max_length=10) + text1 = models.CharField(max_length=200) + text2 = models.CharField(max_length=200) + room = models.ForeignKey(Room, on_delete=models.CASCADE) diff --git a/biscuit/apps/chronos/parse.py b/biscuit/apps/chronos/parse.py new file mode 100644 index 0000000000000000000000000000000000000000..8ffb08fc3f8d3624835341b096e11386d058f541 --- /dev/null +++ b/biscuit/apps/chronos/parse.py @@ -0,0 +1,222 @@ +class Lesson(object): + def __init__(self): + self.filled = False + self.id = None + self.elements = [] + self.times = [] + + def add_element(self, teacher, subject, rooms=[], classes=[]): + el = LessonElement() + el.create(teacher, subject, rooms, classes) + self.elements.append(el) + + def add_time(self, day, hour, rooms=[]): + el = LessonTime() + el.create(day, hour, rooms) + self.times.append(el) + + def create(self, db_obj): + self.filled = True + + +class LessonElement(object): + def __init__(self): + self.teacher = None + self.subject = None + self.rooms = [] + self.classes = [] + + def create(self, teacher, subject, rooms=[], classes=[]): + self.teacher = teacher + self.subject = subject + self.rooms = rooms + self.classes = classes + + +class LessonTime(object): + def __init__(self): + self.hour = None + self.day = None + self.rooms = [] + + def create(self, day, hour, rooms=[]): + self.day = day + self.hour = hour + self.rooms = rooms + + +from untisconnect.api import * + +try: + from schoolapps.untisconnect.api import * +except Exception: + pass + + +def clean_array(a, conv=None): + b = [] + for el in a: + if el != '' and el != "0": + if conv is not None: + el = conv(el) + b.append(el) + return b + + +def untis_split(s, conv=None): + return clean_array(s.split(";"), conv=conv) + + +def parse(): + odrive = { + "teachers": get_all_teachers(), + "rooms": get_all_rooms(), + "classes": get_all_classes(), + "subjects": get_all_subjects() + } + + drive = { + "teachers": {}, + "rooms": {}, + "classes": {}, + "subjects": {} + } + for key, value in odrive.items(): + for el in value: + id = el.id + drive[key][id] = el + + print(drive) + + lessons = [] + raw_lessons = get_raw_lessons() + + for raw_lesson in raw_lessons: + # print("[RAW LESSON]") + # print("LESSON_ID | ", raw_lesson.lesson_id) + # print("LessonElement1 | ", raw_lesson.lessonelement1) + # print("Lesson_TT | ", raw_lesson.lesson_tt) + + if raw_lesson.lesson_tt and raw_lesson.lessonelement1: + # Create object + lesson_obj = Lesson() + + # Split data (,) + lesson_id = raw_lesson.lesson_id + raw_lesson_data = raw_lesson.lessonelement1.split(",") + raw_time_data = raw_lesson.lesson_tt.split(",") + + # print(raw_lesson_data) + # print(raw_time_data) + + # Split data more (~) + rld2 = [] + for el in raw_lesson_data: + rld2.append(el.split("~")) + + # print(rld2) + + for el in rld2: + teacher_id = int(el[0]) + subject_id = int(el[2]) + room_ids = untis_split(el[4], int) + class_ids = untis_split(el[17], conv=int) + # print("TEACHER – ", teacher_id, "; SUBJECT – ", subject_id, "; ROOMS – ", room_ids, "; CLASSES – ", + # class_ids) + + if teacher_id != 0: + teacher = drive["teachers"][teacher_id] + else: + teacher = None + + if subject_id != 0: + subject = drive["subjects"][subject_id] + else: + subject = None + + rooms = [] + for room_id in room_ids: + r = drive["rooms"][room_id] + rooms.append(r) + + classes = [] + for class_id in class_ids: + c = drive["classes"][class_id] + classes.append(c) + + # print("TEACHER – ", teacher, "; SUBJECT – ", subject, "; ROOMS – ", rooms, + # "; CLASSES – ", classes) + + lesson_obj.add_element(teacher, subject, rooms, classes) + + rtd2 = [] + for el in raw_time_data: + rtd2.append(el.split("~")) + + # print(rtd2) + + for el in rtd2: + day = int(el[1]) + hour = int(el[2]) + room_ids = untis_split(el[3], conv=int) + + rooms = [] + for room_id in room_ids: + r = drive["rooms"][room_id] + rooms.append(r) + + lesson_obj.add_time(day, hour, rooms) + + # print("DAY – ", day, "; HOUR – ", hour, "; ROOMS – ", room_ids) + + lessons.append(lesson_obj) + + return lessons + + +TYPE_TEACHER = 0 +TYPE_ROOM = 1 +TYPE_CLASS = 2 + + +def get_plan(type, id): + lessons = parse() + plan = [[[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []], + [[], [], [], [], []]] + + for lesson in lessons: + for element in lesson.elements: + found = False + if type == TYPE_CLASS: + for lclass in element.classes: + if lclass.id == id: + found = True + + elif type == TYPE_TEACHER: + if element.teacher: + if element.teacher.id == id: + found = True + + elif type == TYPE_ROOM: + for lroom in element.rooms: + if lroom.id == id: + found = True + + if found: + for time in lesson.times: + # print(time.hour, " ", time.day) + # print(element.subject.shortcode) + plan[time.hour - 1][time.day - 1].append(element) + + # print(plan) + + return plan diff --git a/biscuit/apps/chronos/templates/timetable/admin/all.html b/biscuit/apps/chronos/templates/timetable/admin/all.html new file mode 100644 index 0000000000000000000000000000000000000000..75dfdf695d821225c05e2c27a3e2af57e673694f --- /dev/null +++ b/biscuit/apps/chronos/templates/timetable/admin/all.html @@ -0,0 +1,62 @@ +{% include 'partials/header.html' %} + +<main> + <h3>Übersicht</h3> + <div class="row"> + <div class="col s12 m3"> + <h4>Alle Lehrkräfte</h4> + <ul class="collection"> + {% for teacher in teachers %} + <li class="collection-item avatar"> + <i class="circle">{{ teacher.shortcode }}</i><!-- Shortcode --> + <a href="{% url 'timetable_plan' 'teacher' teacher.id %}">{{ teacher.first_name }} + <strong>{{ teacher.name }}</strong></a> + </li> + {% endfor %} + </ul> + </div> + + <div class="col s12 m3"> + <h4>Alle Klassen</h4> + <ul class="collection"> + {% for class in classes %} + <li class="collection-item avatar"> + <i class="circle">{{ class.name }}</i> + <a href="{% url 'timetable_plan' 'class' class.id %}"><strong>{{ class.name }}</strong></a> + <p> + {{ class.text1|default:"" }} – {{ class.text2|default:"" }} <br> + Raum: {{ class.room.name|default:"---" }} + </p> + </li> + {% endfor %} + </ul> + </div> + + <div class="col s12 m3"> + <h4>Alle Räume</h4> + <ul class="collection"> + {% for room in rooms %} + <li class="collection-item avatar"> + <i class="circle">{{ room.shortcode }}</i> + <a href="{% url 'timetable_plan' 'room' room.id %}"><strong>{{ room.name }}</strong></a> + </li> + {% endfor %} + </ul> + </div> + + <div class="col s12 m3"> + <h4>Alle Fächer</h4> + <ul class="collection"> + {% for subject in subjects %} + <li class="collection-item avatar"> + <i class="circle">{{ subject.shortcode }}</i> + <strong>{{ subject.shortcode }}</strong> + </li> + {% endfor %} + </ul> + </div> + </div> + +</main> + +{% include 'partials/footer.html' %} diff --git a/biscuit/apps/chronos/templates/timetable/admin/teachers.html b/biscuit/apps/chronos/templates/timetable/admin/teachers.html deleted file mode 100644 index b5262ba8f0df58b1f62890238a128b89546b972c..0000000000000000000000000000000000000000 --- a/biscuit/apps/chronos/templates/timetable/admin/teachers.html +++ /dev/null @@ -1,14 +0,0 @@ -{% include 'partials/header.html' %} - -<main> - <ul class="collection"> - {% for teacher in teachers %} - <li class="collection-item avatar"> - <i class="circle">{{ teacher.shortcode }}</i> - {{ teacher.first_name }} <strong>{{ teacher.name }}</strong> - </li> - {% endfor %} - </ul> -</main> - -{% include 'partials/footer.html' %} diff --git a/biscuit/apps/chronos/templates/timetable/plan.html b/biscuit/apps/chronos/templates/timetable/plan.html new file mode 100644 index 0000000000000000000000000000000000000000..90ab77494b36c05faeb3413c3d902cb646c6d0f6 --- /dev/null +++ b/biscuit/apps/chronos/templates/timetable/plan.html @@ -0,0 +1,105 @@ +{% include 'partials/header.html' %} + +<main> + <h3> + Stundenplan <i>{{ el }}</i> + </h3> + <div class="row"> + <div class="col s2"> + + </div> + <div class="col s2"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + Montag + </span> + </div> + </div> + </div> + <div class="col s2"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + Dienstag + </span> + </div> + </div> + </div> + <div class="col s2"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + Mittwoch + </span> + </div> + </div> + </div> + <div class="col s2"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + Donnerstag + </span> + </div> + </div> + </div> + <div class="col s2"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + Freitag + </span> + </div> + </div> + </div> + + </div> + {% for row in plan %} + <div class="row"> + <div class="col s2"> + <div class="card timetable-title-card"> + <div class="card-content"> + <span class="card-title"> + 0. + </span> + </div> + </div> + + </div> + {% for col in row %} + <div class="col s2"> + <div class="card lesson-card"> + <div class="card-content"> + {% for element in col %} + <p> + + {% if type == 0 or type == 1 %} + {% for class in element.classes %} + {{ class.name }} + {% endfor %} + {% endif %} + {% if type == 2 or type == 1 %} + <span data-position="bottom" class="tooltipped" + data-tooltip="{{ element.teacher }}">{{ element.teacher.shortcode }}</span> + {% endif %} + <strong>{{ element.subject.shortcode }}</strong> + {% if type == 0 or type == 2 %} + {% for room in element.rooms %} + <span class="tooltipped" data-position="bottom" + data-tooltip="{{ room.name }}">{{ room.shortcode }}</span> + {% endfor %} + {% endif %} + </p> + + {% endfor %} + </div> + </div> + </div> + {% endfor %} + </div> + {% endfor %} + +</main> + +{% include 'partials/footer.html' %} diff --git a/biscuit/apps/chronos/urls.py b/biscuit/apps/chronos/urls.py index 18fbd72bb541400e80779ca7fece1e8b841479a2..28d1f0992db7246f2ed51c7a1d908100529c0dce 100644 --- a/biscuit/apps/chronos/urls.py +++ b/biscuit/apps/chronos/urls.py @@ -2,5 +2,6 @@ from django.urls import path from . import views urlpatterns = [ - path('teachers/', views.admin_teachers, name='timetable_admin_teachers') + path('admin/all/', views.admin_all, name='timetable_admin_all'), + path('plan/<str:plan_type>/<int:plan_id>', views.plan, name='timetable_plan') ] diff --git a/biscuit/apps/chronos/views.py b/biscuit/apps/chronos/views.py index 794b866bbc8e1ccdb59076a2dc99c6f19e63475f..d76c9d325ffbfd58a264124b206b8a52091283fe 100644 --- a/biscuit/apps/chronos/views.py +++ b/biscuit/apps/chronos/views.py @@ -1,12 +1,51 @@ from django.contrib.auth.decorators import login_required +from django.http import Http404 from django.shortcuts import render -from untisconnect.api import get_all_teachers +from untisconnect.api import * +from .parse import * + +try: + from schoolapps.untisconnect.api import * +except Exception: + pass + # Create your views here. @login_required -def admin_teachers(request): +def admin_all(request): teachers = get_all_teachers() + classes = get_all_classes() + rooms = get_all_rooms() + subjects = get_all_subjects() + context = { + 'teachers': teachers, + 'classes': classes, + 'rooms': rooms, + 'subjects': subjects + } + return render(request, 'timetable/admin/all.html', context) + + +@login_required +def plan(request, plan_type, plan_id): + if plan_type == 'teacher': + _type = TYPE_TEACHER + el = get_teacher_by_id(plan_id) + elif plan_type == 'class': + _type = TYPE_CLASS + el = get_class_by_id(plan_id) + elif plan_type == 'room': + _type = TYPE_ROOM + el = get_room_by_id(plan_id) + else: + raise Http404('Page not found.') + + plan = get_plan(_type, plan_id) + context = { - "teachers": teachers + "type": _type, + "plan": plan, + "el": el } - return render(request, "timetable/admin/teachers.html", context) + + return render(request, 'timetable/plan.html', context)