Allow specifying start date for grocery list

This commit is contained in:
Matteo Settenvini 2022-08-12 23:56:37 +02:00
parent 63860cd05a
commit f101168f8e
Signed by: matteo
GPG Key ID: 8576CC1AD97D42DF
2 changed files with 30 additions and 6 deletions

View File

@ -5,7 +5,7 @@ use {
crate::api_client::ApiClient, crate::api_client::ApiClient,
crate::recipe::{Ingredient, Recipe}, crate::recipe::{Ingredient, Recipe},
anyhow::{anyhow, Result}, anyhow::{anyhow, Result},
chrono::{Duration, Local}, chrono::{Duration, Local, NaiveDate},
icalendar::Component, icalendar::Component,
regex::Regex, regex::Regex,
reqwest::{Method, StatusCode, Url}, reqwest::{Method, StatusCode, Url},
@ -17,9 +17,10 @@ pub async fn with(
api_client: &ApiClient, api_client: &ApiClient,
calendar_name: &str, calendar_name: &str,
location: &str, location: &str,
start_date: Option<NaiveDate>,
days: u32, days: u32,
) -> Result<()> { ) -> 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 = get_ingredients(api_client, ids).await?;
let ingredients = merge_ingredients(ingredients); let ingredients = merge_ingredients(ingredients);
let md = prepare_grocery_list(&ingredients)?; let md = prepare_grocery_list(&ingredients)?;
@ -31,11 +32,21 @@ pub async fn with(
async fn map_events_to_recipe_ids( async fn map_events_to_recipe_ids(
api_client: &ApiClient, api_client: &ApiClient,
calendar_name: &str, calendar_name: &str,
start_date: Option<NaiveDate>,
days: u32, days: u32,
) -> Result<HashSet<usize>> { ) -> Result<HashSet<usize>> {
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 { let date_range = Range {
start: Local::now(), start,
end: Local::now() + Duration::days(days as i64), end: start + Duration::days(days as i64),
}; };
let all_events = api_client.get_events(calendar_name, date_range).await?; let all_events = api_client.get_events(calendar_name, date_range).await?;

View File

@ -49,7 +49,9 @@ fn setup_args() -> ArgMatches {
.arg(server_arg.clone()) .arg(server_arg.clone())
.arg(arg!(<calendar_name> "The name of the calendar to read from for scheduled recipes")) .arg(arg!(<calendar_name> "The name of the calendar to read from for scheduled recipes"))
.arg(arg!(<filename> "The relative path for the Markdown file that will be saved on the server. Recommended ending it in '.md'.")) .arg(arg!(<filename> "The relative path for the Markdown file that will be saved on the server. Recommended ending it in '.md'."))
.arg(arg!(-d --days <days> "Number of days in the future to consider") .arg(arg!(-f --from <date> "A start date for recipes to consider, in the format YYYY-MM-DD")
.required(false))
.arg(arg!(-d --days <days> "Number of days in the future (from now or from the start date) to consider")
.value_parser(clap::builder::RangedU64ValueParser::<u32>::new().range(1..)) .value_parser(clap::builder::RangedU64ValueParser::<u32>::new().range(1..))
.required(false) .required(false)
.default_value("7")) .default_value("7"))
@ -103,9 +105,20 @@ async fn parse_args(args: &ArgMatches) -> Result<()> {
let calendar_name = sub_matches let calendar_name = sub_matches
.get_one::<String>("calendar_name") .get_one::<String>("calendar_name")
.expect("<calendar_name> is a mandatory parameter, it cannot be missing"); .expect("<calendar_name> is a mandatory parameter, it cannot be missing");
let start_date = sub_matches
.get_one::<String>("from")
.map(|s| chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d"))
.transpose()?;
let days = sub_matches.get_one::<u32>("days").unwrap(); let days = sub_matches.get_one::<u32>("days").unwrap();
let filename = sub_matches.get_one::<String>("filename").unwrap(); let filename = sub_matches.get_one::<String>("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)) => { Some(("schedule", sub_matches)) => {
let api_client = get_api_client(&sub_matches, &configuration)?; let api_client = get_api_client(&sub_matches, &configuration)?;