support cours/td

This commit is contained in:
Mylloon 2024-01-01 13:47:23 +01:00
parent 862c02b3e7
commit 64ce6e478b
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
5 changed files with 35 additions and 10 deletions

View file

@ -12,6 +12,13 @@ const DISCLAIMER: &str = "(selection avec ESPACE, ENTRER pour valider)";
pub fn timetable(timetable: Timetable) -> Timetable { pub fn timetable(timetable: Timetable) -> Timetable {
let mut my_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); choice(&mut my_timetable);
courses(&mut my_timetable); courses(&mut my_timetable);
tdtp(&mut my_timetable); tdtp(&mut my_timetable);
@ -84,7 +91,9 @@ fn courses(timetable: &mut Timetable) {
day.courses.retain(|course_opt| { day.courses.retain(|course_opt| {
if let Some(course) = course_opt { if let Some(course) = course_opt {
// Keep if it's a TD/TP // 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; return true;
} }
@ -134,7 +143,7 @@ fn tdtp(timetable: &mut Timetable) {
day.courses.retain(|course_opt| { day.courses.retain(|course_opt| {
if let Some(course) = course_opt { if let Some(course) = course_opt {
// Keep if it's a course // Keep if it's a course
if course.category == Category::Cours { if course.category.contains(&Category::Cours) {
return true; return true;
} }

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
use chrono::TimeZone; use chrono::TimeZone;
use ics::{ use ics::{
parameters, parameters,
@ -52,13 +54,20 @@ pub fn export(courses: Vec<crate::timetable::models::Course>, filename: &mut Str
// Room location // Room location
event.push(Location::new(course.room)); event.push(Location::new(course.room));
let categories = course
.category
.iter()
.map(|c| c.to_string())
.collect::<Arc<[String]>>()
.join("/");
// Course's name // 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")); course_name.append(parameters!("LANGUAGE" => "fr"));
event.push(course_name); event.push(course_name);
// Course's category // Course's category
event.push(Categories::new(course.category.to_string())); event.push(Categories::new(categories));
// Add the course to the calendar // Add the course to the calendar
calendar.add_event(event); calendar.add_event(event);

View file

@ -49,7 +49,7 @@ pub async fn timetable(
.filter(|element| element.value().attr("title").is_some()) .filter(|element| element.value().attr("title").is_some())
.for_each(|i| { .for_each(|i| {
let matches = let matches =
Regex::new(r"(?P<type>COURS|TD|TP) (?P<name>.*) : (?P<day>(lundi|mardi|mercredi|jeudi|vendredi)) (?P<startime>.*) \(durée : (?P<duration>.*)\)") Regex::new(r"(?P<type>COURS|TD|TP|COURS_TD) (?P<name>.*) : (?P<day>(lundi|mardi|mercredi|jeudi|vendredi)) (?P<startime>.*) \(durée : (?P<duration>.*)\)")
.unwrap() .unwrap()
.captures(i.value().attr("title").unwrap()) .captures(i.value().attr("title").unwrap())
.unwrap(); .unwrap();
@ -71,9 +71,10 @@ pub async fn timetable(
.name("type") .name("type")
.unwrap() .unwrap()
.as_str() { .as_str() {
"COURS" => models::Category::Cours, "COURS" => [models::Category::Cours].into(),
"TP" => models::Category::TP, "TP" => [models::Category::TP].into(),
"TD" => models::Category::TD, "TD" => [models::Category::TD].into(),
"COURS_TD" => [models::Category::Cours, models::Category::TD].into(),
_ => panic!("Unknown type of course") _ => panic!("Unknown type of course")
}, },
name: matches name: matches

View file

@ -1,3 +1,5 @@
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum Category { pub enum Category {
Cours, Cours,
@ -14,7 +16,7 @@ impl std::fmt::Display for Category {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Course { pub struct Course {
/// Type du cours /// Type du cours
pub category: Category, pub category: Arc<[Category]>,
/// Course's name /// Course's name
pub name: String, pub name: String,

View file

@ -232,7 +232,11 @@ pub fn get_count<'a>(
timetable.1 .1.iter().for_each(|day| { timetable.1 .1.iter().for_each(|day| {
day.courses.iter().for_each(|course_opt| { day.courses.iter().for_each(|course_opt| {
if let Some(course) = 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())); courses.push((course, day.name.to_owned()));
let count = counts.entry(get_entry(course)).or_insert(0); let count = counts.entry(get_entry(course)).or_insert(0);
*count += 1; *count += 1;