Add date range to grocery list

This commit is contained in:
Matteo Settenvini 2022-08-13 08:04:15 +02:00
parent f101168f8e
commit bbcb32b119
Signed by: matteo
GPG Key ID: 8576CC1AD97D42DF
2 changed files with 30 additions and 20 deletions

View File

@ -101,7 +101,7 @@ impl ApiClient {
pub async fn get_events<Tz>( pub async fn get_events<Tz>(
&self, &self,
calendar_name: &str, calendar_name: &str,
date_range: Range<DateTime<Tz>>, date_range: &Range<DateTime<Tz>>,
) -> Result<Vec<icalendar::Event>> ) -> Result<Vec<icalendar::Event>>
where where
Tz: chrono::TimeZone, Tz: chrono::TimeZone,

View File

@ -20,23 +20,7 @@ pub async fn with(
start_date: Option<NaiveDate>, start_date: Option<NaiveDate>,
days: u32, days: u32,
) -> Result<()> { ) -> Result<()> {
let ids = map_events_to_recipe_ids(api_client, calendar_name, start_date, days).await?;
let ingredients = get_ingredients(api_client, ids).await?;
let ingredients = merge_ingredients(ingredients);
let md = prepare_grocery_list(&ingredients)?;
log::debug!("Saving the following grocery list:\n\n{}", &md);
save_grocery_list(api_client, location, &md).await?;
Ok(())
}
async fn map_events_to_recipe_ids(
api_client: &ApiClient,
calendar_name: &str,
start_date: Option<NaiveDate>,
days: u32,
) -> Result<HashSet<usize>> {
use chrono::{NaiveDateTime, NaiveTime, TimeZone}; use chrono::{NaiveDateTime, NaiveTime, TimeZone};
let start = start_date let start = start_date
.map(|d| { .map(|d| {
let day_start = NaiveDateTime::new(d, NaiveTime::from_hms(0, 0, 0)); let day_start = NaiveDateTime::new(d, NaiveTime::from_hms(0, 0, 0));
@ -49,6 +33,24 @@ async fn map_events_to_recipe_ids(
end: start + Duration::days(days as i64), end: start + Duration::days(days as i64),
}; };
let ids = map_events_to_recipe_ids(api_client, calendar_name, &date_range).await?;
let ingredients = get_ingredients(api_client, ids).await?;
let ingredients = merge_ingredients(ingredients);
let md = prepare_grocery_list(&date_range, &ingredients)?;
log::debug!("Saving the following grocery list:\n\n{}", &md);
save_grocery_list(api_client, location, &md).await?;
Ok(())
}
async fn map_events_to_recipe_ids<Tz>(
api_client: &ApiClient,
calendar_name: &str,
date_range: &Range<chrono::DateTime<Tz>>,
) -> Result<HashSet<usize>>
where
Tz: chrono::TimeZone,
Tz::Offset: std::fmt::Display,
{
let all_events = api_client.get_events(calendar_name, date_range).await?; let all_events = api_client.get_events(calendar_name, date_range).await?;
let recipe_id_regex: Regex = Regex::new(r"^cookbook@(\d+)$").unwrap(); let recipe_id_regex: Regex = Regex::new(r"^cookbook@(\d+)$").unwrap();
@ -131,14 +133,22 @@ fn merge_ingredients(mut ingredients: Vec<(Ingredient, String)>) -> Vec<(Ingredi
merged_ingredients merged_ingredients
} }
fn prepare_grocery_list(ingredients: &Vec<(Ingredient, Vec<String>)>) -> Result<String> { fn prepare_grocery_list<Tz>(
date_range: &Range<chrono::DateTime<Tz>>,
ingredients: &Vec<(Ingredient, Vec<String>)>,
) -> Result<String>
where
Tz: chrono::TimeZone,
Tz::Offset: std::fmt::Display,
{
let mut out = String::new(); let mut out = String::new();
use std::fmt::Write; use std::fmt::Write;
writeln!( writeln!(
out, out,
"# Grocery list - {}", "# Grocery list\n## From {} to {}",
chrono::Local::now().format("%Y-%m-%d").to_string() date_range.start.date_naive(),
date_range.end.date_naive()
)?; )?;
writeln!(out)?; // leave an empty line writeln!(out)?; // leave an empty line
for (ingredient, recipes) in ingredients { for (ingredient, recipes) in ingredients {