use chrono::TimeZone;
use crate::{datetime::Date, error::Error, jsonrpc, params, resources::*, Session};
pub struct Client {
rpc_client: jsonrpc::Client,
session: Session,
}
impl Client {
pub fn login(
server: &str,
school: &str,
username: &str,
password: &str,
) -> Result<Self, Error> {
let params = params::AuthenticateParams {
client: "untis-rs",
user: username,
password,
};
let mut rpc_client = jsonrpc::Client::new(&make_untis_url(server, school));
let session: Session = rpc_client.request("authenticate", params)?;
Ok(Self {
rpc_client,
session,
})
}
pub fn session(&self) -> &Session {
&self.session
}
pub fn last_update_time(&mut self) -> Result<chrono::DateTime<chrono::Utc>, Error> {
let ts: i64 = self.rpc_client.request("getLatestImportTime", ())?;
Ok(chrono::Utc.timestamp_millis_opt(ts).unwrap())
}
pub fn status_data(&mut self) -> Result<StatusData, Error> {
self.rpc_client.request("getStatusData", ())
}
pub fn current_schoolyear(&mut self) -> Result<Schoolyear, Error> {
self.rpc_client.request("getCurrentSchoolyear", ())
}
pub fn schoolyears(&mut self) -> Result<Vec<Schoolyear>, Error> {
self.rpc_client.request("getSchoolyears", ())
}
pub fn holidays(&mut self) -> Result<Vec<Holiday>, Error> {
self.rpc_client.request("getHolidays", ())
}
pub fn rooms(&mut self) -> Result<Vec<Room>, Error> {
self.rpc_client.request("getRooms", ())
}
pub fn classes(&mut self) -> Result<Vec<Class>, Error> {
self.rpc_client.request("getKlassen", ())
}
pub fn subjects(&mut self) -> Result<Vec<Subject>, Error> {
self.rpc_client.request("getSubjects", ())
}
pub fn teachers(&mut self) -> Result<Vec<Teacher>, Error> {
self.rpc_client.request("getTeachers", ())
}
pub fn students(&mut self) -> Result<Vec<Student>, Error> {
self.rpc_client.request("getStudents", ())
}
pub fn own_timetable_until(&mut self, end_date: &Date) -> Result<Vec<Lesson>, Error> {
self.own_timetable_between(&Date::today(), end_date)
}
pub fn own_timetable_current_week(&mut self) -> Result<Vec<Lesson>, Error> {
self.own_timetable_for_week(&Date::today())
}
pub fn own_timetable_for_week(&mut self, date: &Date) -> Result<Vec<Lesson>, Error> {
self.own_timetable_between(&date.relative_week_begin(), &date.relative_week_end())
}
pub fn own_timetable_between(
&mut self,
start_date: &Date,
end_date: &Date,
) -> Result<Vec<Lesson>, Error> {
self.timetable_between(
&self.session.person_id.clone(),
&self.session.person_type.clone(),
start_date,
end_date,
)
}
pub fn timetable_until(
&mut self,
id: &usize,
ty: &ElementType,
end_date: &Date,
) -> Result<Vec<Lesson>, Error> {
self.timetable_between(id, ty, &Date::today(), end_date)
}
pub fn timetable_current_week(
&mut self,
id: &usize,
ty: &ElementType,
) -> Result<Vec<Lesson>, Error> {
self.timetable_for_week(id, ty, &Date::today())
}
pub fn timetable_for_week(
&mut self,
id: &usize,
ty: &ElementType,
date: &Date,
) -> Result<Vec<Lesson>, Error> {
self.timetable_between(
id,
ty,
&date.relative_week_begin(),
&date.relative_week_end(),
)
}
pub fn timetable_between(
&mut self,
id: &usize,
ty: &ElementType,
start_date: &Date,
end_date: &Date,
) -> Result<Vec<Lesson>, Error> {
let params = params::TimetableParams {
options: ¶ms::TimetableParamsOpts {
element: ¶ms::TimetableParamsElem { id, ty },
start_date,
end_date,
show_booking: &true,
show_info: &true,
show_subst_text: &true,
show_ls_text: &true,
show_ls_number: &true,
show_student_group: &true,
class_fields: &["id", "name"],
room_fields: &["id", "name"],
subject_fields: &["id", "name"],
teacher_fields: &["id", "name"],
},
};
self.rpc_client.request("getTimetable", params)
}
pub fn departments(&mut self) -> Result<Vec<Department>, Error> {
self.rpc_client.request("getDepartments", ())
}
fn logout(&mut self) -> Result<(), Error> {
self.rpc_client.request("logout", ())
}
}
impl Drop for Client {
fn drop(&mut self) {
_ = self.logout();
}
}
impl School {
pub fn client_login(&self, username: &str, password: &str) -> Result<Client, Error> {
Client::login(&self.server, &self.login_name, username, password)
}
}
fn make_untis_url(server: &str, school: &str) -> String {
format!("https://{}/WebUntis/jsonrpc.do?school={}", server, school)
}