From fe8d151257c7e4ce284c6dfc8399ec821d3a020b Mon Sep 17 00:00:00 2001 From: sveco86 Date: Tue, 2 Jun 2026 20:30:08 +0200 Subject: [PATCH] Improve example scripts and handle missing substitution teachers --- edupage_api/substitution.py | 8 ++- examples/get_homework.py | 131 ++++++++++++++++++++++++++++-------- examples/lunch_simple.py | 12 ++-- examples/substitution.py | 57 +++++++++++++--- examples/teachers.py | 52 +++++++------- examples/timetables.py | 73 ++++++++++++-------- 6 files changed, 234 insertions(+), 99 deletions(-) diff --git a/edupage_api/substitution.py b/edupage_api/substitution.py index 5c277c9..073ac2b 100644 --- a/edupage_api/substitution.py +++ b/edupage_api/substitution.py @@ -62,7 +62,13 @@ def get_missing_teachers(self, date: date) -> Optional[list[EduTeacher]]: if not missing_teachers_string: return None - _title, missing_teachers = missing_teachers_string.split(": ") + missing_teachers_data = missing_teachers_string.split(": ", 1) + if len(missing_teachers_data) != 2: + return None + + _title, missing_teachers = missing_teachers_data + if not missing_teachers: + return None all_teachers = People(self.edupage).get_teachers() diff --git a/examples/get_homework.py b/examples/get_homework.py index a7ea598..1da29eb 100644 --- a/examples/get_homework.py +++ b/examples/get_homework.py @@ -1,53 +1,130 @@ from datetime import datetime from edupage_api import Edupage +from edupage_api.dbi import DbiHelper +from edupage_api.subjects import Subjects from edupage_api.timeline import EventType +import json + edupage = Edupage() edupage.login( - "Username (or e-mail)", - "Password", - "Subdomain of your school (SUBDOMAIN.edupage.org)", + "#EMAIL_ADDRESS#", + "#PASSWORD#", + "#SCHOOL_EDUPAGE_SUBDOMAIN#", # SUBDOMAIN.edupage.org ) notifications = edupage.get_notifications() -homework_not_due = 0 +json_data = [] + +#homework_not_due = 0 + +homework_types = { + EventType.HOMEWORK, + EventType.TESTING, + EventType.HOMEWORK_TEST, + EventType.EXAM_ASSIGNMENT, +} + +exam_event_types = { + "exam", + "bexam", + "sexam", + "oexam", + "rexam", + "pexam", +} + +def is_homework_notification(event): + if event.event_type in homework_types: + return True + if event.event_type == EventType.EVENT: + if isinstance(event.additional_data, dict) and event.additional_data.get("typ") in exam_event_types: + return True + return False + -homework = list(filter(lambda x: x.event_type == EventType.HOMEWORK, notifications)) +def get_subject_name(event): + recipient = event.recipient + if isinstance(recipient, str) and " · " in recipient: + return recipient.split(" · ", 1)[1].strip() + + if isinstance(event.additional_data, dict): + subject_id = event.additional_data.get("subjectid") or event.additional_data.get("predmetid") + if subject_id: + try: + subject = Subjects(edupage).get_subject(subject_id) + except (TypeError, ValueError): + subject = None + if subject is not None: + return subject.name or subject.short + try: + return DbiHelper(edupage).fetch_subject_name(int(subject_id)) + except (TypeError, ValueError): + return None + + return recipient if recipient is not None else "" + +homework = [x for x in notifications if is_homework_notification(x)] +#print(homework) for hw in homework: - additional_data = hw.additional_data + additional_data = hw.additional_data if isinstance(hw.additional_data, dict) else {} - old_vals = additional_data.get("oldVals") + if additional_data.get("textReply"): + continue - due_date = None + due_date = additional_data.get("date") hw_title = None + hw_from = f"{hw.timestamp}" - if old_vals: - try: - due_date = old_vals.get("date") - due_date = datetime.strptime(due_date, "%Y-%m-%d") - except TypeError: - pass + def format_homework_text(event): + if ( + event.event_type == EventType.EVENT + and isinstance(event.additional_data, dict) + and event.additional_data.get("typ") in exam_event_types + ): + event_name = event.additional_data.get("name") or event.text + if isinstance(event_name, str): + event_name = event_name.strip() + for prefix in ("Udalosť:", "Udalosť:", "Udalosť:"): + if event_name.startswith(prefix): + event_name = event_name[len(prefix) :].strip() + break + return f"Písomka: {event_name}" + if event.event_type == EventType.EXAM_ASSIGNMENT: + assignment_name = ( + event.additional_data.get("name") + or event.additional_data.get("nazov") + or event.additional_data.get("title") + or event.text + ) + return (assignment_name or "").replace("\n", " ") + return (event.text or "").replace("\n", " ") - hw_title = old_vals.get("title") + hw_text = hw_title or format_homework_text(hw) + text = f"{hw_text}" - text = f"Homework from {hw.timestamp}\n" - - hw_text = hw_title or hw.text.replace("\n", " ") - text += f"{hw_text}" + hw_subject = get_subject_name(hw) if due_date: now = datetime.now() - text += f"\nDue to: {due_date} -> " + #text += f"\nDue to: {due_date}" + + dt_due_date = datetime.strptime(due_date, "%Y-%m-%d") - if due_date > now: - text += "DUE" + if dt_due_date >= now: + text += "" else: - homework_not_due += 1 - text += "UNFINISHED" + #homework_not_due += 1 + continue - print(text) - print("—") + # Append homework details to list + json_data.append({ + "Homework from": hw_from, + "Text of HW": text, + "Subject": hw_subject, + "Due to": due_date + }) -print(f"You have {homework_not_due} unfinished homework assignments.") +print(json.dumps(json_data)) diff --git a/examples/lunch_simple.py b/examples/lunch_simple.py index 301308d..8911174 100644 --- a/examples/lunch_simple.py +++ b/examples/lunch_simple.py @@ -2,15 +2,19 @@ from datetime import datetime edupage = Edupage() -edupage.login_auto("Username (or e-mail)", "Password") +edupage.login( + "#EMAIL_ADDRESS#", + "#PASSWORD#", + "#SCHOOL_EDUPAGE_SUBDOMAIN#", # SUBDOMAIN.edupage.org +) meals = edupage.get_meals(datetime.today().date()) lunch = meals.lunch print(lunch.menus) -snack = meals.snack -print(snack.menus) +#snack = meals.snack +#print(snack.menus) # i don't want a snack for today! -snack.sign_off(edupage) \ No newline at end of file +# snack.sign_off(edupage) diff --git a/examples/substitution.py b/examples/substitution.py index 4a2bc76..67e35ef 100644 --- a/examples/substitution.py +++ b/examples/substitution.py @@ -1,20 +1,55 @@ -from datetime import datetime +import json +from datetime import date, timedelta from edupage_api import Edupage edupage = Edupage() -edupage.login_auto("Username (or e-mail)", "Password") +edupage.login( + "#EMAIL_ADDRESS#", + "#PASSWORD#", + "#SCHOOL_EDUPAGE_SUBDOMAIN#", # SUBDOMAIN.edupage.org +) -tomorrow = datetime.now() -missing_teachers = edupage.get_missing_teachers(tomorrow) -print(f"There are {len(missing_teachers)} missing tomorrow!") +substitution_date = date.today() + timedelta(days=1) -print() -print("Teachers missing:", end=" ") -for i, teacher in enumerate(missing_teachers): - if i != 0: - print(", ", end="") +def format_date(value): + return value.strftime("%Y-%m-%d") if value else None - print(f"{teacher.name}", end="") + +def format_enum(value): + return value.value if value else None + + +def teacher_to_dict(teacher): + return { + "person_id": teacher.person_id, + "name": teacher.name, + "gender": format_enum(teacher.gender), + "in_school_since": format_date(teacher.in_school_since), + "account_type": format_enum(teacher.account_type), + "classroom_name": teacher.classroom_name, + "teacher_to": format_date(teacher.teacher_to), + } + + +def change_to_dict(change): + return { + "class": change.change_class, + "lesson": change.lesson_n, + "title": change.title, + "action": format_enum(change.action), + } + + +missing_teachers = edupage.get_missing_teachers(substitution_date) or [] +timetable_changes = edupage.get_timetable_changes(substitution_date) or [] + +json_data = { + "date": substitution_date.strftime("%Y-%m-%d"), + "missing_teachers": [teacher_to_dict(teacher) for teacher in missing_teachers], + "timetable_changes": [change_to_dict(change) for change in timetable_changes], +} + +print(json.dumps(json_data, ensure_ascii=False, indent=2)) diff --git a/examples/teachers.py b/examples/teachers.py index 8cd23c6..32dd667 100644 --- a/examples/teachers.py +++ b/examples/teachers.py @@ -1,42 +1,36 @@ +import json + from edupage_api import Edupage -from edupage_api.people import EduTeacher edupage = Edupage() -edupage.login_auto("Username (or e-mail)", "Password") +edupage.login( + "#EMAIL_ADDRESS#", + "#PASSWORD#", + "#SCHOOL_EDUPAGE_SUBDOMAIN#", # SUBDOMAIN.edupage.org +) teachers = edupage.get_teachers() -def print_teacher_info(teacher: EduTeacher): - print(f"{teacher.name} is in your school since {teacher.in_school_since}") - - -oldest_teacher = None -for teacher in teachers: - if not teacher.in_school_since: - continue - - if oldest_teacher is None: - oldest_teacher = teacher - continue +def format_date(value): + return value.strftime("%Y-%m-%d") if value else None - if teacher.in_school_since < oldest_teacher.in_school_since: - oldest_teacher = teacher -print("The oldest teacher (the longest time in your school):") -print_teacher_info(oldest_teacher) +def format_enum(value): + return value.value if value else None -youngest_teacher = None -for teacher in teachers: - if not teacher.in_school_since: - continue - if youngest_teacher is None: - youngest_teacher = teacher - continue +def teacher_to_dict(teacher): + return { + "person_id": teacher.person_id, + "name": teacher.name, + "gender": format_enum(teacher.gender), + "in_school_since": format_date(teacher.in_school_since), + "account_type": format_enum(teacher.account_type), + "classroom_name": teacher.classroom_name, + "teacher_to": format_date(teacher.teacher_to), + } - if teacher.in_school_since > youngest_teacher.in_school_since: - youngest_teacher = teacher -print("\n\nThe youngest teacher in your school (the shortest time in your school):") -print_teacher_info(youngest_teacher) +json_data = [teacher_to_dict(teacher) for teacher in teachers or []] +print(json.dumps(json_data, ensure_ascii=False, indent=2)) diff --git a/examples/timetables.py b/examples/timetables.py index fd4b45a..4ad164a 100644 --- a/examples/timetables.py +++ b/examples/timetables.py @@ -1,32 +1,51 @@ import datetime +import json from edupage_api import Edupage edupage = Edupage() -edupage.login_auto("Username (or e-mail)", "Password") - -# My timetable -date = datetime.date(2024, 6, 12) -timetable = edupage.get_my_timetable(date) - -print(f"My timetable from {date}:") - -for lesson in timetable: - print(f"[{lesson.period}] {lesson.subject.name} ({lesson.teachers[0].name})") - -print() - - -# Someone else's timetable -classrooms = edupage.get_classrooms() - -# for i, classroom in enumerate(classrooms): -# print(i, classroom.name) - -classroom = classrooms[0] -date = datetime.date(2024, 6, 12) -timetable = edupage.get_timetable(classroom, date) -print(f"Timetable from {date} for classroom '{classroom.name}':") - -for lesson in timetable: - print(f"[{lesson.period}] {lesson.subject.name} ({lesson.teachers[0].name})") +edupage.login( + "#EMAIL_ADDRESS#", + "#PASSWORD#", + "#SCHOOL_EDUPAGE_SUBDOMAIN#", # SUBDOMAIN.edupage.org +) + +student_name = "#STUDENT_NAME#" # e.g. "Alžbeta Výborná" + +def names(items): + if not items: + return [] + return [item.name for item in items if item is not None] + + +def lesson_to_dict(lesson): + return { + "period": lesson.period, + "start": lesson.start_time.strftime("%H:%M") if lesson.start_time else None, + "end": lesson.end_time.strftime("%H:%M") if lesson.end_time else None, + "duration": lesson.duration, + "subject": lesson.subject.name if lesson.subject else None, + "teachers": names(lesson.teachers), + "classrooms": names(lesson.classrooms), + "classes": names(lesson.classes), + "groups": lesson.groups or [], + "curriculum": lesson.curriculum, + "is_cancelled": lesson.is_cancelled, + "is_event": lesson.is_event, + } + + +date = datetime.date.today() +students = edupage.get_students() or [] +student = next((student for student in students if student.name == student_name), None) + +if student is None: + available_students = [student.name for student in students] + raise RuntimeError( + f"Student {student_name!r} was not found. Available students: {available_students}" + ) + +timetable = edupage.get_timetable(student, date) + +json_data = [lesson_to_dict(lesson) for lesson in timetable] +print(json.dumps(json_data, ensure_ascii=False))