cal7tor/src/info.rs

103 lines
3.3 KiB
Rust
Raw Normal View History

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};
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);
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
}
})
)
}
/// Turn a string to a DateTime
2022-08-15 19:06:36 +02:00
fn get_date(date: &str) -> DateTime<Utc> {
// 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")
.unwrap()
2023-09-07 18:29:09 +02:00
.into()
}