class GradeColumn(Serializable): """A grade column. Represents a topic which a student may get a grade from (e.g. a single exam, short test, homework). :var int ~.id: grade column's ID :var str ~.key: grade column's key (UUID) :var int ~.period_id: ID of the period when the grade is given :var str ~.name: grade column's name (description) :var str ~.code: grade column's code (e.g. short name or abbreviation) :var str ~.group: unknown, yet :var int ~.number: unknown, yet :var int ~.weight: weight of this column's grades :var `~vulcan.hebe.model.Subject` ~.subject: the subject from which grades in this column are given :var `~vulcan.hebe.data.GradeCategory` ~.category: category (base type) of grades in this column :var `~vulcan.hebe.model.Period` ~.period: a resolved period of this grade """ id: int = IntegerField(key="Id") key: str = StringField(key="Key") period_id: int = IntegerField(key="PeriodId") name: str = StringField(key="Name") code: str = StringField(key="Code") group: str = StringField(key="Group") number: int = IntegerField(key="Number") weight: float = FloatField(key="Weight") subject: Subject = ChildField(Subject, key="Subject") category: GradeCategory = ChildField(GradeCategory, key="Category") period: Period = ChildField(Period, key="Period", required=False)
class Notice: """Positive, negative or neutral student notice :var int ~.id: Notice ID :var str ~.content: Content of the notice :var `datetime.date` ~.date: Notice added date :var `~vulcan._notice.NoticeType` ~.type: Notice type class :var `~vulcan._teacher.Teacher` ~.teacher: Teacher, who added the notice """ id = IntegerField(key="Id") content = StringField(key="TrescUwagi") date = DateField(key="DataWpisuTekst") type = ChildField(NoticeType, required=False) teacher = ChildField(Teacher, required=False) @classmethod def get(cls, api): j = api.post("Uczen/UwagiUcznia") notices = sorted(j.get("Data", []), key=itemgetter("DataWpisu")) for notice in notices: notice["type"] = api.dict.get_notice_category_json( notice["IdKategoriaUwag"]) notice["teacher"] = api.dict.get_teacher_json( notice["IdPracownik"]) yield to_model(cls, notice)
class Grade(Serializable): """A grade. :var int ~.id: grade's ID :var str ~.key: grade's key (UUID) :var int ~.pupil_id: the related pupil's ID :var str ~.content_raw: grade's content (with comment) :var str ~.content: grade's content (without comment) :var `~vulcan.model.DateTime` ~.date_created: grade's creation date :var `~vulcan.model.DateTime` ~.date_modified: grade's modification date (may be the same as ``date_created`` if it was never modified) :var `~vulcan.model.Teacher` ~.teacher_created: the teacher who added the grade :var `~vulcan.model.Teacher` ~.teacher_modified: the teacher who modified the grade :var `~vulcan.data.GradeColumn` ~.column: grade's column :var float ~.value: grade's value, may be `None` if 0.0 :var str ~.comment: grade's comment, visible in parentheses in ``content_raw`` :var float ~.numerator: for point grades: the numerator value :var float ~.denominator: for point grades: the denominator value """ id: int = IntegerField(key="Id") key: str = StringField(key="Key") pupil_id: int = IntegerField(key="PupilId") content_raw: str = StringField(key="ContentRaw") content: str = StringField(key="Content") date_created: DateTime = ChildField(DateTime, key="DateCreated") date_modified: DateTime = ChildField(DateTime, key="DateModify") teacher_created: Teacher = ChildField(Teacher, key="Creator") teacher_modified: Teacher = ChildField(Teacher, key="Modifier") column: GradeColumn = ChildField(GradeColumn, key="Column") value: float = FloatField(key="Value", required=False) comment: str = StringField(key="Comment", required=False) numerator: float = FloatField(key="Numerator", required=False) denominator: float = FloatField(key="Denominator", required=False) @classmethod async def get( cls, api, last_sync, deleted, **kwargs ) -> Union[AsyncIterator["Grade"], List[int]]: """ :rtype: Union[AsyncIterator[:class:`~vulcan.data.Grade`], List[int]] """ data = await api.helper.get_list( DATA_GRADE, FilterType.BY_PUPIL, deleted=deleted, last_sync=last_sync, **kwargs ) for grade in data: grade["Column"]["Period"] = api.student.period_by_id( grade["Column"]["PeriodId"] ).as_dict yield Grade.load(grade)
class Student: """Student :var int ~.id: Student ID :var int ~.login_id: ID of the logged user :var str ~.account_name: Student account name :var str ~.first_name: Student first name :var str ~.second_name: Student second name, optional :var str ~.last_name: Student last name (surname) :var `~vulcan._student.Gender` ~.gender: Student gender :var str ~.nickname: Student nickname :var `~vulcan._period.Period` ~.period: Current student class period :var `~vulcan._class.Class` ~.class_: Student class :var `~vulcan._school.School` ~.school: Student school """ id = IntegerField(key="Id") login_id = IntegerField(key="UzytkownikLoginId") account_name = StringField(key="UzytkownikNazwa") first_name = StringField(key="Imie") last_name = StringField(key="Nazwisko") gender = ChildField(Gender, key="UczenPlec") second_name = StringField(key="Imie2", required=False) nickname = StringField(key="Pseudonim", required=False) period = ChildField(Period, required=False) class_ = ChildField(Class, required=False) school = ChildField(School, required=False) @property def name(self): """Returns the student's full name as "Name SecondName Surname". :rtype: str """ first = "{} {}".format(self.first_name, self.second_name).rstrip() return "{} {}".format(first, self.last_name) @staticmethod def format_json(json): json["period"] = Period.only_keys(json) json["class_"] = Class.only_keys(json) json["school"] = School.only_keys(json) return json @classmethod def get(cls, api): j = api.post(api.base_url + "UczenStart/ListaUczniow") for student in j.get("Data", []): yield to_model(cls, cls.format_json(student))
class Lesson(Serializable): """A lesson. :var int ~.id: lesson's ID :var `~vulcan.hebe.model.DateTime` ~.date: lesson's date :var `~vulcan.hebe.model.TimeSlot` ~.time: lesson's time :var `~vulcan.hebe.data.LessonRoom` ~.room: classroom, in which is the lesson :var `~vulcan.hebe.model.Teacher` ~.teacher: teacher of the lesson :var `~vulcan.hebe.model.Teacher` ~.second_teacher: second teacher of the lesson :var `~vulcan.hebe.model.Subject` ~.subject: subject on the lesson :var str ~.event: an event happening during this lesson :var str ~.changes: lesson changes :var `~vulcan.hebe.model.TeamClass` ~.team_class: the class that has the lesson :var str ~.pupil_alias: pupil alias :var `~vulcan.hebe.model.TeamVirtual` ~.group: group, that has the lesson :var bool ~.visible: lesson visibility (whether the timetable applies to the given student) """ id: int = IntegerField(key="Id", required=False) date: DateTime = ChildField(DateTime, key="Date", required=False) time: TimeSlot = ChildField(TimeSlot, key="TimeSlot", required=False) room: LessonRoom = ChildField(LessonRoom, key="Room", required=False) teacher: Teacher = ChildField(Teacher, key="TeacherPrimary", required=False) second_teacher: Teacher = ChildField( Teacher, key="TeacherSecondary", required=False ) subject: Subject = ChildField(Subject, key="Subject", required=False) event: str = StringField(key="Event", required=False) changes: str = StringField(key="Change", required=False) team_class: TeamClass = ChildField(TeamClass, key="Clazz", required=False) pupil_alias: str = StringField(key="PupilAlias", required=False) group: TeamVirtual = ChildField(TeamVirtual, key="Distribution", required=False) visible = BooleanField(key="Visible", required=False) @classmethod async def get( cls, api, last_sync, deleted, date_from, date_to, **kwargs ) -> Union[AsyncIterator["Lesson"], List[int]]: """ :rtype: Union[AsyncIterator[:class:`~vulcan.hebe.data.Lesson`], List[int]] """ if date_from == None: date_from = datetime.date.today() if date_to == None: date_to = date_from date_to = date_to + datetime.timedelta( days=1 ) # Vulcan requires the date_to to be one greater the date it is supposed to be data = await api.helper.get_list( DATA_TIMETABLE, FilterType.BY_PUPIL, deleted=deleted, date_from=date_from, date_to=date_to, last_sync=last_sync, **kwargs ) for lesson in data: yield Lesson.load(lesson)
class Attendance: """Attendance :var `datetime.date` ~.date: Attendance date :var `~vulcan._subject.Subject` ~.subject: Subject of the lesson :var `~vulcan._attendance.AttendanceCategory` ~.category: Information about Attendance category :var `~vulcan._lesson.LessonTime` ~.time: Information about the lesson time """ date = DateField(key="DzienTekst") subject = ChildField(Subject, required=False) category = ChildField(AttendanceCategory, required=False) time = ChildField(LessonTime, required=False) @classmethod def get(cls, api, date_from, date_to): if not date_from: date_from = datetime.date.today() if not date_to: date_to = date_from data = { "DataPoczatkowa": date_from.strftime("%Y-%m-%d"), "DataKoncowa": date_to.strftime("%Y-%m-%d"), } j = api.post("Uczen/Frekwencje", json=data) attendances = sort_and_filter_dates( j.get("Data", {}).get("Frekwencje", []), date_from, date_to, sort_key="Numer", date_key="DzienTekst", ) for attendance in attendances: attendance["subject"] = api.dict.get_subject_json( attendance["IdPrzedmiot"]) attendance["category"] = api.dict.get_attendance_category_json( attendance["IdKategoria"]) attendance["time"] = api.dict.get_lesson_time_json( attendance["IdPoraLekcji"]) yield to_model(cls, attendance)
class Period(Serializable): """A school year period. :var int ~.id: the period ID :var int ~.level: a grade/level number :var int ~.number: number of the period in the school year :var bool ~.current: whether the period is currently ongoing :var bool ~.last: whether the period is last in the school year :var `~vulcan.model.DateTime` ~.start: the period start datetime :var `~vulcan.model.DateTime` ~.end: the period end datetime """ id: int = IntegerField(key="Id") level: int = IntegerField(key="Level") number: int = IntegerField(key="Number") current: bool = BooleanField(key="Current") last: bool = BooleanField(key="Last") start: DateTime = ChildField(DateTime, key="Start") end: DateTime = ChildField(DateTime, key="End")
class Homework: """Homework :var int ~.id: Homework ID :var str ~.description: Homework description :var `datetime.date` ~.date: Homework deadline date :var `~vulcan._teacher.Teacher` ~.teacher: Teacher, who added the homework :var `~vulcan._subject.Subject` ~.subject: Subject, from which is the homework """ id = IntegerField(key="Id") description = StringField(key="Opis") date = DateField(key="DataTekst") teacher = ChildField(Teacher, required=False) subject = ChildField(Subject, required=False) @classmethod def get(cls, api, date_from, date_to): if not date_from: date_from = datetime.date.today() if not date_to: date_to = date_from data = { "DataPoczatkowa": date_from.strftime("%Y-%m-%d"), "DataKoncowa": date_to.strftime("%Y-%m-%d"), } j = api.post("Uczen/ZadaniaDomowe", json=data) homework_list = sort_and_filter_dates(j.get("Data", []), date_from, date_to) for homework in homework_list: homework["teacher"] = api.dict.get_teacher_json( homework["IdPracownik"]) homework["subject"] = api.dict.get_subject_json( homework["IdPrzedmiot"]) yield to_model(cls, homework)
class Exam: """Exam, test, short test or class test :var int ~.id: Exam ID :var `~vulcan._exam.ExamType` ~.type: Exam type :var str ~.description: Exam description :var `datetime.date` ~.date: Exam date :var `~vulcan._teacher.Teacher` ~.teacher: Teacher, who added the exam :var `~vulcan._subject.Subject` ~.subject: Subject, from which is the exam """ id = IntegerField(key="Id") type = ChildField(ExamType, key="RodzajNumer") description = StringField(key="Opis") date = DateField(key="DataTekst") teacher = ChildField(Teacher, required=False) subject = ChildField(Subject, required=False) @classmethod def get(cls, api, date_from, date_to): if not date_from: date_from = datetime.date.today() if not date_to: date_to = date_from data = { "DataPoczatkowa": date_from.strftime("%Y-%m-%d"), "DataKoncowa": date_to.strftime("%Y-%m-%d"), } j = api.post("Uczen/Sprawdziany", json=data) exams = sort_and_filter_dates(j.get("Data", []), date_from, date_to) for exam in exams: exam["teacher"] = api.dict.get_teacher_json(exam["IdPracownik"]) exam["subject"] = api.dict.get_subject_json(exam["IdPrzedmiot"]) yield to_model(cls, exam)
class Grade: """Grade :var int ~.id: Grade ID :var str ~.content: Grade content :var float ~.weight: Grade weight :var str ~.description: Grade description :var `datetime.datetime` ~.date: Grade creation date :var `datetime.datetime` ~.last_modification_date: Last grade modification date :var float ~.value: Grade value (you can use it to calculate the average) :var `~vulcan._teacher.Teacher` ~.teacher: Teacher, who added the grade :var `~vulcan._subject.Subject` ~.subject: Subject, from which student received the grade :var `~vulcan._grade.GradeCategory` ~.category: Grade category """ id = IntegerField(key="Id") content = StringField(key="Wpis") weight = FloatField(key="WagaOceny") description = StringField(key="Opis") date = DateTimeField(key="DataUtworzeniaTekst") last_modification_date = DateTimeField(key="DataModyfikacjiTekst") value = FloatField(key="Wartosc", required=False) teacher = ChildField(Teacher, required=False) subject = ChildField(Subject, required=False) category = ChildField(GradeCategory, required=False) @classmethod def get(cls, api): j = api.post("Uczen/Oceny") for grade in j.get("Data", []): grade["teacher"] = api.dict.get_teacher_json(grade["IdPracownikD"]) grade["subject"] = api.dict.get_subject_json(grade["IdPrzedmiot"]) grade["category"] = api.dict.get_grade_category_json( grade["IdKategoria"]) yield to_model(cls, grade)
class Exam(Serializable): """An exam or short quiz. :var int ~.id: exam's ID :var str ~.key: exam's key (UUID) :var str ~.type: exam's type :var str ~.topic: exam's topic :var `~vulcan.hebe.model.DateTime` ~.date_created: exam's creation date :var `~vulcan.hebe.model.DateTime` ~.date_modified: exam's modification date (may be the same as ``date_created`` if it was never modified) :var `~vulcan.hebe.model.DateTime` ~.deadline: exam's date and time :var `~vulcan.hebe.model.Teacher` ~.creator: the teacher who added the exam :var `~vulcan.hebe.model.Subject` ~.subject: the exam's subject :var `~vulcan.hebe.model.TeamClass` ~.team_class: the class taking the exam :var `~vulcan.hebe.model.TeamVirtual` ~.team_virtual: the class distribution taking the exam, optional """ id: int = IntegerField(key="Id") key: str = StringField(key="Key") type: str = StringField(key="Type") topic: str = StringField(key="Content") date_created: DateTime = ChildField(DateTime, key="DateCreated") date_modified: DateTime = ChildField(DateTime, key="DateModify") deadline: DateTime = ChildField(DateTime, key="Deadline") creator: Teacher = ChildField(Teacher, key="Creator") subject: Subject = ChildField(Subject, key="Subject") team_class: TeamClass = ChildField(TeamClass, key="Class") team_virtual: TeamVirtual = ChildField( TeamVirtual, key="Distribution", required=False ) @classmethod async def get( cls, api, last_sync, deleted, **kwargs ) -> Union[AsyncIterator["Exam"], List[int]]: """ :rtype: Union[AsyncIterator[:class:`~vulcan.hebe.data.Exam`], List[int]] """ data = await api.helper.get_list( DATA_EXAM, FilterType.BY_PUPIL, deleted=deleted, last_sync=last_sync, **kwargs ) for exam in data: yield Exam.load(exam)
class Homework(Serializable): """A homework. :var int ~.id: homework's external ID :var str ~.key: homework's key (UUID) :var int ~.homework_id: homework's internal ID :var str ~.content: homework's content :var `~vulcan.hebe.model.DateTime` ~.date_created: homework's creation date :var `~vulcan.hebe.model.Teacher` ~.creator: the teacher who added the homework :var `~vulcan.hebe.model.Subject` ~.subject: the homework's subject :var List[Attachment] ~.attachments: attachments added to homework :var bool ~.is_answer_required: Is an answer required :var `~vulcan.hebe.model.DateTime` ~.deadline: homework's date and time :var `~vulcan.hebe.model.DateTime` ~.answer_deadline: homework's answer deadline :var `~vulcan.hebe.model.DateTime` ~.answer_date: homework's answer date and time """ id: int = IntegerField(key="Id") key: str = StringField(key="Key") homework_id: int = StringField(key="IdHomework") content: str = StringField(key="Content") date_created: DateTime = ChildField(DateTime, key="DateCreated") creator: Teacher = ChildField(Teacher, key="Creator") subject: Subject = ChildField(Subject, key="Subject") attachments: List[Attachment] = SequenceField(Attachment, key="Attachments", repr=True) is_answer_required: Subject = BooleanField(key="IsAnswerRequired") deadline: DateTime = ChildField(DateTime, key="Deadline") answer_deadline: DateTime = ChildField(DateTime, key="AnswerDeadline", required=False) answer_date: DateTime = ChildField(DateTime, key="AnswerDate", required=False) @classmethod async def get(cls, api, last_sync, deleted, **kwargs) -> Union[AsyncIterator["Homework"], List[int]]: """ :rtype: Union[AsyncIterator[:class:`~vulcan.hebe.data.Homework`], List[int]] """ data = await api.helper.get_list(DATA_HOMEWORK, FilterType.BY_PUPIL, deleted=deleted, last_sync=last_sync, **kwargs) for homework in data: yield Homework.load(homework)
class Pupil(Serializable): """A class containing the student's data. :var int ~.id: pupil's ID :var int ~.login_id: pupil's account login ID :var str ~.login_value: pupil's account login name (email/username) :var str ~.first_name: student's first name :var str ~.second_name: student's second name, optional :var str ~.last_name: student's last name / surname :var `~vulcan.model.Gender` ~.gender: student's gender """ id: int = IntegerField(key="Id") login_id: int = IntegerField(key="LoginId") first_name: str = StringField(key="FirstName") last_name: str = StringField(key="Surname") gender: Gender = ChildField(Gender, key="Sex") second_name: str = StringField(key="SecondName", required=False) login_value: str = StringField(key="LoginValue", required=False)
class Student(Serializable): """A student object, along with his school, class and period information :var str ~.symbol: the "partition" symbol - can be a town or county name :var str ~.symbol_code: the school unit code - often a 6 digit number :var `~vulcan.hebe.model.Pupil` ~.pupil: contains the student's IDs, names and email :var `~vulcan.hebe.model.Unit` ~.unit: info about the school unit (e.g. several school buildings) :var `~vulcan.hebe.model.School` ~.school: info about the school (a single building of the unit) :var List[`~vulcan.hebe.model.Period`] ~.periods: a list of the student's school year periods """ symbol: str = StringField(key="TopLevelPartition") symbol_code: str = StringField(key="Partition") pupil: Pupil = ChildField(Pupil, key="Pupil") unit: Unit = ChildField(Unit, key="Unit") school: School = ChildField(School, key="ConstituentUnit") periods: List[Period] = SequenceField(Period, key="Periods") @property def full_name(self) -> str: """Gets the student's full name in "FirstName SecondName LastName" format. :rtype: str """ return " ".join(part for part in [ self.pupil.first_name.strip(), self.pupil.second_name.strip(), self.pupil.last_name.strip(), ] if part) @property def current_period(self) -> Period: """Gets the currently ongoing period of the student. :rtype: :class:`~vulcan.hebe.model.Period` """ return next((period for period in self.periods if period.current), None) def period_by_id(self, period_id: int) -> Period: """Gets a period matching the given period ID. :param int period_id: the period ID to look for :rtype: :class:`~vulcan.hebe.model.Period` """ return next( (period for period in self.periods if period.id == period_id), None) @classmethod async def get(cls, api, **kwargs) -> List["Student"]: """ :rtype: List[:class:`~vulcan.hebe.model.Student`] """ data = await api.get(STUDENT_LIST, **kwargs) return list(Student.load(student) for student in data)
class Document: title = StringField(required=True) version = StringField(required=False) date = DateField(required=False) reference = StringField(required=False) custodian = ChildField(Agent, required=False) preparations = SequenceField(Action, required=False) contributions = SequenceField(Action, required=False) approbations = SequenceField(Action, required=False) issues = SequenceField(Issue, required=False) applicable_documents = SequenceField(LinkedDocument, required=False) reference_documents = SequenceField(LinkedDocument, required=False) title_template = StringField(default="Document about {name}", required=False) def configure_from_project(self, project): self.title = self.title_template.format(name=project.name) @staticmethod def sample(): d = Document("document title") d.version = "1.0" d.reference = "REC-FOO-A" d.custodian = "mister.custodian" d.preparations.append( Action(name='John Doe', role='Leader', description='Preparation of review', date='2019-01-01')) d.contributions = [ Action(name='John Doe', role='Leader', description='Preparation of review', date='2019-01-01'), Action(name='John Doe', role='Leader', description='Preparation of review', date='2019-01-01'), Action(name='John Doe', role='Leader', description='Preparation of review', date='2019-01-01') ] d.approbations.append( Action(name='John Doe', role='Leader', description='Preparation of review', date='2019-01-01')) d.issues = [ Issue( id='0.1', date='2018-11-01', page=["2"], description='Typo', comment= 'file to view the source code until proper documentation is generated.' ), Issue(id='0.2', date='2018-11-01', page=["2"], description='Typo very long', comment='balbalbalbalbalb'), Issue(id='0.3', date='2018-11-01', page=["2", "3"], description='Typo', comment='datetime field formatted using formatter.'), Issue(id='0.4', date='2018-11-01', page=["2"], description='Typo', comment='balbalbalbalbalb'), Issue( id='0.5', date='2018-11-01', page=["2"], description='Typo', comment='Adding your own field types is fairly straightforward ' ), ] return d
class Attendance(Serializable): """Attendance. :var int ~.lesson_id: lesson ID :var int ~.id: attendance ID :var int ~.lesson_number: lesson number :var str ~.global_key: attendance global key :var int ~.lesson_class_id: lesson class ID :var str ~.global_key: lesson class global key :var bool ~.calculate_presence: does it count for absences :var bool ~.replacement: os it replaced :var `~vulcan.hebe.model.Subject` ~.subject: subject of the lesson :var str ~.topic: topic of the lesson :var `~vulcan.hebe.model.Teacher` ~.teacher: teacher of the lesson :var `~vulcan.hebe.model.Teacher` ~.second_teacher: second teacher of the lesson :var `~vulcan.hebe.model.Teacher` ~.main_teacher: pupil main teacher :var `~vulcan.hebe.model.TeamClass` ~.team_class: the class that had lesson :var str ~.class_alias: class short name :var `~vulcan.hebe.model.DateTime` ~.date: lesson's date :var `~vulcan.hebe.model.TimeSlot` ~.time: lesson's time :var `~vulcan.hebe.model.DateTime` ~.date_modified: attendance modification date, if not modified it is created date :var int ~.id: aux presence ID :var str ~.justification_status: attendance justification status :var `~vulcan.hebe.data.PresenceType` ~.presence_type: presence type :var str ~.note: attendance note :var str ~.public_resources: attendance public resources :var str ~.remote_resources: attendance remote resources :var `~vulcan.hebe.model.TeamVirtual` ~.group: group, that has the lesson :var bool ~.visible: attendance visibility """ lesson_id: int = IntegerField(key="LessonId") id: int = IntegerField(key="Id") lesson_number: int = IntegerField(key="LessonNumber") global_key: str = StringField(key="GlobalKey") lesson_class_id: int = IntegerField(key="LessonClassId") lesson_class_global_key: str = StringField(key="LessonClassGlobalKey") calculate_presence: bool = BooleanField(key="CalculatePresence") replacement: bool = BooleanField(key="Replacement") subject: Subject = ChildField(Subject, key="Subject", required=False) topic: str = StringField(key="Topic", required=False) teacher: Teacher = ChildField(Teacher, key="TeacherPrimary", required=False) second_teacher: Teacher = ChildField(Teacher, key="TeacherSecondary", required=False) main_teacher: Teacher = ChildField(Teacher, key="TeacherMod", required=False) team_class: TeamClass = ChildField(TeamClass, key="Clazz", required=False) class_alias: str = StringField(key="GroupDefinition", required=False) date: DateTime = ChildField(DateTime, key="Day", required=False) time: TimeSlot = ChildField(TimeSlot, key="TimeSlot", required=False) date_modified: DateTime = ChildField(DateTime, key="DateModify", required=False) aux_presence_id: int = IntegerField(key="AuxPresenceId", required=False) justification_status: str = StringField(key="JustificationStatus", required=False) presence_type: PresenceType = ChildField(PresenceType, key="PresenceType", required=False) note: str = StringField(key="Note", required=False) public_resources: str = StringField(key="PublicResources", required=False) remote_resources: str = StringField(key="RemoteResources", required=False) group: TeamVirtual = ChildField(TeamVirtual, key="Distribution", required=False) visible = BooleanField(key="Visible", required=False) @classmethod async def get(cls, api, last_sync, deleted, date_from, date_to, **kwargs) -> Union[AsyncIterator["Attendance"], List[int]]: """ :rtype: Union[AsyncIterator[:class:`~vulcan.hebe.data.Attendance`], List[int]] """ if date_from == None: date_from = datetime.date.today() if date_to == None: date_to = date_from date_to = date_to + datetime.timedelta( days=1 ) # Vulcan requires the date_to to be one greater the date it is supposed to be data = await api.helper.get_list(DATA_ATTENDANCE, FilterType.BY_PUPIL, deleted=deleted, date_from=date_from, date_to=date_to, last_sync=last_sync, **kwargs) for attendance in data: yield Attendance.load(attendance)
class Message: """Message :var int ~.id: Message ID :var int ~.sender_id: Message sender's (teacher) ID :var list ~.recipients: A list of :class:`vulcan._message.MessageRecipient` objects :var str ~.title: Title (subject) of the message :var str ~.content: Message content :var `~vulcan._teacher.Teacher` ~.sender: Sender of the message (teacher) :var `datetime.datetime` ~.sent_datetime: Date with time when the message was sent :var `datetime.date` ~.sent_date: Date when the message was sent :var `datetime.time` ~.sent_time: Time when the message was sent :var `datetime.datetime` ~.read_datetime: Date with time when the message was read, optional :var `datetime.date` ~.read_date: Date when the message was read, optional :var `datetime.time` ~.read_time: Time when the message was read, optional :var bool ~.is_read: Whether the message is read """ id = IntegerField(key="WiadomoscId") sender_id = IntegerField(key="NadawcaId") recipients = SequenceField(MessageRecipient, key="Adresaci") title = StringField(key="Tytul") content = StringField(key="Tresc") sent_date = DateField(key="DataWyslania", formatter="%d.%m.%Y") sent_time = TimeField(key="GodzinaWyslania", formatter="%H:%M") read_date = DateField(key="DataPrzeczytania", formatter="%d.%m.%Y", required=False) read_time = TimeField(key="GodzinaPrzeczytania", formatter="%H:%M", required=False) sender = ChildField(Teacher, required=False) @property def sent_datetime(self): return datetime.combine(self.sent_date, self.sent_time) @property def read_datetime(self): if self.read_date and self.read_time: return datetime.combine(self.read_date, self.read_time) return None @property def is_read(self): return self.read_date is not None @classmethod def get(cls, api, date_from=None, date_to=None): if not date_from: date_from = api.student.period.from_ if not date_to: date_to = api.student.period.to data = { "DataPoczatkowa": date_from.strftime("%Y-%m-%d"), "DataKoncowa": date_to.strftime("%Y-%m-%d"), } j = api.post("Uczen/WiadomosciOdebrane", json=data) messages = j.get("Data", []) for message in messages: message["sender"] = api.dict.get_teacher_by_login_id_json( message["NadawcaId"] ) yield to_model(cls, message) @classmethod def send(cls, api, title, content, teachers): recipients = list() for teacher_repr in teachers: if isinstance(teacher_repr, int) or ( isinstance(teacher_repr, str) and teacher_repr.isnumeric() ): teacher = to_model( Teacher, api.dict.get_teacher_json(int(teacher_repr)) ) elif isinstance(teacher_repr, str): teacher = to_model( Teacher, api.dict.get_teacher_by_name_json(teacher_repr) ) elif isinstance(teacher_repr, dict): teacher = to_model(Teacher, teacher_repr) elif isinstance(teacher_repr, Teacher): teacher = teacher_repr else: continue recipients.append( { "LoginId": teacher.login_id, "Nazwa": teacher.name_reversed, } ) if len(recipients) == 0: raise ValueError("There must be at least 1 correct recipient.") data = { "NadawcaWiadomosci": api.student.account_name, "Tytul": title, "Tresc": content, "Adresaci": recipients, } log.info("Sending a message...") j = api.post("Uczen/DodajWiadomosc", json=data) log.info("Message sent successfully!") return j.get("Data", {}).get("WiadomoscId")
class Lesson: """Lesson :var int ~.number: Lesson number :var str ~.room: Classroom, in which is the lesson :var str ~.group: Group, that has the lesson :var `datetime.date` ~.date: Lesson date :var str ~.changes: Lesson changes :var bool ~.visible: Lesson visibility (whether the timetable applies to the given student) :var `datetime.datetime` ~.from_: Lesson start date and time :var `datetime.datetime` ~.to: Lesson end date and time :var `~vulcan._lesson.LessonTime` ~.time: Information about the lesson time :var `~vulcan._teacher.Teacher` ~.teacher: Teacher of the lesson :var `~vulcan._subject.Subject` ~.subject: Subject on the lesson """ number = IntegerField(key="NumerLekcji") room = StringField(key="Sala", required=False) group = StringField(key="PodzialSkrot", required=False) date = DateField(key="DzienTekst", required=False) changes = StringField(key="AdnotacjaOZmianie", required=False) visible = BooleanField(key="PlanUcznia", required=False) time = ChildField(LessonTime, required=False) teacher = ChildField(Teacher, required=False) subject = ChildField(Subject, required=False) # pylint: disable=E1101 @property def from_(self): return datetime.datetime.combine(self.date, self.time.from_) # pylint: disable=E1101 @property def to(self): return datetime.datetime.combine(self.date, self.time.to) @classmethod def get(cls, api, date_from, date_to): if not date_from: date_from = datetime.date.today() if not date_to: date_to = date_from data = { "DataPoczatkowa": date_from.strftime("%Y-%m-%d"), "DataKoncowa": date_to.strftime("%Y-%m-%d"), } j = api.post("Uczen/PlanLekcjiZeZmianami", json=data) lessons = sort_and_filter_dates( j.get("Data", []), date_from, date_to, sort_key="NumerLekcji", date_key="DzienTekst", ) for lesson in lessons: lesson["time"] = api.dict.get_lesson_time_json(lesson["IdPoraLekcji"]) lesson["teacher"] = api.dict.get_teacher_json(lesson["IdPracownik"]) lesson["subject"] = api.dict.get_subject_json(lesson["IdPrzedmiot"]) yield to_model(cls, lesson)
class ChangedLesson(Serializable): """Changed lesson. :var int ~.id: changed lesson's ID :var int ~.unit_id: unit ID :var int ~.schedule_id: normal lesson's ID :var `~vulcan.model.DateTime` ~.lesson_date: lesson's date :var `~vulcan.model.DateTime` ~.change_date: change date :var `~vulcan.model.TimeSlot` ~.time: lesson's time :var str ~.note: change note :var str ~.reason: change reason :var `~vulcan.data.LessonRoom` ~.room: classroom, in which is the lesson :var `~vulcan.model.Teacher` ~.teacher: teacher of the lesson :var `~vulcan.model.Teacher` ~.second_teacher: second teacher of the lesson :var `~vulcan.model.Subject` ~.subject: subject on the lesson :var str ~.event: an event happening during this lesson :var `~vulcan.data.LessonChanges` ~.changes: lesson changes :var `~vulcan.model.TeamClass` ~.team_class: the class that has the lesson :var `~vulcan.model.TeamVirtual` ~.group: group, that has the lesson """ id: int = IntegerField(key="Id", required=False) unit_id: int = IntegerField(key="UnitId", required=False) schedule_id: int = IntegerField(key="'ScheduleId': ", required=False) lesson_date: DateTime = ChildField(DateTime, key="LessonDate", required=False) note: str = StringField(key="Note", required=False) reason: str = StringField(key="Reason", required=False) time: TimeSlot = ChildField(TimeSlot, key="TimeSlot", required=False) room: LessonRoom = ChildField(LessonRoom, key="Room", required=False) teacher: Teacher = ChildField(Teacher, key="TeacherPrimary", required=False) second_teacher: Teacher = ChildField(Teacher, key="TeacherSecondary", required=False) subject: Subject = ChildField(Subject, key="Subject", required=False) event: str = StringField(key="Event", required=False) changes: LessonChanges = ChildField(LessonChanges, key="Change", required=False) change_date: DateTime = ChildField(DateTime, key="ChangeDate", required=False) team_class: TeamClass = ChildField(TeamClass, key="Clazz", required=False) group: TeamVirtual = ChildField(TeamVirtual, key="Distribution", required=False) @classmethod async def get(cls, api, last_sync, deleted, date_from, date_to, **kwargs) -> Union[AsyncIterator["Lesson"], List[int]]: """ :rtype: Union[AsyncIterator[:class:`~vulcan.data.ChangeLesson`], List[int]] """ if date_from is None: date_from = datetime.date.today() if date_to is None: date_to = date_from date_to = date_to + datetime.timedelta( days=1 ) # Vulcan requires the date_to to be one greater the date it is supposed to be data = await api.helper.get_list( DATA_TIMETABLE_CHANGES, FilterType.BY_PUPIL, deleted=deleted, date_from=date_from, date_to=date_to, last_sync=last_sync, **kwargs, ) for lesson in data: yield ChangedLesson.load(lesson)