nextcloud-cooking-schedule/src/api_client.rs

104 lines
3.0 KiB
Rust
Raw Normal View History

// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: AGPL-3.0-or-later
use {
2022-07-29 19:52:50 +02:00
crate::config::Config, crate::constants, anyhow::anyhow, anyhow::Result,
base64::write::EncoderWriter as Base64Encoder, reqwest::Url, std::io::Write,
};
pub struct ApiClient {
2022-07-29 19:52:50 +02:00
rest: reqwest::Client,
agent: ureq::Agent,
base_url: Url,
caldav_base_url: Url,
username: String,
password: String,
}
impl ApiClient {
2022-07-29 19:52:50 +02:00
pub fn new(server_name: &str, configuration: &Config) -> Result<Self> {
let server = configuration
.credentials
.servers
.get(server_name)
.ok_or_else(|| {
anyhow!(
"Unknown server {}. Did you use '{} init' first? Known servers: {:#?}",
server_name,
env!("CARGO_BIN_NAME"),
configuration.credentials.servers.keys().collect::<Vec<_>>()
)
})?;
use reqwest::header;
let mut default_headers = header::HeaderMap::new();
let mut auth_header = b"Basic ".to_vec();
{
let mut encoder = Base64Encoder::new(&mut auth_header, base64::STANDARD);
write!(encoder, "{}:{}", server.login_name, server.password).unwrap();
}
let mut auth_header = header::HeaderValue::from_bytes(&auth_header)?;
auth_header.set_sensitive(true);
default_headers.insert(header::AUTHORIZATION, auth_header);
let rest_client = reqwest::Client::builder()
.user_agent(constants::USER_AGENT)
.default_headers(default_headers)
.build()?;
2022-07-29 19:52:50 +02:00
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 {
2022-07-29 19:52:50 +02:00
base_url,
caldav_base_url,
username: server.login_name.clone(),
2022-07-29 19:52:50 +02:00
password: server.password.clone(),
rest: rest_client,
2022-07-29 19:52:50 +02:00
agent: ureq::Agent::new(),
})
}
2022-07-29 19:52:50 +02:00
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,
)
}
}