This repository has been archived on 2024-05-23. You can view files and clone it, but cannot push or open issues or pull requests.
cal8tor/src/main.rs

177 lines
5.9 KiB
Rust
Raw Normal View History

2022-08-12 19:55:28 +02:00
use scraper::{Html, Selector};
2022-08-12 21:20:39 +02:00
mod models;
2022-08-12 19:55:28 +02:00
#[tokio::main]
2022-08-14 12:44:36 +02:00
async fn main() {
let document = get_webpage(3, 1, None).await.expect("Can't reach website.");
2022-08-12 19:55:28 +02:00
2022-08-13 15:00:34 +02:00
// Selectors
let sel_table = Selector::parse("table").unwrap();
let sel_tr = Selector::parse("tr").unwrap();
2022-08-13 15:00:34 +02:00
let sel_tbody = Selector::parse("tbody").unwrap();
let sel_th = Selector::parse("th").unwrap();
let sel_td = Selector::parse("td").unwrap();
let sel_em = Selector::parse("em").unwrap();
let sel_small = Selector::parse("small").unwrap();
let sel_strong = Selector::parse("strong").unwrap();
2022-08-12 21:20:39 +02:00
2022-08-13 15:00:34 +02:00
// Find the timetable
let raw_timetable = document.select(&sel_table).next().unwrap();
2022-08-12 21:20:39 +02:00
// Find the slots available for the timetable
2022-08-13 15:00:34 +02:00
let raw_schedules = raw_timetable.select(&sel_tr).next().unwrap();
// Find availables schedules
let mut schedules = Vec::new();
for time in raw_schedules.select(&sel_th) {
schedules.push(time.inner_html());
}
// Find the timetable values
let raw_timetable_values = raw_timetable.select(&sel_tbody).next().unwrap();
// For each days
let mut timetable = Vec::new();
for day in raw_timetable_values.select(&sel_tr) {
let mut courses_vec = Vec::new();
let mut location_tracker = 0;
2022-08-13 15:00:34 +02:00
for course in day.select(&sel_td) {
if course.inner_html() == "" {
courses_vec.push(None);
location_tracker += 1;
2022-08-13 15:00:34 +02:00
} else {
courses_vec.push(Some(models::Course {
name: course.select(&sel_em).next().unwrap().inner_html(),
professor: match course
.select(&sel_small)
.next()
.unwrap()
.inner_html()
.split("<br>")
.next()
{
Some(data) => {
if data.contains("</strong>") {
// This is the room, so there is no professor assigned
// to this courses yet
None
} else {
Some(data.to_string())
}
}
None => None,
},
room: course.select(&sel_strong).next().unwrap().inner_html(),
start: location_tracker,
size: match course.value().attr("colspan") {
Some(i) => i.parse().unwrap(),
None => 1,
},
2022-08-13 15:00:34 +02:00
}));
match &courses_vec[courses_vec.len() - 1] {
Some(course) => location_tracker += course.size,
None => location_tracker += 1,
}
2022-08-13 15:00:34 +02:00
}
}
timetable.push(models::Day {
name: day.select(&sel_th).next().unwrap().inner_html(),
courses: courses_vec,
})
}
2022-08-12 19:55:28 +02:00
2022-08-13 17:27:35 +02:00
if !check_timetable_consistency(&schedules, &timetable) {
panic!("Error when building the timetable.");
}
2022-08-12 19:01:29 +02:00
}
2022-08-13 17:27:35 +02:00
/// Check if the timetable is well built
fn check_timetable_consistency(schedules: &Vec<String>, timetable: &Vec<models::Day>) -> bool {
let mut checker = true;
for day in timetable {
let mut i = 0;
for course in &day.courses {
match course {
Some(course_it) => {
// Checks the consistency of course start times
if i != course_it.start {
checker = false;
break;
}
// Keep the track of how many courses are in the day
i += course_it.size
}
None => i += 1,
}
}
// The counter should be the same as the amount of possible hours of the day
if i != schedules.len() {
checker = false;
break;
}
2022-08-13 17:27:35 +02:00
}
checker
2022-08-13 17:27:35 +02:00
}
2022-08-14 12:44:36 +02:00
async fn get_webpage(
_year: i8,
_semester: i8,
_letter: Option<char>,
) -> Result<Html, Box<dyn std::error::Error>> {
/* let url = {
let panic_semester_message = "Unknown semester.";
let panic_letter_message = "Unknown letter.";
let base_url = "https://informatique.up8.edu/licence-iv/edt";
match year {
1 => {
let allow_letters = match semester {
1 => ['a', 'b', 'c'],
2 => ['x', 'y', 'z'],
_ => panic!("{}", panic_semester_message),
};
let c = letter.expect(panic_letter_message);
if allow_letters.contains(&c) {
format!("{}/l1-{}.html", base_url, c)
} else {
panic!("{}", panic_letter_message)
}
}
2 => {
let allow_letters = match semester {
1 => ['a', 'b'],
2 => ['x', 'y'],
_ => panic!("{}", panic_semester_message),
};
let c = letter.expect(panic_letter_message);
if allow_letters.contains(&c) {
format!("{}/l2-{}.html", base_url, c)
} else {
panic!("{}", panic_letter_message)
}
}
3 => match semester {
1 => format!("{}/l3.html", base_url),
2 => format!("{}/l3_2.html", base_url),
_ => panic!("{}", panic_semester_message),
},
_ => panic!("Unknown year."),
}
};
// Get raw html
let html = reqwest::get(url).await?.text().await?;
// Parse document
let document = Html::parse_document(&html); */
let html = include_str!("../target/debug.html");
let document = Html::parse_document(html);
Ok(document)
}