from json import JSONDecodeError, loads
from typing import Optional
from pydantic import BaseModel, Field, field_validator
from .api.enums import ProgramCode, ShiftTime, Weekday
[docs]
class UpdateInfo(BaseModel):
"""
Represents a single update metadata of a routine.
"""
id: str
routine: str
semester: str
semseter_code: str = Field(alias="semseterCode")
hash: str
minor_change: str = Field(alias="minorChange")
major_change: str = Field(alias="majorChange")
updated_at: str
created_at: str
[docs]
class ClassPeriod(BaseModel):
"""
Represents a single class period in Class routine.
"""
week_day: Weekday = Field(alias="classDay")
period_time: str = Field(alias="timeSlotLabel", examples=["12:00 PM to 01:30 PM"])
intake: str = Field(alias="studentIntake", examples=["48", "49", "50"])
section: str = Field(alias="studentSection", examples=["1", "2", "3"])
faculty_code: str = Field(alias="teacherShortCode")
faculty_name: Optional[str] = Field(
alias="teacherFullName", exclude=True, default=None
)
building: str = Field(alias="buildingId", examples=["1", "2", "3", "4"])
room: str = Field(alias="roomNo")
course_code: str = Field(alias="courseNo", examples=["CSE 101", "CSE 201"])
course_name: Optional[str] = Field(alias="courseName", exclude=True, default=None)
shift_time: ShiftTime = Field(alias="shiftTime")
[docs]
class FacultyPeriod(BaseModel):
"""
Represents a single class period in Faculty routine.
"""
week_day: Weekday = Field(alias="dayName")
period_time: str = Field(alias="timeSlotLabel", examples=["12:00 PM to 01:30 PM"])
intake: str = Field(alias="intake", examples=["48", "49", "50"])
section: str = Field(alias="section", examples=["1", "2", "3"])
building: str = Field(alias="buildingId", examples=["1", "2", "3", "4"])
room: str = Field(alias="roomNumber")
course_code: str = Field(alias="courseNumber", examples=["CSE 101", "CSE 201"])
shift_time: ShiftTime = Field(alias="shiftName")
[docs]
class TermExam(BaseModel):
"""
Represents a single exam period in Exam routine.
"""
program_code: ProgramCode = Field(alias="program_code")
course_code: str = Field(alias="course_code", examples=["CSE 101", "CSE 201"])
intake: str = Field(alias="student_intake", examples=["48", "49", "50"])
section: str = Field(alias="student_section", examples=["1", "2", "3"])
faculty_code: str = Field(alias="course_faculty", examples=["AQO", "MDI", "MMRH"])
building: str = Field(alias="building", examples=["1", "2", "3", "4"])
room: str = Field(alias="room_number", examples=['["906"]'])
total_students: Optional[str] = None
exam_date: str = Field(alias="e_date", examples=["2025-03-12 00:00:00"])
period_time: str = Field(alias="slot_label", examples=["12:00 PM to 01:30 PM"])
# Why? Because for some *good* reason developer thought of sending
# room number as an array of str e.g, '["801"]' ¯\_(ツ)_/¯
[docs]
@field_validator("room")
def parse_room(cls, value):
try:
return loads(value)[0]
except (JSONDecodeError, IndexError, TypeError):
return value
[docs]
@field_validator("exam_date")
def parse_exam_date(cls, value):
try:
return value.split()[0]
except (JSONDecodeError, IndexError):
return value