Split today and latest timetable
This commit is contained in:
parent
e04f39945e
commit
228bd4e46e
@ -17,6 +17,7 @@ serde_json = "1.0"
|
||||
jsonwebtoken = "7.2"
|
||||
time = "0.2"
|
||||
keycloak = "14"
|
||||
chrono = "0.4"
|
||||
|
||||
|
||||
[dependencies.serde_derive]
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::config;
|
||||
use crate::schema::timetable;
|
||||
use crate::DbConn;
|
||||
use chrono::Local;
|
||||
use diesel::{Insertable, Queryable};
|
||||
use quickxml_to_serde::{xml_string_to_json, Config};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
@ -21,10 +22,14 @@ pub struct TimetableData {
|
||||
pub courses: Vec<rocket::serde::json::Value>,
|
||||
}
|
||||
|
||||
async fn get_timetable_xml() -> serde_json::value::Value {
|
||||
async fn get_today_timetable_xml() -> serde_json::value::Value {
|
||||
let client = reqwest::Client::new();
|
||||
let resp = client
|
||||
.get(config::TIMETABLE_URL)
|
||||
.get(format!(
|
||||
"{}/PlanKl{}.xml",
|
||||
config::TIMETABLE_URL,
|
||||
Local::today().format("%Y%m%d")
|
||||
))
|
||||
.basic_auth(config::TIMETABLE_USER, config::TIMETABLE_PASSWORD)
|
||||
.send()
|
||||
.await
|
||||
@ -35,6 +40,36 @@ async fn get_timetable_xml() -> serde_json::value::Value {
|
||||
xml_string_to_json(resp, &Config::new_with_defaults()).unwrap()
|
||||
}
|
||||
|
||||
async fn get_timetable_xml() -> serde_json::value::Value {
|
||||
let client = reqwest::Client::new();
|
||||
let resp = client
|
||||
.get(format!("{}/Klassen.xml", config::TIMETABLE_URL))
|
||||
.basic_auth(config::TIMETABLE_USER, config::TIMETABLE_PASSWORD)
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.text()
|
||||
.await
|
||||
.unwrap();
|
||||
xml_string_to_json(resp, &Config::new_with_defaults()).unwrap()
|
||||
}
|
||||
|
||||
async fn get_today_timetable_xml_data() -> Vec<serde_json::value::Value> {
|
||||
let xml = get_today_timetable_xml().await;
|
||||
let classes = xml
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.get("VpMobil")
|
||||
.unwrap()
|
||||
.get("Klassen")
|
||||
.unwrap()
|
||||
.get("Kl")
|
||||
.unwrap()
|
||||
.as_array()
|
||||
.unwrap();
|
||||
classes.to_owned()
|
||||
}
|
||||
|
||||
async fn get_timetable_xml_data() -> Vec<serde_json::value::Value> {
|
||||
let xml = get_timetable_xml().await;
|
||||
let classes = xml
|
||||
@ -51,6 +86,79 @@ async fn get_timetable_xml_data() -> Vec<serde_json::value::Value> {
|
||||
classes.to_owned()
|
||||
}
|
||||
|
||||
pub async fn get_today_timetable(_conn: DbConn) -> Vec<Timetable> {
|
||||
let xml = get_today_timetable_xml().await;
|
||||
let classes = get_today_timetable_xml_data().await;
|
||||
let mut timetable: Vec<Timetable> = Vec::new();
|
||||
for i in classes.iter() {
|
||||
let mut courses: Vec<rocket::serde::json::Value> = Vec::new();
|
||||
let nothing = json!([""]);
|
||||
let std = i
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.get("Pl")
|
||||
.unwrap()
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.get("Std")
|
||||
.unwrap_or(¬hing);
|
||||
let mut plan = vec![];
|
||||
if std.is_array() {
|
||||
plan.extend(std.as_array().unwrap().iter().cloned())
|
||||
} else if std.is_object() {
|
||||
plan.push(std.clone())
|
||||
}
|
||||
for i in &plan {
|
||||
if i.as_object() != None {
|
||||
courses.push(i.to_owned());
|
||||
} else {
|
||||
dbg!("Failed: {:?}", &i);
|
||||
}
|
||||
}
|
||||
let response = TimetableData {
|
||||
count: plan.len(),
|
||||
courses,
|
||||
};
|
||||
let timetable_element = Timetable {
|
||||
date: String::from(
|
||||
xml.as_object()
|
||||
.unwrap()
|
||||
.get("VpMobil")
|
||||
.unwrap()
|
||||
.get("Kopf")
|
||||
.unwrap()
|
||||
.get("DatumPlan")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap(),
|
||||
),
|
||||
updated: String::from(
|
||||
xml.as_object()
|
||||
.unwrap()
|
||||
.get("VpMobil")
|
||||
.unwrap()
|
||||
.get("Kopf")
|
||||
.unwrap()
|
||||
.get("zeitstempel")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap(),
|
||||
),
|
||||
class: String::from(
|
||||
i.as_object()
|
||||
.unwrap()
|
||||
.get("Kurz")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap(),
|
||||
),
|
||||
timetable_data: serde_json::from_str(&json!(response).to_string()).unwrap(),
|
||||
};
|
||||
timetable.push(timetable_element)
|
||||
}
|
||||
timetable
|
||||
}
|
||||
|
||||
pub async fn get_timetable(_conn: DbConn) -> Vec<Timetable> {
|
||||
let xml = get_timetable_xml().await;
|
||||
let classes = get_timetable_xml_data().await;
|
||||
@ -124,6 +232,50 @@ pub async fn get_timetable(_conn: DbConn) -> Vec<Timetable> {
|
||||
timetable
|
||||
}
|
||||
|
||||
pub async fn get_today_class_timetable(_conn: DbConn, class: String) -> TimetableData {
|
||||
let classes = get_today_timetable_xml_data().await;
|
||||
let courses: Vec<rocket::serde::json::Value> = Vec::new();
|
||||
let mut response = TimetableData { count: 0, courses };
|
||||
for i in classes.iter() {
|
||||
if i.as_object()
|
||||
.unwrap()
|
||||
.get("Kurz")
|
||||
.unwrap()
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.replace("/", "_")
|
||||
== class
|
||||
{
|
||||
let nothing = json!([""]);
|
||||
let std = i
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.get("Pl")
|
||||
.unwrap()
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.get("Std")
|
||||
.unwrap_or(¬hing);
|
||||
let mut plan = vec![];
|
||||
if std.is_array() {
|
||||
plan.extend(std.as_array().unwrap().iter().cloned())
|
||||
} else if std.is_object() {
|
||||
plan.push(std.clone())
|
||||
}
|
||||
response.count = plan.len();
|
||||
for i in plan {
|
||||
if i.as_object() != None {
|
||||
response.courses.push(i.to_owned());
|
||||
} else {
|
||||
dbg!("Failed: {:?}", &i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
response
|
||||
}
|
||||
|
||||
pub async fn get_class_timetable(_conn: DbConn, class: String) -> TimetableData {
|
||||
let classes = get_timetable_xml_data().await;
|
||||
let courses: Vec<rocket::serde::json::Value> = Vec::new();
|
||||
|
26
src/main.rs
26
src/main.rs
@ -168,6 +168,15 @@ async fn get_timetable(
|
||||
Json::from(timetable)
|
||||
}
|
||||
|
||||
#[get("/today")]
|
||||
async fn get_today_timetable(
|
||||
conn: DbConn,
|
||||
_key: ApiKey<'_>,
|
||||
) -> Json<Vec<timetable_connector::Timetable>> {
|
||||
let timetable = timetable_connector::get_today_timetable(conn).await;
|
||||
Json::from(timetable)
|
||||
}
|
||||
|
||||
#[get("/<class>")]
|
||||
async fn get_class_timetable(
|
||||
conn: DbConn,
|
||||
@ -178,6 +187,16 @@ async fn get_class_timetable(
|
||||
Json::from(timetable)
|
||||
}
|
||||
|
||||
#[get("/<class>/today")]
|
||||
async fn get_today_class_timetable(
|
||||
conn: DbConn,
|
||||
class: String,
|
||||
_key: ApiKey<'_>,
|
||||
) -> Json<timetable_connector::TimetableData> {
|
||||
let timetable = timetable_connector::get_today_class_timetable(conn, class).await;
|
||||
Json::from(timetable)
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn get_classes(_key: ApiKey<'_>) -> Json<Vec<String>> {
|
||||
let class_list = timetable_connector::get_classes().await;
|
||||
@ -192,7 +211,12 @@ fn rocket() -> _ {
|
||||
.mount("/login", routes![login])
|
||||
.mount(
|
||||
"/api/timetable",
|
||||
routes![get_timetable, get_class_timetable],
|
||||
routes![
|
||||
get_timetable,
|
||||
get_class_timetable,
|
||||
get_today_timetable,
|
||||
get_today_class_timetable
|
||||
],
|
||||
)
|
||||
.mount("/api/classes", routes![get_classes])
|
||||
.mount("/api/userinfo", routes![get_userinfo])
|
||||
|
Reference in New Issue
Block a user