From f101168f8e9eb9546a38bbd3a1bf11809b665828 Mon Sep 17 00:00:00 2001 From: Matteo Settenvini Date: Fri, 12 Aug 2022 23:56:37 +0200 Subject: [PATCH] Allow specifying start date for grocery list --- src/commands/groceries.rs | 19 +++++++++++++++---- src/main.rs | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/commands/groceries.rs b/src/commands/groceries.rs index 5ee2536..3280340 100644 --- a/src/commands/groceries.rs +++ b/src/commands/groceries.rs @@ -5,7 +5,7 @@ use { crate::api_client::ApiClient, crate::recipe::{Ingredient, Recipe}, anyhow::{anyhow, Result}, - chrono::{Duration, Local}, + chrono::{Duration, Local, NaiveDate}, icalendar::Component, regex::Regex, reqwest::{Method, StatusCode, Url}, @@ -17,9 +17,10 @@ pub async fn with( api_client: &ApiClient, calendar_name: &str, location: &str, + start_date: Option, days: u32, ) -> Result<()> { - let ids = map_events_to_recipe_ids(api_client, calendar_name, days).await?; + 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)?; @@ -31,11 +32,21 @@ pub async fn with( async fn map_events_to_recipe_ids( api_client: &ApiClient, calendar_name: &str, + start_date: Option, days: u32, ) -> Result> { + use chrono::{NaiveDateTime, NaiveTime, TimeZone}; + + let start = start_date + .map(|d| { + let day_start = NaiveDateTime::new(d, NaiveTime::from_hms(0, 0, 0)); + Local.from_local_datetime(&day_start).unwrap() + }) + .unwrap_or_else(|| Local::now()); + let date_range = Range { - start: Local::now(), - end: Local::now() + Duration::days(days as i64), + start, + end: start + Duration::days(days as i64), }; let all_events = api_client.get_events(calendar_name, date_range).await?; diff --git a/src/main.rs b/src/main.rs index 68e8f23..d13d84a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,7 +49,9 @@ fn setup_args() -> ArgMatches { .arg(server_arg.clone()) .arg(arg!( "The name of the calendar to read from for scheduled recipes")) .arg(arg!( "The relative path for the Markdown file that will be saved on the server. Recommended ending it in '.md'.")) - .arg(arg!(-d --days "Number of days in the future to consider") + .arg(arg!(-f --from "A start date for recipes to consider, in the format YYYY-MM-DD") + .required(false)) + .arg(arg!(-d --days "Number of days in the future (from now or from the start date) to consider") .value_parser(clap::builder::RangedU64ValueParser::::new().range(1..)) .required(false) .default_value("7")) @@ -103,9 +105,20 @@ async fn parse_args(args: &ArgMatches) -> Result<()> { let calendar_name = sub_matches .get_one::("calendar_name") .expect(" is a mandatory parameter, it cannot be missing"); + let start_date = sub_matches + .get_one::("from") + .map(|s| chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d")) + .transpose()?; let days = sub_matches.get_one::("days").unwrap(); let filename = sub_matches.get_one::("filename").unwrap(); - commands::groceries::with(&api_client, calendar_name.as_str(), filename, *days).await + commands::groceries::with( + &api_client, + calendar_name.as_str(), + filename, + start_date, + *days, + ) + .await } Some(("schedule", sub_matches)) => { let api_client = get_api_client(&sub_matches, &configuration)?;