Many improvement to support many type of cases

- ask for first period day of the current one instead of the first one
- holidays are not mandatory anymore
- also add an option to force the weeks number
This commit is contained in:
Mylloon 2025-01-03 11:17:28 +01:00
parent bbdc50b23a
commit 64911ba351
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
3 changed files with 68 additions and 18 deletions

View file

@ -4,7 +4,7 @@ use scraper::Selector;
use std::{collections::HashMap, sync::Arc};
use crate::utils::{
get_semester, get_webpage, get_year,
get_period_weeks, get_semester, get_webpage, get_year,
models::{Info, InfoList, InfoType},
};
@ -33,28 +33,47 @@ pub async fn get_start_date(
.unwrap()
.inner_html();
let re = Regex::new(r"\d{1,2} (septembre|octobre)").unwrap();
let first_semester = semester == 1;
re.captures(&raw_data)
.and_then(|caps| caps.get(0))
.map_or("1 septembre".to_owned(), |m| m.as_str().to_owned())
let re = Regex::new(if first_semester {
r"\d{1,2} (septembre|octobre)"
} else {
r"\d{1,2} (janvier|février)"
})
.unwrap();
re.captures(&raw_data).and_then(|caps| caps.get(0)).map_or(
if first_semester {
"1 septembre"
} else {
"1 janvier"
}
.to_owned(),
|m| m.as_str().to_owned(),
)
}
pub fn info(semester_opt: Option<i8>, year_opt: Option<i32>, date: &str, skip_week: bool) -> Info {
#[allow(clippy::bool_to_int_with_if)]
pub fn info(
semester_opt: Option<i8>,
year_opt: Option<i32>,
date: &str,
skip_week: bool,
holidays: bool,
weeks: Option<i32>,
) -> Info {
let semester = get_semester(semester_opt);
let year = get_year(year_opt, semester);
// 1st semester
let weeks_s1_1 = 6; // Weeks before break
let weeks_s1_2 = 7; // Weeks after break
let (weeks_s1_1, weeks_s1_2) = get_period_weeks(1, weeks); // Weeks before and after break
let date_s1_1 = get_date(&format!("{} {}", date, year.split_once('-').unwrap().0)); // Get first week of school
let date_s1_2 = date_s1_1 + Duration::weeks(weeks_s1_1 + 1); // Back-to-school week - add week of holidays
let date_s1_2 = date_s1_1 + Duration::weeks(weeks_s1_1 + if holidays { 1 } else { 0 }); // Back-to-school week
// 2nd semester
let weeks_s2_1 = 11; // Weeks before break
let weeks_s2_2 = 1; // Weeks after break
let date_s2_1 = date_s1_2 + Duration::weeks(weeks_s1_2 + 4); // Get first week - add week of 'christmas/new year holidays'
let date_s2_2 = date_s2_1 + Duration::weeks(weeks_s2_1 + 2); // Back-to-school week - add week of holidays
let (weeks_s2_1, weeks_s2_2) = get_period_weeks(2, weeks); // Weeks before and after break
let date_s2_1 = get_date(&format!("{} {}", date, year.split_once('-').unwrap().1)); // Get first week
let date_s2_2 = date_s2_1 + Duration::weeks(weeks_s2_1 + if holidays { 2 } else { 0 }); // Back-to-school week
// Group courses values and derive it for TD/TP
let cours_s1 = vec![(date_s1_1, weeks_s1_1), (date_s1_2, weeks_s1_2)];

View file

@ -8,6 +8,7 @@ mod info;
mod timetable;
mod utils;
#[allow(clippy::struct_excessive_bools)]
#[derive(Parser)]
#[clap(version, about, long_about = None)]
struct Args {
@ -31,17 +32,25 @@ struct Args {
#[clap(short, long)]
td_are_tp: bool,
/// Number of weeks for the period
#[clap(short, long, value_parser)]
weeks: Option<i32>,
/// First day of your year
#[clap(short, long)]
#[clap(long)]
first_day: Option<String>,
/// If TD/TP start a week after courses
#[clap(short, long)]
#[clap(long)]
week_skip: bool,
/// If the exported ICS file should not use the timezone
#[clap(short, long)]
#[clap(long)]
no_tz: bool,
/// Guess the holidays and apply it to the generated calendar
#[clap(long)]
holidays: bool,
}
#[tokio::main]
@ -69,7 +78,7 @@ async fn main() {
let date = match args.first_day {
None => Input::new()
.with_prompt("Début des cours de l'année (première période)")
.with_prompt("Début des cours de la période")
.default(info::get_start_date(level, args.semester, args.year, &user_agent).await)
.interact_text()
.unwrap(),
@ -77,7 +86,14 @@ async fn main() {
};
println!("Récupération des informations par rapport à l'année...");
let info = info::info(args.semester, args.year, &date, args.week_skip);
let info = info::info(
args.semester,
args.year,
&date,
args.week_skip,
args.holidays,
args.weeks,
);
if let Some(mut filename) = args.export {
// Export the calendar

View file

@ -176,3 +176,18 @@ pub fn format_time_slot(start: usize, size: usize) -> String {
format!("{start_hour:02}h{start_minute:02}-{end_hour:02}h{end_minute:02}")
}
/// Based on the user input and some default values, find the correct repartition of weeks between the break
pub fn get_period_weeks(semester: i32, user_input: Option<i32>) -> (i64, i64) {
if let Some(nb_weeks) = user_input {
// When weeks are forced by the user, we simply cut the period in half
let half = nb_weeks / 2;
return (half.into(), (nb_weeks - half).into());
}
match semester {
1 => (6, 7),
2 => (11, 1),
_ => panic!("Weird semester"),
}
}