diff options
| author | Joris | 2024-11-17 13:00:35 +0100 | 
|---|---|---|
| committer | Joris | 2024-11-17 13:00:35 +0100 | 
| commit | fbe6787acb3c844339e34c3bf4509c36281693e6 (patch) | |
| tree | 20f6d2147b18324ce2b6ba9b40e7757ec1cf9c28 | |
| parent | 0fad55124684989ec9fd9a742b5731359d0238ce (diff) | |
Add --start-between CLI option
| -rw-r--r-- | src/cli/mod.rs | 66 | ||||
| -rw-r--r-- | src/main.rs | 13 | ||||
| -rw-r--r-- | src/model/event.rs | 9 | 
3 files changed, 77 insertions, 11 deletions
| diff --git a/src/cli/mod.rs b/src/cli/mod.rs index b952a75..e7439b5 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,21 +1,71 @@  use anyhow::Result; -use chrono::Local; +use chrono::{Local, NaiveDate, NaiveDateTime, TimeZone};  use rusqlite::Connection;  use crate::{db, model::event}; +use crate::model::event::Event;  pub fn today(conn: &Connection) -> Result<String> {      let today = Local::now().date_naive(); -    let mut events = db::events::list_non_recurring_between(conn, today, today)?; +    let events = between_inclusive(conn, today, today)?; +    Ok(format_events(events)) +} + +pub fn parse_timestamp_range(s: String) -> Option<(NaiveDateTime, NaiveDateTime)> { +    match s.split("..").collect::<Vec<&str>>()[..] { +        [from, to] => { +            let from = from.parse().ok()?; +            let to = to.parse().ok()?; + +            let from = Local.timestamp_opt(from, 0).single()?; +            let to = Local.timestamp_opt(to, 0).single()?; + +            Some((from.naive_local(), to.naive_local())) +        } +        _ => None, +    } +} + +pub fn start_between(conn: &Connection, from: NaiveDateTime, to: NaiveDateTime) -> Result<String> { +    let from_date = from.date(); +    let to_date = to.date(); +    let events = between_inclusive(conn, from_date, to_date)?; +    println!("{events:?}"); +    let events: Vec<Event> = events +        .iter() +        .filter(|e| { +            match e.start { +                None => false, +                Some(t) => { +                    let dt = NaiveDateTime::new(e.date, t); +                    dt >= from && dt < to +                } +            } +        }) +        .map(|e| e.clone()) +        .collect::<Vec<Event>>(); +    Ok(format_events(events)) +} + +fn between_inclusive(conn: &Connection, from: NaiveDate, to: NaiveDate) -> Result<Vec<Event>> { +    let mut events = db::events::list_non_recurring_between(conn, from, to)?;      let recurring_events = db::events::list_recurring(conn)?; -    let repetitions = event::repetitions_between(&recurring_events, today, today); -    for repetition in repetitions.values().flatten() { -        events.push(repetition.clone()); +    let repetitions = event::repetitions_between(&recurring_events, from, to); +    for (date, original_events) in repetitions.iter() { +        for original_event in original_events { +            let event = Event { date: *date, ..original_event.clone() }; +            events.push(event); +        }      } -    events.sort_by_key(|e| e.start); -    Ok(events +    Ok(events) +} + +fn format_events(events: Vec<Event>) -> String { +    let mut events = events; +    events.sort_by_key(|e| e.local_timestamp()); +    events          .iter()          .map(|e| format!("{}\n", e.pprint()))          .collect::<Vec<String>>() -        .join("")) +        .join("")  } diff --git a/src/main.rs b/src/main.rs index d3080ab..4e2a5f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,18 +17,27 @@ struct Opt {      /// List today’s events as plain text      #[clap(long = "list-today")]      list_today: bool, + +    /// Start between <timestamp..timestamp> events as plain text +    #[clap(long = "start-between")] +    start_between: Option<String>,  }  fn main() -> Result<()> {      let Opt {          db_path,          list_today, +        start_between      } = Opt::parse();      let conn = db::init(&db_path)?;      if list_today {          print!("{}", cli::today(&conn)?);      } else { -        gui::run(conn); -    } +        match start_between.and_then(cli::parse_timestamp_range) { +            Some((from, to)) => print!("{}", cli::start_between(&conn, from, to)?), +            None => gui::run(conn) +        } +    };      Ok(())  } + diff --git a/src/model/event.rs b/src/model/event.rs index 6cc16a2..dc052fe 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -1,4 +1,4 @@ -use chrono::{NaiveDate, NaiveTime}; +use chrono::{NaiveDate, NaiveTime, NaiveDateTime, Local, TimeZone};  use std::collections::HashMap;  use uuid::Uuid; @@ -33,6 +33,13 @@ impl Event {          };          format!("{}{}{}{}", start, end, space, self.name)      } + +    pub fn local_timestamp(&self) -> Option<i64> { +        let time = self.start.unwrap_or(NaiveTime::from_hms_opt(0, 0, 0)?); +        let naive_datetime = NaiveDateTime::new(self.date, time); +        let local_datetime = Local.from_local_datetime(&naive_datetime).single()?; +        Some(local_datetime.timestamp()) +    }  }  /// Recurring events in an date range (inclusive) | 
