Created first API Endpoints for timetable.
This commit is contained in:
173
src/main.rs
173
src/main.rs
@ -1,3 +1,172 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
#[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(¬hing)
|
||||
.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(¬hing)
|
||||
.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])
|
||||
}
|
||||
|
9
src/schema.rs
Normal file
9
src/schema.rs
Normal file
@ -0,0 +1,9 @@
|
||||
table! {
|
||||
timetable (id) {
|
||||
id -> Int4,
|
||||
date -> Varchar,
|
||||
updated -> Varchar,
|
||||
class -> Varchar,
|
||||
timetable_data -> Nullable<Jsonb>,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user