155 lines
4.8 KiB
Rust
155 lines
4.8 KiB
Rust
use std::io::Write;
|
|
|
|
use ics::{
|
|
components::Property,
|
|
properties::{DtEnd, DtStart, Summary},
|
|
ICalendar,
|
|
};
|
|
use sqlx::SqlitePool;
|
|
|
|
use crate::model::{event::Event, trip::Trip, user::User};
|
|
use chrono::{Duration, NaiveTime};
|
|
|
|
pub(crate) async fn get_personal_cal(db: &SqlitePool, user: &User) -> String {
|
|
let mut calendar = ICalendar::new("2.0", "ics-rs");
|
|
calendar.push(Property::new(
|
|
"X-WR-CALNAME",
|
|
"Donau Linz - Deine Ausfahrten",
|
|
));
|
|
|
|
let events = Event::all_with_user(db, user).await;
|
|
for event in events {
|
|
calendar.add_event(event.get_vevent(db).await);
|
|
}
|
|
|
|
let trips = Trip::all_with_user(db, user).await;
|
|
for trip in trips {
|
|
calendar.add_event(trip.get_vevent(db, user).await);
|
|
}
|
|
let mut buf = Vec::new();
|
|
write!(&mut buf, "{}", calendar).unwrap();
|
|
String::from_utf8(buf).unwrap()
|
|
}
|
|
|
|
impl Trip {
|
|
pub(crate) async fn get_vevent<'a>(self, db: &'a SqlitePool, user: &'a User) -> ics::Event<'a> {
|
|
let mut vevent =
|
|
ics::Event::new(format!("trip-{}@rudernlinz.at", self.id), "19900101T180000");
|
|
let time_str = self.planned_starting_time.replace(':', "");
|
|
let formatted_time = if time_str.len() == 3 {
|
|
format!("0{}", time_str)
|
|
} else {
|
|
time_str
|
|
};
|
|
|
|
vevent.push(DtStart::new(format!(
|
|
"{}T{}00",
|
|
self.day.replace('-', ""),
|
|
formatted_time
|
|
)));
|
|
|
|
let original_time = NaiveTime::parse_from_str(&self.planned_starting_time, "%H:%M")
|
|
.expect("Failed to parse time");
|
|
let long_trip = match self.trip_type(db).await {
|
|
Some(a) if a.name == "Lange Ausfahrt" => true,
|
|
_ => false,
|
|
};
|
|
let later_time = if long_trip {
|
|
original_time + Duration::hours(6)
|
|
} else {
|
|
original_time + Duration::hours(3)
|
|
};
|
|
if later_time > original_time {
|
|
// Check if no day-overflow
|
|
let time_three_hours_later = later_time.format("%H%M").to_string();
|
|
vevent.push(DtEnd::new(format!(
|
|
"{}T{}00",
|
|
self.day.replace('-', ""),
|
|
time_three_hours_later
|
|
)));
|
|
}
|
|
|
|
let mut name = String::new();
|
|
if self.is_cancelled() {
|
|
name.push_str("ABGESAGT");
|
|
if let Some(notes) = &self.notes {
|
|
if !notes.is_empty() {
|
|
name.push_str(&format!(" (Grund: {notes})"))
|
|
}
|
|
}
|
|
|
|
name.push_str("! :-( ");
|
|
}
|
|
if self.cox_id == user.id {
|
|
name.push_str("Ruderausfahrt (selber ausgeschrieben)");
|
|
} else {
|
|
name.push_str(&format!("Ruderausfahrt mit {} ", self.cox_name));
|
|
}
|
|
|
|
vevent.push(Summary::new(name));
|
|
vevent
|
|
}
|
|
}
|
|
|
|
impl Event {
|
|
pub(crate) async fn get_vevent(self, db: &SqlitePool) -> ics::Event {
|
|
let mut vevent = ics::Event::new(
|
|
format!("event-{}@rudernlinz.at", self.id),
|
|
"19900101T180000",
|
|
);
|
|
let time_str = self.planned_starting_time.replace(':', "");
|
|
let formatted_time = if time_str.len() == 3 {
|
|
format!("0{}", time_str)
|
|
} else {
|
|
time_str.clone() // TODO: remove again
|
|
};
|
|
vevent.push(DtStart::new(format!(
|
|
"{}T{}00",
|
|
self.day.replace('-', ""),
|
|
formatted_time
|
|
)));
|
|
|
|
let original_time = NaiveTime::parse_from_str(&self.planned_starting_time, "%H:%M")
|
|
.expect("Failed to parse time");
|
|
|
|
let long_trip = match self.trip_type(db).await {
|
|
Some(a) if a.name == "Lange Ausfahrt" => true,
|
|
_ => false,
|
|
};
|
|
let later_time = if long_trip {
|
|
original_time + Duration::hours(6)
|
|
} else {
|
|
original_time + Duration::hours(3)
|
|
};
|
|
if later_time > original_time {
|
|
// Check if no day-overflow
|
|
let time_three_hours_later = later_time.format("%H%M").to_string();
|
|
vevent.push(DtEnd::new(format!(
|
|
"{}T{}00",
|
|
self.day.replace('-', ""),
|
|
time_three_hours_later
|
|
)));
|
|
}
|
|
|
|
let tripdetails = self.trip_details(db).await;
|
|
let mut name = String::new();
|
|
if self.is_cancelled() {
|
|
name.push_str("ABGESAGT");
|
|
if let Some(notes) = &tripdetails.notes {
|
|
if !notes.is_empty() {
|
|
name.push_str(&format!(" (Grund: {notes})"))
|
|
}
|
|
}
|
|
|
|
name.push_str("! :-( ");
|
|
}
|
|
name.push_str(&format!("{} ", self.name));
|
|
|
|
if let Some(triptype) = tripdetails.triptype(db).await {
|
|
name.push_str(&format!("• {} ", triptype.name))
|
|
}
|
|
vevent.push(Summary::new(name));
|
|
vevent
|
|
}
|
|
}
|