Fix outputting tzid and alarm trigger

This commit is contained in:
Matteo Settenvini 2022-07-29 19:52:50 +02:00
parent 096db12c74
commit 77404d1642
Signed by: matteo
GPG key ID: 8576CC1AD97D42DF
7 changed files with 117 additions and 78 deletions

View file

@ -2,18 +2,21 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
use {
crate::config::Config, crate::constants, anyhow::anyhow,
crate::config::Config, crate::constants, anyhow::anyhow, anyhow::Result,
base64::write::EncoderWriter as Base64Encoder, reqwest::Url, std::io::Write,
};
pub struct ApiClient {
pub base_url: Url,
pub username: String,
pub rest: reqwest::Client,
rest: reqwest::Client,
agent: ureq::Agent,
base_url: Url,
caldav_base_url: Url,
username: String,
password: String,
}
impl ApiClient {
pub fn new(server_name: &str, configuration: &Config) -> anyhow::Result<Self> {
pub fn new(server_name: &str, configuration: &Config) -> Result<Self> {
let server = configuration
.credentials
.servers
@ -43,10 +46,58 @@ impl ApiClient {
.default_headers(default_headers)
.build()?;
let base_url = Url::parse(&server.url)?;
let caldav_base_url = futures::executor::block_on(
rest_client
.head(base_url.join("/.well-known/caldav")?)
.send(),
)?
.url()
.clone();
Ok(ApiClient {
base_url: Url::parse(&server.url)?,
base_url,
caldav_base_url,
username: server.login_name.clone(),
password: server.password.clone(),
rest: rest_client,
agent: ureq::Agent::new(),
})
}
pub fn rest(&self) -> &reqwest::Client {
&self.rest
}
pub fn base_url(&self) -> &Url {
&self.base_url
}
pub fn username(&self) -> &str {
&self.username
}
pub fn get_calendars(
&self,
) -> core::result::Result<Vec<minicaldav::Calendar>, minicaldav::Error> {
minicaldav::get_calendars(
self.agent.clone(),
self.username(),
&self.password,
&self.caldav_base_url,
)
}
pub fn get_events(
&self,
calendar: &minicaldav::Calendar,
) -> core::result::Result<(Vec<minicaldav::Event>, Vec<minicaldav::Error>), minicaldav::Error>
{
minicaldav::get_events(
self.agent.clone(),
self.username(),
&self.password,
calendar,
)
}
}

View file

@ -10,8 +10,8 @@ where
{
for url in urls {
let response = api_client
.rest
.post(api_client.base_url.join("apps/cookbook/import")?)
.rest()
.post(api_client.base_url().join("apps/cookbook/import")?)
.json(&serde_json::json!({
"url": url.as_ref(),
}))

View file

@ -5,8 +5,8 @@ use {crate::api_client::ApiClient, crate::recipe, anyhow::Result};
pub async fn with(api_client: &ApiClient) -> Result<()> {
let recipes = api_client
.rest
.get(api_client.base_url.join("apps/cookbook/api/recipes")?)
.rest()
.get(api_client.base_url().join("apps/cookbook/api/recipes")?)
.send()
.await?;
println!("{:#?}", recipes.json::<Vec<recipe::Metadata>>().await?);

View file

@ -71,8 +71,8 @@ where
async fn get_all_recipes(api_client: &ApiClient) -> Result<HashMap<String, Rc<recipe::Recipe>>> {
let metadata = api_client
.rest
.get(api_client.base_url.join("apps/cookbook/api/recipes")?)
.rest()
.get(api_client.base_url().join("apps/cookbook/api/recipes")?)
.send()
.await?
.json::<Vec<recipe::Metadata>>()
@ -80,10 +80,10 @@ async fn get_all_recipes(api_client: &ApiClient) -> Result<HashMap<String, Rc<re
let recipes = metadata.iter().map(|rm| async {
let response = api_client
.rest
.rest()
.get(
api_client
.base_url
.base_url()
.join(&format!("apps/cookbook/api/recipes/{id}", id = rm.id))
.unwrap(),
)
@ -113,21 +113,22 @@ where
let calendar_prototype: ics::ICalendar = ics::ICalendar::new(
"2.0",
format!(
"-//{}//NONSGML {}//EN",
"-//IDN {}//{} {}//EN",
constants::VENDOR,
env!("CARGO_PKG_NAME")
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION")
),
);
let dav_base = api_client
.rest
.head(api_client.base_url.join("/.well-known/caldav")?)
.rest()
.head(api_client.base_url().join("/.well-known/caldav")?)
.send()
.await?;
let calendar_url = dav_base.url().join(&format!(
"calendars/{}/{}/",
&api_client.username,
&api_client.username(),
calendar.to_lowercase().as_str().replace(" ", "-")
))?;
@ -139,7 +140,7 @@ where
cal.add_event(ev.into());
api_client
.rest
.rest()
.put(url)
.header("Content-Type", "text/calendar; charset=utf-8")
.body(cal.to_string())

View file

@ -48,7 +48,11 @@ impl Event {
impl<'a> From<Event> for CalEvent<'a> {
fn from(ev: Event) -> Self {
let start_time = ev.ends_at - ev.recipe.total_time();
let start_time = Local
.from_local_datetime(&(*&ev.ends_at - ev.recipe.total_time()))
.unwrap();
let end_time = Local.from_local_datetime(&ev.ends_at).unwrap();
let timezone = iana_time_zone::get_timezone().unwrap();
let mut event = ics::Event::new(ev.uid.clone(), dt_utc_fmt(&Utc::now()));
event.push(calprop::Summary::new(escape_text(ev.recipe.name.clone())));
@ -57,18 +61,22 @@ impl<'a> From<Event> for CalEvent<'a> {
ev.recipe.id
)));
event.push(calprop::Location::new(escape_text(ev.recipe.url.clone())));
event.push(calprop::DtStart::new(dt_fmt(
&Local.from_local_datetime(&start_time).unwrap(),
)));
event.push(calprop::DtEnd::new(dt_fmt(
&Local.from_local_datetime(&ev.ends_at).unwrap(),
)));
let mut dtstart = calprop::DtStart::new(dt_fmt(&start_time));
dtstart.append(ics::parameters!("TZID" => timezone.clone()));
event.push(dtstart);
let mut dtend = calprop::DtEnd::new(dt_fmt(&end_time));
dtend.append(ics::parameters!("TZID" => timezone));
event.push(dtend);
// TODO make configurable yearly repetition, for now this suits my personal uses
event.push(calprop::RRule::new("FREQ=YEARLY"));
let mut trigger = calprop::Trigger::new("-PT15M");
trigger.append(ics::parameters!("RELATED" => "START"));
let alarm = ics::Alarm::display(
calprop::Trigger::new("-P15M"),
trigger,
calprop::Description::new(escape_text(ev.recipe.name.clone())),
);
event.add_alarm(alarm);