From 64ce6e478b3ad18de749121465a8d37729343fe1 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Mon, 1 Jan 2024 13:47:23 +0100 Subject: [PATCH] support cours/td --- src/filter.rs | 13 +++++++++++-- src/ics.rs | 13 +++++++++++-- src/timetable.rs | 9 +++++---- src/timetable/models.rs | 4 +++- src/utils.rs | 6 +++++- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/filter.rs b/src/filter.rs index 655c70a..5319afe 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -12,6 +12,13 @@ const DISCLAIMER: &str = "(selection avec ESPACE, ENTRER pour valider)"; pub fn timetable(timetable: Timetable) -> Timetable { let mut my_timetable = timetable; + /* Note on Cours/TD: + * We use the "as long as x interests us, we accept" approach. + * + * Because when a course and its TD are on the same slot, + * it's probably because there's an alternation between course + * and TD and no other choice is possible. */ + choice(&mut my_timetable); courses(&mut my_timetable); tdtp(&mut my_timetable); @@ -84,7 +91,9 @@ fn courses(timetable: &mut Timetable) { day.courses.retain(|course_opt| { if let Some(course) = course_opt { // Keep if it's a TD/TP - if course.category == Category::TD || course.category == Category::TP { + if course.category.contains(&Category::TD) + || course.category.contains(&Category::TP) + { return true; } @@ -134,7 +143,7 @@ fn tdtp(timetable: &mut Timetable) { day.courses.retain(|course_opt| { if let Some(course) = course_opt { // Keep if it's a course - if course.category == Category::Cours { + if course.category.contains(&Category::Cours) { return true; } diff --git a/src/ics.rs b/src/ics.rs index c1cdb9f..f83a337 100644 --- a/src/ics.rs +++ b/src/ics.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use chrono::TimeZone; use ics::{ parameters, @@ -52,13 +54,20 @@ pub fn export(courses: Vec, filename: &mut Str // Room location event.push(Location::new(course.room)); + let categories = course + .category + .iter() + .map(|c| c.to_string()) + .collect::>() + .join("/"); + // Course's name - let mut course_name = Summary::new(format!("{} - {}", course.category, course.name)); + let mut course_name = Summary::new(format!("{} - {}", categories, course.name)); course_name.append(parameters!("LANGUAGE" => "fr")); event.push(course_name); // Course's category - event.push(Categories::new(course.category.to_string())); + event.push(Categories::new(categories)); // Add the course to the calendar calendar.add_event(event); diff --git a/src/timetable.rs b/src/timetable.rs index 5a6ae56..b7c0d2c 100644 --- a/src/timetable.rs +++ b/src/timetable.rs @@ -49,7 +49,7 @@ pub async fn timetable( .filter(|element| element.value().attr("title").is_some()) .for_each(|i| { let matches = - Regex::new(r"(?PCOURS|TD|TP) (?P.*) : (?P(lundi|mardi|mercredi|jeudi|vendredi)) (?P.*) \(durée : (?P.*)\)") + Regex::new(r"(?PCOURS|TD|TP|COURS_TD) (?P.*) : (?P(lundi|mardi|mercredi|jeudi|vendredi)) (?P.*) \(durée : (?P.*)\)") .unwrap() .captures(i.value().attr("title").unwrap()) .unwrap(); @@ -71,9 +71,10 @@ pub async fn timetable( .name("type") .unwrap() .as_str() { - "COURS" => models::Category::Cours, - "TP" => models::Category::TP, - "TD" => models::Category::TD, + "COURS" => [models::Category::Cours].into(), + "TP" => [models::Category::TP].into(), + "TD" => [models::Category::TD].into(), + "COURS_TD" => [models::Category::Cours, models::Category::TD].into(), _ => panic!("Unknown type of course") }, name: matches diff --git a/src/timetable/models.rs b/src/timetable/models.rs index b3c567d..4ad20c4 100644 --- a/src/timetable/models.rs +++ b/src/timetable/models.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + #[derive(Clone, Debug, PartialEq)] pub enum Category { Cours, @@ -14,7 +16,7 @@ impl std::fmt::Display for Category { #[derive(Clone, Debug, PartialEq)] pub struct Course { /// Type du cours - pub category: Category, + pub category: Arc<[Category]>, /// Course's name pub name: String, diff --git a/src/utils.rs b/src/utils.rs index afb56a6..2294491 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -232,7 +232,11 @@ pub fn get_count<'a>( timetable.1 .1.iter().for_each(|day| { day.courses.iter().for_each(|course_opt| { if let Some(course) = course_opt { - if allowed_list.contains(&course.category) { + if course + .category + .iter() + .any(|category| allowed_list.contains(category)) + { courses.push((course, day.name.to_owned())); let count = counts.entry(get_entry(course)).or_insert(0); *count += 1;