Save back markdown file to server
This commit is contained in:
parent
1510eb4f3d
commit
e1b6017f06
2 changed files with 70 additions and 9 deletions
|
@ -1,26 +1,32 @@
|
|||
use reqwest::Method;
|
||||
|
||||
// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use {
|
||||
crate::api_client::ApiClient,
|
||||
crate::recipe::{Ingredient, Recipe},
|
||||
anyhow::Result,
|
||||
anyhow::{anyhow, Result},
|
||||
chrono::{Duration, Local},
|
||||
icalendar::Component,
|
||||
regex::Regex,
|
||||
reqwest::StatusCode,
|
||||
std::collections::HashSet,
|
||||
std::ops::Range,
|
||||
};
|
||||
|
||||
pub async fn with(api_client: &ApiClient, calendar_name: &str, days: u32) -> Result<()> {
|
||||
pub async fn with(
|
||||
api_client: &ApiClient,
|
||||
calendar_name: &str,
|
||||
location: &str,
|
||||
days: u32,
|
||||
) -> Result<()> {
|
||||
let ids = map_events_to_recipe_ids(api_client, calendar_name, days).await?;
|
||||
let ingredients = get_ingredients(api_client, ids).await?;
|
||||
let ingredients = merge_ingredients(ingredients);
|
||||
let md = prepare_grocery_list(&ingredients)?;
|
||||
|
||||
println!("{}", md);
|
||||
|
||||
// save_grocery_list(api_client, "", md).await?;
|
||||
// TODO filename is hardcoded for now
|
||||
save_grocery_list(api_client, location, &md).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -89,10 +95,63 @@ fn prepare_grocery_list(ingredients: &Vec<Ingredient>) -> Result<String> {
|
|||
"# Grocery list - {}",
|
||||
chrono::Local::now().format("%Y-%m-%d").to_string()
|
||||
)?;
|
||||
writeln!(out)?; // leave an empty line
|
||||
for ingredient in ingredients {
|
||||
let ingredient = ingredient.0.as_str();
|
||||
writeln!(out, "* {}", ingredient)?;
|
||||
writeln!(out, "- [ ] {}", ingredient)?;
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
async fn save_grocery_list(api_client: &ApiClient, filename: &str, contents: &str) -> Result<()> {
|
||||
let dav_base_url = api_client
|
||||
.base_url()
|
||||
.join(&format!("remote.php/dav/files/{}/", api_client.username()))?;
|
||||
|
||||
let filename_components = filename.split('/').collect::<Vec<_>>();
|
||||
filename_components
|
||||
.iter()
|
||||
.take(filename_components.len() - 1)
|
||||
.fold(Ok(dav_base_url.clone()), |url, dir| {
|
||||
url.map(|u| u.join(&format!("{dir}/")).unwrap())
|
||||
.and_then(|url| {
|
||||
futures::executor::block_on(async {
|
||||
let response = api_client
|
||||
.rest()
|
||||
.request(Method::from_bytes(b"MKCOL").unwrap(), url.clone())
|
||||
.send()
|
||||
.await;
|
||||
|
||||
match response.map(|r| r.status()) {
|
||||
Ok(StatusCode::OK)
|
||||
| Ok(StatusCode::METHOD_NOT_ALLOWED /* already exists */) => Ok(url),
|
||||
Ok(status) => Err(anyhow!(
|
||||
"Could not create WebDAV collection {}, server responded with {}",
|
||||
&url,
|
||||
status
|
||||
)),
|
||||
Err(e) => Err(anyhow!(e)),
|
||||
}
|
||||
})
|
||||
})
|
||||
})?;
|
||||
|
||||
let file_url = dav_base_url.join(filename).unwrap();
|
||||
let response = api_client
|
||||
.rest()
|
||||
.put(file_url.clone())
|
||||
.header("Content-Type", "text/markdown; charset=utf-8")
|
||||
.body(contents.to_owned())
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
match response.status() {
|
||||
StatusCode::CREATED | StatusCode::NO_CONTENT => Ok(()),
|
||||
status => Err(anyhow!(
|
||||
"Cannot save grocery list at {}, server responded with status {}",
|
||||
file_url,
|
||||
status
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue