This repository has been archived on 2023-06-26. You can view files and clone it, but cannot push or open issues or pull requests.
meincantor-api/src/main.rs
2021-07-01 17:57:15 +02:00

173 lines
4.9 KiB
Rust

#[macro_use] extern crate rocket;
#[macro_use] extern crate diesel;
mod schema;
extern crate serde;
use rocket::serde::json::{Json, json};
use crate::schema::timetable;
use diesel::{Queryable, Insertable};
use serde_derive::{Serialize, Deserialize};
use rocket_sync_db_pools::{database, diesel::PgConnection};
use reqwest;
use quickxml_to_serde::{xml_string_to_json, Config};
extern crate serde_json;
mod config;
#[database("timetable")]
struct DbConn(PgConnection);
#[derive(Queryable, Serialize, Insertable, Deserialize)]
#[table_name="timetable"]
struct Timetable {
date: String,
updated: String,
class: String,
timetable_data: serde_json::Value
}
#[derive(Serialize, Deserialize)]
struct TimetableData {
count: usize,
courses: Vec<rocket::serde::json::Value>
}
async fn get_timetable_xml() -> serde_json::value::Value {
let client = reqwest::Client::new();
let resp = client
.get(config::TIMETABLE_URL)
.basic_auth(config::TIMETABLE_USER, config::TIMETABLE_PASSWORD)
.send().await.unwrap()
.text().await.unwrap();
let xml = xml_string_to_json(resp, &Config::new_with_defaults()).unwrap();
xml
}
async fn get_timetable_xml_data() -> Vec<serde_json::value::Value> {
let xml = get_timetable_xml().await;
let classes = xml
.as_object().unwrap()
.get("VpMobil").unwrap()
.get("Klassen").unwrap()
.get("Kl").unwrap()
.as_array().unwrap();
classes.to_owned().to_owned()
}
#[get("/")]
async fn get_timetable(_conn: DbConn) -> Json<Vec<Timetable>> {
let xml = get_timetable_xml().await;
let classes = get_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 plan = i
.as_object().unwrap()
.get("Pl").unwrap()
.as_object().unwrap()
.get("Std").unwrap_or(&nothing)
.as_array().unwrap();
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: 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)
}
Json::from(timetable)
}
#[get("/<class>")]
async fn get_class_timetable(_conn: DbConn, class: String) -> Json<TimetableData> {
let classes = get_timetable_xml_data().await;
let courses: Vec<rocket::serde::json::Value> = Vec::new();
let mut response = TimetableData {
count: 0,
courses: courses
};
for i in classes.iter() {
if i
.as_object().unwrap()
.get("Kurz").unwrap()
.as_str().unwrap()
.replace("/", "_") == class {
let nothing = json!([""]);
let plan = i
.as_object().unwrap()
.get("Pl").unwrap()
.as_object().unwrap()
.get("Std").unwrap_or(&nothing)
.as_array().unwrap();
response.count = plan.len();
for i in plan {
if i.as_object() != None {
response.courses.push(i.to_owned());
} else {
dbg!("Failed: {:?}", &i);
}
}
break;
}
}
Json::from(response)
}
#[get("/classes")]
async fn get_classes() -> Json<Vec<String>> {
let classes = get_timetable_xml_data().await;
let mut class_list: Vec<String> = Vec::new();
for i in classes.iter() {
class_list.push(i.as_object().unwrap()
.get("Kurz").unwrap()
.as_str().unwrap()
.replace("/", "_"))
}
Json::from(class_list)
}
#[get("/")]
fn hello() -> &'static str {
"Hello, World!"
}
#[get("/<name>")]
fn hello_name(name: String) -> String {
format!("Hello, {}!", name)
}
#[launch]
fn rocket() -> _ {
rocket::build()
.attach(DbConn::fairing())
.mount("/hello", routes![hello, hello_name])
.mount("/timetable", routes![get_timetable, get_class_timetable, get_classes])
}