This repository has been archived on 2024-05-23. You can view files and clone it, but cannot push or open issues or pull requests.
cal8tor/src/ics.rs

77 lines
2.3 KiB
Rust
Raw Normal View History

2022-08-16 17:56:24 +02:00
use chrono::TimeZone;
2022-08-16 10:32:46 +02:00
use ics::{
2022-08-16 17:56:24 +02:00
parameters,
2022-08-16 10:32:46 +02:00
properties::{Class, Description, DtEnd, DtStart, Location, Summary, Transp},
2022-08-16 17:56:24 +02:00
Event, ICalendar, Standard,
2022-08-16 10:32:46 +02:00
};
pub fn export(courses: Vec<crate::timetable::models::Course>, filename: String) {
2022-08-16 10:32:46 +02:00
let mut calendar = ICalendar::new("2.0", "cal8tor");
2022-08-16 17:56:24 +02:00
// Add Europe/Paris timezone
let timezone_name = "Europe/Paris";
calendar.add_timezone(ics::TimeZone::standard(
timezone_name,
Standard::new(
// Add a Z because it's UTC
dt_ical(chrono::Utc.ymd(1970, 1, 1).and_hms(0, 0, 0)) + "Z",
2022-08-16 17:56:24 +02:00
"+0100",
"+0200",
),
));
2022-08-16 11:54:47 +02:00
// Create events which contains the information regarding the course
for course in courses {
2022-08-16 14:40:55 +02:00
let mut event = Event::new(
uuid::Uuid::new_v4().to_string(),
// Add a Z because it's UTC
dt_ical(chrono::Utc::now()) + "Z",
2022-08-16 14:40:55 +02:00
);
2022-08-16 10:32:46 +02:00
2022-08-16 11:54:47 +02:00
// Public event
event.push(Class::public());
2022-08-16 14:22:04 +02:00
2022-08-16 11:54:47 +02:00
// Consume actual time
event.push(Transp::opaque());
2022-08-16 14:22:04 +02:00
2022-08-16 11:54:47 +02:00
// Professor's name
2022-08-16 14:06:58 +02:00
if course.professor.is_some() {
event.push(Description::new(course.professor.unwrap()));
}
2022-08-16 14:22:04 +02:00
2022-08-16 11:54:47 +02:00
// Start time of the course
2022-08-16 17:56:24 +02:00
let mut date_start = DtStart::new(dt_ical(course.dtstart.unwrap()));
date_start.append(parameters!("TZID" => timezone_name));
event.push(date_start);
2022-08-16 14:22:04 +02:00
2022-08-16 11:54:47 +02:00
// End time of the course
2022-08-16 17:56:24 +02:00
let mut date_end = DtEnd::new(dt_ical(course.dtend.unwrap()));
date_end.append(parameters!("TZID" => timezone_name));
event.push(date_end);
2022-08-16 14:22:04 +02:00
2022-08-16 11:54:47 +02:00
// Room location
event.push(Location::new(course.room));
2022-08-16 14:22:04 +02:00
2022-08-16 11:54:47 +02:00
// Course's name
let mut course_name = Summary::new(course.name);
course_name.append(parameters!("LANGUAGE" => "fr"));
event.push(course_name);
2022-08-16 10:32:46 +02:00
2022-08-16 11:54:47 +02:00
// Add the course to the calendar
calendar.add_event(event);
}
2022-08-16 10:32:46 +02:00
2022-08-17 14:38:31 +02:00
calendar
.save_file(match filename {
2022-08-17 14:38:31 +02:00
x if x.ends_with(".ics") => x,
x => format!("{}.ics", x),
})
.unwrap();
2022-08-16 10:32:46 +02:00
}
2022-08-16 11:54:47 +02:00
/// Transform the datetime from chrono to the ICS format
2022-08-16 12:16:23 +02:00
/// See <https://github.com/hummingly/ics/issues/17#issue-985662287>
2022-08-16 11:54:47 +02:00
fn dt_ical(dt: chrono::DateTime<chrono::Utc>) -> String {
2022-08-16 17:56:24 +02:00
format!("{}", dt.format("%Y%m%dT%H%M%S"))
2022-08-16 11:54:47 +02:00
}