Allow multiple urls which are split with a semicolon

This commit is contained in:
Jan-Henrik 2024-01-07 13:17:37 +01:00
parent 868d27a113
commit 35349b9d04

View file

@ -10,13 +10,14 @@ use serde::Serialize;
async fn handler(params: HashMap<String, String>) -> Result<impl Reply, Rejection> { async fn handler(params: HashMap<String, String>) -> Result<impl Reply, Rejection> {
match params.get("url") { match params.get("url") {
Some(url) => Ok(warp::reply::json(&convert(&url, params.get("days")).await.map_err(|_| warp::reject::reject())?.entries)), Some(url) => Ok(warp::reply::json(&convert(&[url], params.get("days")).await.map_err(|_| warp::reject::reject())?.entries)),
None => Err(warp::reject::reject()) None => Err(warp::reject::reject())
} }
} }
async fn new_handler(url: String, params: HashMap<String, String>) -> Result<impl Reply, Rejection> { async fn new_handler(url: String, params: HashMap<String, String>) -> Result<impl Reply, Rejection> {
Ok(warp::reply::json(&convert(&url, params.get("days")).await.map_err(|_| warp::reject::reject())?.entries)) let urls: Vec<&str> = url.split(";").collect();
Ok(warp::reply::json(&convert(&urls, params.get("days")).await.map_err(|_| warp::reject::reject())?.entries))
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -34,61 +35,63 @@ struct CustomCalendarEntry {
isallday: bool, isallday: bool,
} }
async fn convert(url: &str, days: Option<&String>) -> Result<CustomCalendar> { async fn convert(urls: &[&str], days: Option<&String>) -> Result<CustomCalendar> {
let url = urlencoding::decode(url)?.into_owned();
let ics_text = reqwest::get(url)
.await?
.text()
.await?;
let calendar = ics_text.parse::<Calendar>().map_err(|e| anyhow::Error::msg(e))?;
let mut entries = Vec::new(); let mut entries = Vec::new();
for url in urls {
let filter_start = chrono::Utc::now().date_naive().and_hms_opt(0, 0, 0).unwrap().and_utc(); let url = urlencoding::decode(url)?.into_owned();
let filter_end = filter_start + chrono::Duration::days(days.unwrap_or(&String::from("1")).parse().unwrap_or(1)); let ics_text = reqwest::get(url)
.await?
.text()
.await?;
let calendar = ics_text.parse::<Calendar>().map_err(|e| anyhow::Error::msg(e))?;
for event in calendar.components {
if let Some(event) = event.as_event() { let filter_start = chrono::Utc::now().date_naive().and_hms_opt(0, 0, 0).unwrap().and_utc();
let Some(start) = event.get_start() else { let filter_end = filter_start + chrono::Duration::days(days.unwrap_or(&String::from("1")).parse().unwrap_or(1));
println!("No start!");
continue;
};
let start = match convert_time(start) { for event in calendar.components {
Ok(t) => { t }, if let Some(event) = event.as_event() {
Err(e) => { let Some(start) = event.get_start() else {
println!("Invalid start timestamp: {:?}", e); println!("No start!");
continue;
};
let start = match convert_time(start) {
Ok(t) => { t },
Err(e) => {
println!("Invalid start timestamp: {:?}", e);
continue;
}
};
let end = match event.get_end() {
Some(end) => {
match convert_time(end) {
Ok(t) => { t },
Err(e) => {
println!("Invalid end timestamp: {:?}", e);
continue;
}
}
},
None => start + chrono::Duration::days(1),
};
if start < filter_start || start > filter_end {
continue; continue;
} }
};
let end = match event.get_end() { entries.push(CustomCalendarEntry {
Some(end) => { title: event.get_summary().unwrap_or("").to_string(),
match convert_time(end) { description: event.get_description().unwrap_or("").to_string(),
Ok(t) => { t }, location: event.get_location().unwrap_or("").to_string(),
Err(e) => { start: start.timestamp(),
println!("Invalid end timestamp: {:?}", e); end: end.timestamp(),
continue; isallday: start.time() == chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap() && end - start == chrono::Duration::days(1) // the event has a length of 24 hours and
} // starts at 00:00
} });
},
None => start + chrono::Duration::days(1),
};
if start < filter_start || start > filter_end {
continue;
} }
entries.push(CustomCalendarEntry {
title: event.get_summary().unwrap_or("").to_string(),
description: event.get_description().unwrap_or("").to_string(),
location: event.get_location().unwrap_or("").to_string(),
start: start.timestamp(),
end: end.timestamp(),
isallday: start.time() == chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap() && end - start == chrono::Duration::days(1) // the event has a length of 24 hours and
// starts at 00:00
});
} }
} }