Fix outputting tzid and alarm trigger
This commit is contained in:
parent
096db12c74
commit
77404d1642
7 changed files with 117 additions and 78 deletions
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
}))
|
||||
|
|
|
@ -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?);
|
||||
|
|
|
@ -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())
|
||||
|
|
24
src/event.rs
24
src/event.rs
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue