From 189b77cc4fe0b0c2625a052e9872d266ccf83d86 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Tue, 26 Sep 2023 23:08:41 +0200 Subject: [PATCH] Correctly build the timetable from scratch --- src/main.rs | 7 ++-- src/timetable.rs | 86 ++++++++++++++++++++++++++++++++++++----- src/timetable/models.rs | 13 ++++++- 3 files changed, 92 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3828c65..f907a05 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,10 +55,9 @@ async fn main() { level, pathway.to_uppercase() ); - let timetable = - timetable::timetable(level, args.semester, args.year, pathway, &user_agent).await; + let timetable = timetable::timetable(level, args.semester, args.year, &user_agent).await; - /* println!("Récupération des informations par rapport à l'année..."); + println!("Récupération des informations par rapport à l'année..."); let info = info::info(&user_agent).await; if args.export.is_some() { @@ -74,5 +73,5 @@ async fn main() { println!("Affichage..."); timetable::display(timetable, args.cl); println!("Vous devrez peut-être mettre votre terminal en plein écran si ce n'est pas déjà le cas."); - } */ + } } diff --git a/src/timetable.rs b/src/timetable.rs index f029c4c..0c16348 100644 --- a/src/timetable.rs +++ b/src/timetable.rs @@ -4,7 +4,7 @@ use scraper::{Html, Selector}; use std::collections::HashMap; use crate::utils::{ - self, capitalize, + self, models::{Position, TabChar}, }; @@ -15,7 +15,6 @@ pub async fn timetable( level: i8, semester_opt: Option, year_opt: Option, - pathway: &str, user_agent: &str, ) -> (Vec, (usize, Vec)) { let semester = get_semester(semester_opt); @@ -30,23 +29,92 @@ pub async fn timetable( let sel_table = Selector::parse("table").unwrap(); let sel_tbody = Selector::parse("tbody").unwrap(); let sel_td = Selector::parse("td").unwrap(); + let sel_small = Selector::parse("small").unwrap(); + let sel_b = Selector::parse("b").unwrap(); // Find the timetable let raw_timetable = document.select(&sel_table).next().unwrap(); - /* We are now iterating over all the 15-minute intervals to find courses */ - for element in raw_timetable + let mut schedules = Vec::new(); + for hour in 8..=20 { + for minute in &[0, 15, 30, 45] { + let hour_str = format!("{}h{:02}", hour, minute); + schedules.push(hour_str); + } + } + + let mut timetable: Vec = Vec::new(); + + raw_timetable .select(&sel_tbody) .next() .unwrap() .select(&sel_td) - { - if let Some(i) = element.value().attr("title") { - println!("{}", i) - } + .filter(|element| element.value().attr("title").is_some()) + .for_each(|i| { + let matches = + Regex::new(r"(?PCOURS|TD|TP) (?P.*) : (?P(lundi|mardi|mercredi|jeudi|vendredi)) (?P.*) \(durée : (?P.*)\)") + .unwrap() + .captures(i.value().attr("title").unwrap()) + .unwrap(); + + let day: &str = matches + .name("day") + .unwrap() + .as_str(); + + + let binding = i.select(&sel_b).last().unwrap().inner_html(); + let course = models::Course{ + typee: match matches + .name("type") + .unwrap() + .as_str() { + "COURS" => models::Type::Cours, + "TP" => models::Type::TP, + "TD" => models::Type::TD, + _ => panic!("Unknown type of course") + }, + name: matches + .name("name") + .unwrap() + .as_str().to_owned(), + professor: match i.select(&sel_small).last().unwrap().inner_html() { + i if i.starts_with(" None, + i => Some(i), + }, + room: Regex::new(r"(|
.*?
.*?)
(?P.*?)
") + .unwrap() + .captures(&binding) + .unwrap().name("location") + .unwrap() + .as_str().to_owned(), + start: schedules.iter().position(|r| r == matches + .name("startime") + .unwrap() + .as_str()).unwrap(), + size: i.value().attr("rowspan").unwrap().parse::().unwrap(), + dtstart: None, + dtend: None, + }; + + // Search for the day in the timetable + if let Some(existing_day) = timetable.iter_mut().find(|x| x.name == day) { + existing_day.courses.push(Some(course)); + } else { + // Day with the name doesn't exist, create a new Day + timetable.push(models::Day { + name: day.to_owned(), + courses: vec![Some(course)], + }); + } + }); + + if !check_consistency(&schedules, &timetable) { + panic!("Error when building the timetable."); } - todo!() + (schedules, (semester as usize, timetable)) } /// Get timetable webpage diff --git a/src/timetable/models.rs b/src/timetable/models.rs index 1b67bcf..bb813a3 100644 --- a/src/timetable/models.rs +++ b/src/timetable/models.rs @@ -1,5 +1,15 @@ -#[derive(Clone)] +#[derive(Clone, Debug)] +pub enum Type { + Cours, + TP, + TD, +} + +#[derive(Clone, Debug)] pub struct Course { + /// Type du cours + pub typee: Type, + /// Course's name pub name: String, @@ -27,6 +37,7 @@ pub struct Course { pub dtend: Option>, } +#[derive(Debug)] pub struct Day { /// Day's name pub name: String,