class Period: """School year period :var int ~.id: Period ID :var int ~.number: Number of the period :var int ~.level: Level (class level) of the period :var `datetime.date` ~.from_: Period start date :var `datetime.date` ~.to: Period end date """ id = IntegerField(key="IdOkresKlasyfikacyjny") number = IntegerField(key="OkresNumer") level = IntegerField(key="OkresPoziom") from_ = DateField(key="OkresDataOdTekst", required=False) to = DateField(key="OkresDataDoTekst", required=False) @staticmethod def only_keys(json): return dict_only( json, { "IdOkresKlasyfikacyjny", "OkresNumer", "OkresPoziom", "OkresDataOdTekst", "OkresDataDoTekst", }, )
class DateTime(Serializable): """A date-time object used for representing points in time. :var int ~.timestamp: number of millis since the Unix epoch :var `datetime.date` ~.date: a date object :var `datetime.time` ~.time: a time object """ timestamp: int = IntegerField(key="Timestamp") date: date = DateField(key="Date") time: time = TimeField(key="Time") @property def date_time(self) -> datetime: """Combine the date and time of this object. :rtype: :class:`datetime.datetime` """ return datetime.combine(self.date, self.time) def __str__(self) -> str: return self.date_time.strftime("%Y-%m-%d %H:%m:%S") @classmethod async def get(cls, api, **kwargs) -> "DateTime": """ :rtype: :class:`~vulcan.hebe.model.DateTime` """ return await api.helper.get_object(DateTime, DATA_INTERNAL_TIME, *kwargs)
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 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 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 LuckyNumber(Serializable): """A lucky number for the specified date. :var `datetime.date` ~.date: lucky number date :var int ~.number: the lucky number """ date: date = DateField(key="Day") number: int = IntegerField(key="Number") @classmethod async def get(cls, api, day: date, **kwargs) -> "LuckyNumber": """ :rtype: :class:`~vulcan.data.LuckyNumber` """ return await api.helper.get_object(LuckyNumber, DATA_LUCKY_NUMBER, query={ "constituentId": api.student.school.id, "day": day.strftime("%Y-%m-%d"), }, **kwargs)
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 LinkedDocument: id = StringField() title = StringField() document_reference = StringField() issue = StringField() date = DateField()
class Issue: id = StringField() description = StringField() date = DateField() comment = StringField(required=False) page = SetField(str, required=False)
class Action: name = StringField() description = StringField() role = StringField(required=False) date = DateField(required=False)
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 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")