From efc0061390edcab663c3b9b4c3f0827d6012f1e1 Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Mon, 19 Aug 2024 22:16:19 +0300 Subject: [PATCH] feat(main): rudimentary filter by date or author --- src/helpers.rs | 32 +++++++++++++++++-------------- src/main.rs | 52 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index 1b5a007..0c63ddc 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,7 +1,7 @@ use std::fmt::Display; use std::io::{stdin, stdout, Write}; -use chrono::{Local, NaiveDateTime, TimeZone}; +use chrono::{DateTime, Local, NaiveDateTime, TimeZone, Utc}; use chrono::LocalResult::Single; use log::{debug, error, info, trace, warn}; use nostr_sdk::Timestamp; @@ -30,24 +30,28 @@ pub fn prompt(prompt: &str) -> Option { } } +pub fn parse_date(str: &str) -> Option> { + // Using two libraries for better exhaustiveness, see https://github.com/uutils/parse_datetime/issues/84 + match interim::parse_date_string(str, Local::now(), interim::Dialect::Us) { + Ok(date) => Some(date.to_utc()), + Err(e) => { + match parse_datetime::parse_datetime_at_date(Local::now(), str) { + Ok(date) => Some(date.to_utc()), + Err(_) => { + warn!("Could not parse date from {str}: {e}"); + None + } + } + } + } +} + pub fn parse_tracking_stamp(str: &str) -> Option { let stripped = str.trim().trim_start_matches('+').trim_start_matches("in "); if let Ok(num) = stripped.parse::() { return Some(Timestamp::from(Timestamp::now().as_u64().saturating_add_signed(num * 60))); } - // Using two libraries for better exhaustiveness, see https://github.com/uutils/parse_datetime/issues/84 - match interim::parse_date_string(stripped, Local::now(), interim::Dialect::Us) { - Ok(date) => Some(date.to_utc()), - Err(e) => { - match parse_datetime::parse_datetime_at_date(Local::now(), stripped) { - Ok(date) => Some(date.to_utc()), - Err(_) => { - warn!("Could not parse time from {str}: {e}"); - None - } - } - } - }.and_then(|time| { + parse_date(str).and_then(|time| { if time.timestamp() > 0 { Some(Timestamp::from(time.timestamp() as u64)) } else { diff --git a/src/main.rs b/src/main.rs index ef0e315..590b777 100644 --- a/src/main.rs +++ b/src/main.rs @@ -379,15 +379,49 @@ async fn main() { } Some('@') => { - let key = arg.and_then(|a| PublicKey::from_str(a).ok()).unwrap_or_else(|| keys.public_key()); - let author = tasks.get_author(&key); - info!("Filtering for events by {author}"); - tasks.set_filter( - tasks.filtered_tasks(tasks.get_position_ref()) - .filter(|t| t.event.pubkey == key) - .map(|t| t.event.id) - .collect() - ) + match arg { + None => { + let today = Timestamp::from(Timestamp::now() - 80_000); + info!("Filtering for tasks from the last 22 hours"); + tasks.set_filter( + tasks.filtered_tasks(tasks.get_position_ref()) + .filter(|t| t.event.created_at > today) + .map(|t| t.event.id) + .collect() + ); + } + Some(arg) => { + if arg == "@" { + let key = keys.public_key(); + info!("Filtering for own tasks"); + tasks.set_filter( + tasks.filtered_tasks(tasks.get_position_ref()) + .filter(|t| t.event.pubkey == key) + .map(|t| t.event.id) + .collect() + ) + } else if let Ok(key) = PublicKey::from_str(arg) { + let author = tasks.get_author(&key); + info!("Filtering for tasks by {author}"); + tasks.set_filter( + tasks.filtered_tasks(tasks.get_position_ref()) + .filter(|t| t.event.pubkey == key) + .map(|t| t.event.id) + .collect() + ) + } else { + parse_date(arg).map(|time| { + info!("Filtering for tasks from {}", time); // TODO localize + tasks.set_filter( + tasks.filtered_tasks(tasks.get_position_ref()) + .filter(|t| t.event.created_at.as_u64() as i64 > time.timestamp()) + .map(|t| t.event.id) + .collect() + ); + }); + } + } + } } Some('*') => {