2023-09-28 00:00:46 +02:00
|
|
|
use chrono::{DateTime, Duration, Utc};
|
2022-08-15 17:25:36 +02:00
|
|
|
use regex::{Captures, Regex};
|
2023-09-28 00:00:46 +02:00
|
|
|
use scraper::Selector;
|
2022-08-16 11:55:51 +02:00
|
|
|
use std::collections::HashMap;
|
2022-08-15 12:20:16 +02:00
|
|
|
|
2023-09-28 00:00:46 +02:00
|
|
|
use crate::utils::{get_semester, get_webpage, get_year};
|
2022-08-15 17:50:16 +02:00
|
|
|
|
2023-09-28 00:00:46 +02:00
|
|
|
pub async fn info(
|
|
|
|
level: i8,
|
|
|
|
semester_opt: Option<i8>,
|
|
|
|
year_opt: Option<i32>,
|
|
|
|
user_agent: &str,
|
|
|
|
) -> HashMap<usize, Vec<(DateTime<Utc>, i64)>> {
|
|
|
|
let semester = get_semester(semester_opt);
|
2022-08-15 17:50:16 +02:00
|
|
|
|
2023-09-28 00:00:46 +02:00
|
|
|
let year = get_year(year_opt, semester);
|
2022-08-15 20:12:22 +02:00
|
|
|
|
2023-09-28 00:00:46 +02:00
|
|
|
let document = get_webpage(level, semester, &year, user_agent)
|
|
|
|
.await
|
|
|
|
.expect("Can't reach info website.");
|
2022-08-15 12:20:16 +02:00
|
|
|
|
2023-09-28 00:00:46 +02:00
|
|
|
// Selectors
|
|
|
|
let sel_b = Selector::parse("b").unwrap();
|
|
|
|
let sel_font = Selector::parse("font").unwrap();
|
|
|
|
|
|
|
|
// Find when is the back-to-school date
|
|
|
|
let raw_data = document
|
|
|
|
.select(&sel_b)
|
|
|
|
.find(|element| element.select(&sel_font).next().is_some())
|
|
|
|
.unwrap()
|
|
|
|
.inner_html();
|
|
|
|
|
|
|
|
let re = Regex::new(r"\d{1,2} (septembre|octobre)").unwrap();
|
|
|
|
let date = re.captures(&raw_data).unwrap().get(0).unwrap().as_str();
|
|
|
|
|
|
|
|
let weeks_s1_1 = 6; // Number of weeks in the first part of the first semester
|
|
|
|
let date_s1_1 = get_date(&format!("{} {}", date, year.split_once('-').unwrap().0)); // Get week of back-to-school
|
|
|
|
let weeks_s1_2 = 7; // Number of weeks in the second part of the first semester
|
|
|
|
let date_s1_2 = date_s1_1 + Duration::weeks(weeks_s1_1 + 1); // Add past weeks with the break-week
|
|
|
|
|
|
|
|
let weeks_s2_1 = 6; // Number of weeks in the first part of the second semester
|
|
|
|
let date_s2_1 = date_s1_2 + Duration::weeks(weeks_s1_2 + 4); // 4 weeks of vacation between semester
|
|
|
|
let weeks_s2_2 = 7; // Number of weeks in the second part of the second semester
|
|
|
|
let date_s2_2 = date_s2_1 + Duration::weeks(weeks_s2_1 + 1); // Add past weeks with the break-week
|
|
|
|
|
|
|
|
HashMap::from([
|
|
|
|
(
|
|
|
|
1_usize,
|
|
|
|
vec![(date_s1_1, weeks_s1_1), (date_s1_2, weeks_s1_2)],
|
|
|
|
),
|
|
|
|
(
|
|
|
|
2_usize,
|
|
|
|
vec![(date_s2_1, weeks_s2_1), (date_s2_2, weeks_s2_2)],
|
|
|
|
),
|
|
|
|
])
|
2022-08-15 12:20:16 +02:00
|
|
|
}
|
2022-08-15 17:25:36 +02:00
|
|
|
|
|
|
|
/// Turn a french date to an english one
|
|
|
|
fn anglophonization(date: &str) -> String {
|
|
|
|
let dico = HashMap::from([
|
|
|
|
("janvier", "january"),
|
2023-09-07 18:20:51 +02:00
|
|
|
("février", "february"),
|
2022-08-15 17:25:36 +02:00
|
|
|
("mars", "march"),
|
2023-09-07 18:20:51 +02:00
|
|
|
("avril", "april"),
|
|
|
|
("mai", "may"),
|
|
|
|
("juin", "june"),
|
|
|
|
("juillet", "july"),
|
|
|
|
("août", "august"),
|
2022-08-15 17:25:36 +02:00
|
|
|
("septembre", "september"),
|
2023-09-07 18:20:51 +02:00
|
|
|
("octobre", "october"),
|
2022-08-15 17:25:36 +02:00
|
|
|
("novembre", "november"),
|
2023-09-07 18:20:51 +02:00
|
|
|
("décembre", "december"),
|
2022-08-15 17:25:36 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
// New regex of all the french month
|
|
|
|
let re = Regex::new(&format!(
|
|
|
|
"({})",
|
|
|
|
dico.keys().cloned().collect::<Vec<_>>().join("|")
|
|
|
|
))
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
format!(
|
2023-09-07 18:29:09 +02:00
|
|
|
// Use 12:00 and UTC TZ for chrono parser
|
|
|
|
"{} 12:00 +0000",
|
2022-08-15 17:25:36 +02:00
|
|
|
// Replace french by english month
|
2023-09-07 18:19:29 +02:00
|
|
|
re.replace_all(date, |cap: &Captures| match &cap[0] {
|
|
|
|
month if dico.contains_key(month) => dico.get(month).unwrap(),
|
|
|
|
month => {
|
|
|
|
panic!("Unknown month: {}", month)
|
2022-08-15 17:25:36 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
)
|
|
|
|
}
|
2022-08-15 17:50:16 +02:00
|
|
|
|
|
|
|
/// Turn a string to a DateTime
|
2022-08-15 19:06:36 +02:00
|
|
|
fn get_date(date: &str) -> DateTime<Utc> {
|
2022-08-15 17:50:16 +02:00
|
|
|
// Use and keep UTC time, we have the hour set to 12h and
|
2023-09-18 18:46:50 +02:00
|
|
|
// Paris 7 is in France so there is no problems
|
2023-09-07 18:29:09 +02:00
|
|
|
DateTime::parse_from_str(&anglophonization(date), "%e %B %Y %H:%M %z")
|
2022-08-15 17:50:16 +02:00
|
|
|
.unwrap()
|
2023-09-07 18:29:09 +02:00
|
|
|
.into()
|
2022-08-15 17:50:16 +02:00
|
|
|
}
|