feat(api): add api endpoints to retrieve every teacher and class
This commit is contained in:
parent
8d1fe3b8f2
commit
d3d9f04a2c
113
src/api/mod.rs
113
src/api/mod.rs
@ -11,7 +11,7 @@ use scraper::{Html, Selector};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use sha1::{Digest, Sha1};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ops::Range;
|
||||
use std::{fs, process::Command};
|
||||
|
||||
@ -21,7 +21,9 @@ pub fn get_routes() -> Router {
|
||||
Router::new()
|
||||
.route("/pdf", get(pdf))
|
||||
.route("/classi", get(get_classes))
|
||||
.route("/professori", get(get_teachers)),
|
||||
.route("/professori", get(get_teachers))
|
||||
.route("/classe", get(get_class))
|
||||
.route("/professore", get(get_teacher)),
|
||||
)
|
||||
}
|
||||
|
||||
@ -94,7 +96,7 @@ pub struct Header {
|
||||
weekdays: HashMap<String, Range<usize>>,
|
||||
}
|
||||
|
||||
pub async fn get_classes(Query(params): Query<FilterByTeacherQuery>) -> impl IntoResponse {
|
||||
pub async fn get_class(Query(params): Query<FilterByTeacherQuery>) -> impl IntoResponse {
|
||||
let filename = match download_pdf(params.id).await {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
@ -136,7 +138,7 @@ pub struct FilterByClassQuery {
|
||||
classe: String,
|
||||
}
|
||||
|
||||
pub async fn get_teachers(Query(params): Query<FilterByClassQuery>) -> impl IntoResponse {
|
||||
pub async fn get_teacher(Query(params): Query<FilterByClassQuery>) -> impl IntoResponse {
|
||||
let filename = match download_pdf(params.id).await {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
@ -222,3 +224,106 @@ pub fn get_header(record: &StringRecord) -> Header {
|
||||
weekdays,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GetTeachersQuery {
|
||||
id: u8,
|
||||
}
|
||||
|
||||
pub async fn get_teachers(Query(params): Query<GetTeachersQuery>) -> impl IntoResponse {
|
||||
let filename = match download_pdf(params.id).await {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
Json(json!({ "errore": "ID non valido"})),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let csv_content = fs::read_to_string(&filename).unwrap();
|
||||
let mut rdr = csv::Reader::from_reader(csv_content.as_bytes());
|
||||
let header = get_header(rdr.headers().unwrap());
|
||||
|
||||
let mut teachers = Vec::new();
|
||||
|
||||
for record in rdr.records() {
|
||||
let record = match record {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
Json(json!({ "errore": "Formato non supportato"})),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(teacher) = record.get(header.teacher as usize) {
|
||||
if !teacher.is_empty() {
|
||||
teachers.push(teacher.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !teachers.is_empty() {
|
||||
(StatusCode::OK, Json(json!(teachers)))
|
||||
} else {
|
||||
(
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
Json(json!({ "errore": "classe non trovata"})),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GetClassesQuery {
|
||||
id: u8,
|
||||
}
|
||||
|
||||
fn is_valid_class(class: &str) -> bool {
|
||||
class.len() == 5
|
||||
&& class.chars().next().unwrap().is_digit(6)
|
||||
&& class.chars().skip(1).all(|x| x.is_alphabetic())
|
||||
}
|
||||
|
||||
pub async fn get_classes(Query(params): Query<GetClassesQuery>) -> impl IntoResponse {
|
||||
let filename = match download_pdf(params.id).await {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return (
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
Json(json!({ "errore": "ID non valido"})),
|
||||
)
|
||||
}
|
||||
};
|
||||
let csv_content = fs::read_to_string(&filename).unwrap();
|
||||
|
||||
let mut rdr = csv::Reader::from_reader(csv_content.as_bytes());
|
||||
let header = get_header(rdr.headers().unwrap());
|
||||
|
||||
let mut classes: Vec<HashMap<char, HashSet<String>>> = vec![HashMap::new(); 5];
|
||||
|
||||
for record in rdr.records() {
|
||||
let record = record.unwrap();
|
||||
for (i, cell) in record.iter().enumerate() {
|
||||
for (_, range) in header.weekdays.clone() {
|
||||
if range.contains(&i) && is_valid_class(cell) {
|
||||
let value = classes
|
||||
[cell.chars().next().unwrap().to_digit(6).unwrap() as usize - 1usize]
|
||||
.entry(cell.chars().nth(1).unwrap())
|
||||
.or_default();
|
||||
value.insert(cell[2..].to_string().to_lowercase());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if classes.is_empty() {
|
||||
(
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
Json(json!({ "errore": "classe non trovata"})),
|
||||
)
|
||||
} else {
|
||||
(StatusCode::OK, Json(json!(classes)))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user