diff --git a/src/main.rs b/src/main.rs
index 0cd853d..cab88fb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,176 +1,21 @@
-use scraper::{Html, Selector};
+use scraper::Html;
-mod models;
+mod timetable;
#[tokio::main]
async fn main() {
- let document = get_webpage(3, 1, None).await.expect("Can't reach website.");
- // Selectors
- let sel_table = Selector::parse("table").unwrap();
- let sel_tr = Selector::parse("tr").unwrap();
- 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();
+ let _timetable = timetable::timetable(3, 1, None).await;
- // Find the timetable
- let raw_timetable = document.select(&sel_table).next().unwrap();
-
- // Find the slots available for the timetable
- 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;
- for course in day.select(&sel_td) {
- if course.inner_html() == "—" {
- courses_vec.push(None);
- location_tracker += 1;
- } 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("
")
- .next()
- {
- Some(data) => {
- if data.contains("") {
- // 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,
- },
- }));
-
- match &courses_vec[courses_vec.len() - 1] {
- Some(course) => location_tracker += course.size,
- None => location_tracker += 1,
- }
- }
- }
-
- timetable.push(models::Day {
- name: day.select(&sel_th).next().unwrap().inner_html(),
- courses: courses_vec,
- })
- }
-
- if !check_timetable_consistency(&schedules, &timetable) {
- panic!("Error when building the timetable.");
- }
+ let _document_info = get_webpage_info().await.expect("Can't reach info website.");
+ // println!("{:#?}", document_info);
}
-/// Check if the timetable is well built
-fn check_timetable_consistency(schedules: &Vec, timetable: &Vec) -> 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;
- }
- }
+async fn get_webpage_info() -> Result> {
+ /* let html = reqwest::get("https://informatique.up8.edu/licence-iv/edt").await?.text().await?;
- checker
-}
-
-async fn get_webpage(
- _year: i8,
- _semester: i8,
- _letter: Option,
-) -> Result> {
- /* 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)
+ Ok(Html::parse_document(&html)) */
+
+ let html = include_str!("../target/debug2.html");
+ Ok(Html::parse_document(html))
}
diff --git a/src/timetable.rs b/src/timetable.rs
new file mode 100644
index 0000000..40d6961
--- /dev/null
+++ b/src/timetable.rs
@@ -0,0 +1,183 @@
+use scraper::{Selector, Html};
+
+mod models;
+
+pub async fn timetable(year: i8, semester: i8, letter: Option) -> Vec {
+ let document_timetable = get_webpage(year, semester, letter).await.expect("Can't reach timetable website.");
+
+ // Selectors
+ let sel_table = Selector::parse("table").unwrap();
+ let sel_tr = Selector::parse("tr").unwrap();
+ 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();
+
+ // Find the timetable
+ let raw_timetable = document_timetable.select(&sel_table).next().unwrap();
+
+ // Find the slots available for the timetable
+ 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;
+ for course in day.select(&sel_td) {
+ if course.inner_html() == "—" {
+ courses_vec.push(None);
+ location_tracker += 1;
+ } 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("
")
+ .next()
+ {
+ Some(data) => {
+ if data.contains("") {
+ // 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()
+ .replace("
", ""),
+ start: location_tracker,
+ size: match course.value().attr("colspan") {
+ Some(i) => i.parse().unwrap(),
+ None => 1,
+ },
+ }));
+
+ match &courses_vec[courses_vec.len() - 1] {
+ Some(course) => location_tracker += course.size,
+ None => location_tracker += 1,
+ }
+ }
+ }
+
+ timetable.push(models::Day {
+ name: day.select(&sel_th).next().unwrap().inner_html(),
+ courses: courses_vec,
+ })
+ }
+
+ if !check_consistency(&schedules, &timetable) {
+ panic!("Error when building the timetable.");
+ }
+
+ timetable
+}
+
+async fn get_webpage(
+ year: i8,
+ semester: i8,
+ letter: Option,
+) -> Result> {
+ /* 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); */
+
+ println!("Fetch 'L{}{} (s{})'", year, letter.unwrap_or(' '), semester);
+ let html = include_str!("../target/debug.html");
+ let document = Html::parse_document(html);
+
+ Ok(document)
+}
+
+/// Check if the timetable is well built
+fn check_consistency(schedules: &Vec, timetable: &Vec) -> 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;
+ }
+ }
+
+ checker
+}
diff --git a/src/models.rs b/src/timetable/models.rs
similarity index 100%
rename from src/models.rs
rename to src/timetable/models.rs