From a4f93988461d1d83324f12e41cda5ef98b15423f Mon Sep 17 00:00:00 2001 From: xeruf <27jf@pm.me> Date: Mon, 19 Aug 2024 11:45:12 +0300 Subject: [PATCH] fix: simplify tracking functions Pruning the local history is not worth it. --- src/helpers.rs | 27 +++++++++++++++++++++ src/tasks.rs | 65 +++++++++++--------------------------------------- 2 files changed, 41 insertions(+), 51 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index 658e659..1b5a007 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -30,6 +30,33 @@ pub fn prompt(prompt: &str) -> Option { } } +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| { + if time.timestamp() > 0 { + Some(Timestamp::from(time.timestamp() as u64)) + } else { + warn!("Can only track times after 1970!"); + None + } + }) +} + // For use in format strings but not possible, so need global find-replace pub const MAX_TIMESTAMP_WIDTH: u8 = 15; /// Format nostr Timestamp relative to local time diff --git a/src/tasks.rs b/src/tasks.rs index 8ca01d9..5359fa3 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -16,7 +16,7 @@ use nostr_sdk::prelude::Marker; use TagStandard::Hashtag; use crate::{EventSender, MostrMessage}; -use crate::helpers::{format_stamp, local_datetimestamp, relative_datetimestamp, some_non_empty}; +use crate::helpers::{format_stamp, local_datetimestamp, parse_tracking_stamp, relative_datetimestamp, some_non_empty}; use crate::kinds::*; use crate::task::{MARKER_DEPENDS, MARKER_PARENT, State, Task, TaskState}; @@ -686,51 +686,17 @@ impl Tasks { /// Parse string and set tracking /// Returns false and prints a message if parsing failed pub(crate) fn track_from(&mut self, str: &str) -> bool { - // Using two libraries for better exhaustiveness, see https://github.com/uutils/parse_datetime/issues/84 - let stripped = str.trim().trim_start_matches('+').trim_start_matches("in "); - if let Ok(num) = stripped.parse::() { - self.track_at(Timestamp::from(Timestamp::now().as_u64().saturating_add_signed(num * 60))); - return true; - } - 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 - } - } - } - }.filter(|time| { - if time.timestamp() > 0 { - self.track_at(Timestamp::from(time.timestamp() as u64)); - true - } else { - warn!("Can only track times after 1970!"); - false - } - }).is_some() + parse_tracking_stamp(str) + .map(|stamp| self.track_at(stamp, self.get_position())) + .is_some() } - pub(crate) fn track_at(&mut self, time: Timestamp) -> EventId { - info!("{} from {}", self.position.map_or(String::from("Stopping time-tracking"), |id| format!("Tracking \"{}\"", self.get_task_title(&id))), relative_datetimestamp(&time)); - let pos = self.get_position(); - let tracking = build_tracking(pos); - // TODO this can lead to funny omittals - self.get_own_history().map(|events| { - if let Some(event) = events.pop_last() { - if event.kind.as_u16() == TRACKING_KIND && - (pos == None && event.tags.is_empty()) || - event.tags.iter().all(|t| t.content().map(|str| str.to_string()) == pos.map(|id| id.to_string())) { - // Replace last for easier calculation - } else { - events.insert(event); - } - } - }); - self.submit(tracking.custom_created_at(time)) + pub(crate) fn track_at(&mut self, time: Timestamp, task: Option) -> EventId { + info!("{} from {}", task.map_or(String::from("Stopping time-tracking"), |id| format!("Tracking \"{}\"", self.get_task_title(&id))), relative_datetimestamp(&time)); + self.submit( + build_tracking(task) + .custom_created_at(time) + ) } /// Sign and queue the event to the relay, returning its id @@ -1096,16 +1062,14 @@ mod tasks_test { let mut tasks = stub_tasks(); let zero = EventId::all_zeros(); - tasks.track_at(Timestamp::from(0)); + tasks.track_at(Timestamp::from(0), None); assert_eq!(tasks.history.len(), 1); - tasks.move_to(Some(zero)); let now: Timestamp = Timestamp::now() - 2u64; - tasks.track_at(Timestamp::from(1)); + tasks.track_at(Timestamp::from(1), Some(zero)); assert!(tasks.time_tracked(zero) > now.as_u64()); - tasks.move_to(None); - tasks.track_at(Timestamp::from(2)); + tasks.track_at(Timestamp::from(2), None); assert_eq!(tasks.get_own_history().unwrap().len(), 3); assert_eq!(tasks.time_tracked(zero), 1); @@ -1118,8 +1082,7 @@ mod tasks_test { let mut tasks = stub_tasks(); let zero = EventId::all_zeros(); - tasks.move_to(Some(zero)); - tasks.track_at(Timestamp::from(Timestamp::now().as_u64() + 100)); + tasks.track_at(Timestamp::from(Timestamp::now().as_u64() + 100), Some(zero)); assert_eq!(timestamps(tasks.history.values().nth(0).unwrap().into_iter(), &vec![&zero]).collect_vec().len(), 2) // TODO Does not show both future and current tracking properly, need to split by current time }