Explorar el Código

use custom parser for Timestamp and do conversions in tau

Dastan-glitch hace 3 años
padre
commit
aa2fd4e023

+ 14 - 4
bin/tau/tau-cli/src/drawdown.rs

@@ -18,11 +18,11 @@
 
 use std::collections::HashMap;
 
-use chrono::{Datelike, Duration, NaiveDate, TimeZone, Utc};
+use chrono::{Datelike, Duration, NaiveDate, Utc};
 use colored::Colorize;
 use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
 
-use darkfi::{Error, Result};
+use darkfi::{util::time::DateTime, Error, Result};
 
 use crate::primitives::{TaskEvent, TaskInfo};
 
@@ -111,10 +111,20 @@ pub fn drawdown(date: String, tasks: Vec<TaskInfo>, assignee: Option<String>) ->
                 .into_iter()
                 .filter(|t| {
                     // last event is always state stop
-                    let event_date = Utc.timestamp_nanos(
+                    let event_date = DateTime::from_timestamp(
                         t.events.last().unwrap_or(&TaskEvent::default()).timestamp.0,
+                        0,
                     );
-                    event_date.day() == day
+                    // let event_date = Utc.timestamp_nanos(
+                    //     t.events
+                    //         .last()
+                    //         .unwrap_or(&TaskEvent::default())
+                    //         .timestamp
+                    //         .0
+                    //         .try_into()
+                    //         .unwrap(),
+                    // );
+                    event_date.day == day
                 })
                 .collect();
 

+ 4 - 3
bin/tau/tau-cli/src/filter.rs

@@ -72,7 +72,7 @@ pub fn apply_filter(tasks: &mut Vec<TaskInfo>, filter: &str) {
                     let year = year + (Utc::now().year() / 100) * 100;
                     tasks.retain(|task| {
                         let date = task.created_at;
-                        let task_date = Utc.timestamp_nanos(date).date_naive();
+                        let task_date = Utc.timestamp_nanos(date.try_into().unwrap()).date_naive();
                         task_date.month() == month && task_date.year() == year
                     })
                 } else {
@@ -147,12 +147,13 @@ pub fn apply_filter(tasks: &mut Vec<TaskInfo>, filter: &str) {
                             Local::now().date_naive()
                         } else {
                             let due_date = due_as_timestamp(value).unwrap_or(0);
-                            Utc.timestamp_nanos(due_date).date_naive()
+                            Utc.timestamp_nanos(due_date.try_into().unwrap()).date_naive()
                         };
 
                         tasks.retain(|task| {
                             let date = task.due.unwrap_or(0);
-                            let task_date = Utc.timestamp_nanos(date).date_naive();
+                            let task_date =
+                                Utc.timestamp_nanos(date.try_into().unwrap()).date_naive();
 
                             match due_op {
                                 "not" => task_date != filter_date,

+ 8 - 8
bin/tau/tau-cli/src/primitives.rs

@@ -18,7 +18,7 @@
 
 use std::{fmt, str::FromStr};
 
-use darkfi::{util::time::NanoTimestamp, Error, Result};
+use darkfi::{util::time::Timestamp, Error, Result};
 
 use crate::due_as_timestamp;
 
@@ -74,7 +74,7 @@ pub struct BaseTask {
     pub desc: Option<String>,
     pub assign: Vec<String>,
     pub project: Vec<String>,
-    pub due: Option<i64>,
+    pub due: Option<u64>,
     pub rank: Option<f32>,
 }
 
@@ -89,9 +89,9 @@ pub struct TaskInfo {
     pub owner: String,
     pub assign: Vec<String>,
     pub project: Vec<String>,
-    pub due: Option<i64>,
+    pub due: Option<u64>,
     pub rank: Option<f32>,
-    pub created_at: i64,
+    pub created_at: u64,
     pub state: String,
     pub events: Vec<TaskEvent>,
     pub comments: Vec<Comment>,
@@ -111,7 +111,7 @@ impl From<BaseTask> for TaskInfo {
             project: value.project,
             due: value.due,
             rank: value.rank,
-            created_at: i64::default(),
+            created_at: u64::default(),
             state: String::default(),
             events: vec![],
             comments: vec![],
@@ -124,7 +124,7 @@ pub struct TaskEvent {
     pub action: String,
     pub author: String,
     pub content: String,
-    pub timestamp: NanoTimestamp,
+    pub timestamp: Timestamp,
 }
 
 impl std::fmt::Display for TaskEvent {
@@ -139,7 +139,7 @@ impl Default for TaskEvent {
             action: State::Open.to_string(),
             author: "".to_string(),
             content: "".to_string(),
-            timestamp: NanoTimestamp::current_time(),
+            timestamp: Timestamp::current_time(),
         }
     }
 }
@@ -148,7 +148,7 @@ impl Default for TaskEvent {
 pub struct Comment {
     content: String,
     author: String,
-    timestamp: NanoTimestamp,
+    timestamp: Timestamp,
 }
 
 impl std::fmt::Display for Comment {

+ 2 - 2
bin/tau/tau-cli/src/util.rs

@@ -34,7 +34,7 @@ use crate::{
 };
 
 /// Parse due date (e.g. "1503" for 15 March) as i64 timestamp.
-pub fn due_as_timestamp(due: &str) -> Option<i64> {
+pub fn due_as_timestamp(due: &str) -> Option<u64> {
     if due.len() != 4 || due.parse::<u32>().is_err() {
         error!("Due date must be digits of length 4 (e.g. \"1503\" for 15 March)");
         return None
@@ -58,7 +58,7 @@ pub fn due_as_timestamp(due: &str) -> Option<i64> {
     }
 
     let dt = NaiveDate::from_ymd_opt(year, month, day).unwrap().and_hms_opt(12, 0, 0).unwrap();
-    Some(dt.timestamp())
+    dt.timestamp().try_into().ok()
 }
 
 /// Start up the preferred editor to edit a task's description.

+ 14 - 14
bin/tau/tau-cli/src/view.rs

@@ -128,19 +128,19 @@ pub fn taskinfo_table(taskinfo: TaskInfo) -> Result<Table> {
     let rank = if let Some(r) = taskinfo.rank { r.to_string() } else { "".to_string() };
 
     let mut table = table!(
-        [Bd => "ref_id", &taskinfo.ref_id],
-        ["workspace", &taskinfo.workspace],
-        [Bd =>"id", &taskinfo.id.to_string()],
-        ["owner", &taskinfo.owner],
-        [Bd =>"title", &taskinfo.title],
-        ["tags", &taskinfo.tags.join(", ")],
-        [Bd =>"desc", &taskinfo.desc.to_string()],
-        ["assign", taskinfo.assign.join(", ")],
-        [Bd =>"project", taskinfo.project.join(", ")],
-        ["due", due],
-        [Bd =>"rank", rank],
-        ["created_at", created_at],
-        [Bd =>"current_state", &taskinfo.state]);
+         [Bd => "ref_id", &taskinfo.ref_id],
+         ["workspace", &taskinfo.workspace],
+         [Bd =>"id", &taskinfo.id.to_string()],
+         ["owner", &taskinfo.owner],
+         [Bd =>"title", &taskinfo.title],
+         ["tags", &taskinfo.tags.join(", ")],
+         [Bd =>"desc", &taskinfo.desc.to_string()],
+         ["assign", taskinfo.assign.join(", ")],
+         [Bd =>"project", taskinfo.project.join(", ")],
+         ["due", due],
+         [Bd =>"rank", rank],
+         ["created_at", created_at],
+         [Bd =>"current_state", &taskinfo.state]);
 
     table.set_format(
         FormatBuilder::new()
@@ -221,7 +221,7 @@ pub fn events_as_string(events: Vec<TaskEvent>) -> (String, String) {
                     events_str,
                     "- {} changed due date to {}",
                     event.author,
-                    timestamp_to_date(event.content.parse::<i64>().unwrap_or(0), DateFormat::Date)
+                    timestamp_to_date(event.content.parse::<u64>().unwrap_or(0), DateFormat::Date)
                 )
                 .unwrap();
             }

+ 4 - 4
bin/tau/taud/src/jsonrpc.rs

@@ -31,7 +31,7 @@ use darkfi::{
         jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResult},
         server::RequestHandler,
     },
-    util::{path::expand_path, time::NanoTimestamp},
+    util::{path::expand_path, time::Timestamp},
     Error,
 };
 
@@ -58,7 +58,7 @@ struct BaseTaskInfo {
     desc: String,
     assign: Vec<String>,
     project: Vec<String>,
-    due: Option<NanoTimestamp>,
+    due: Option<Timestamp>,
     rank: Option<f32>,
 }
 
@@ -271,7 +271,7 @@ impl JsonRpcInterface {
         if params.len() != 1 {
             return Err(TaudError::InvalidData("len of params should be 1".into()))
         }
-        let month = params[0].as_i64().map(NanoTimestamp);
+        let month = params[0].as_u64().map(Timestamp);
         let ws = self.workspace.lock().await.clone();
 
         let tasks = MonthTasks::load_stop_tasks(&self.dataset_path, ws, month.as_ref())?;
@@ -448,7 +448,7 @@ impl JsonRpcInterface {
 
         if fields.contains_key("due") {
             let due = fields.get("due").unwrap().clone();
-            let due: Option<Option<NanoTimestamp>> = serde_json::from_value(due)?;
+            let due: Option<Option<Timestamp>> = serde_json::from_value(due)?;
             if let Some(d) = due {
                 task.set_due(d);
                 match d {

+ 14 - 15
bin/tau/taud/src/month_tasks.rs

@@ -27,7 +27,7 @@ use serde::{Deserialize, Serialize};
 
 use darkfi::util::{
     file::{load_json_file, save_json_file},
-    time::NanoTimestamp,
+    time::Timestamp,
 };
 
 use crate::{
@@ -37,7 +37,7 @@ use crate::{
 
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
 pub struct MonthTasks {
-    created_at: NanoTimestamp,
+    created_at: Timestamp,
     active_tks: Vec<String>,
     deactive_tks: Vec<String>,
 }
@@ -45,7 +45,7 @@ pub struct MonthTasks {
 impl MonthTasks {
     pub fn new(active_tks: &[String], deactive_tks: &[String]) -> Self {
         Self {
-            created_at: NanoTimestamp::current_time(),
+            created_at: Timestamp::current_time(),
             active_tks: active_tks.to_owned(),
             deactive_tks: deactive_tks.to_owned(),
         }
@@ -84,14 +84,16 @@ impl MonthTasks {
         }
     }
 
-    pub fn set_date(&mut self, date: &NanoTimestamp) {
+    pub fn set_date(&mut self, date: &Timestamp) {
         debug!(target: "tau", "MonthTasks::set_date()");
         self.created_at = *date;
     }
 
-    fn get_path(date: &NanoTimestamp, dataset_path: &Path) -> PathBuf {
+    fn get_path(date: &Timestamp, dataset_path: &Path) -> PathBuf {
         debug!(target: "tau", "MonthTasks::get_path()");
-        dataset_path.join("month").join(Utc.timestamp_nanos(date.0).format("%m%y").to_string())
+        dataset_path
+            .join("month")
+            .join(Utc.timestamp_nanos(date.0.try_into().unwrap()).format("%m%y").to_string())
     }
 
     pub fn save(&self, dataset_path: &Path) -> TaudResult<()> {
@@ -112,7 +114,7 @@ impl MonthTasks {
         Ok(entries)
     }
 
-    fn create(date: &NanoTimestamp, dataset_path: &Path) -> TaudResult<Self> {
+    fn create(date: &Timestamp, dataset_path: &Path) -> TaudResult<Self> {
         debug!(target: "tau", "MonthTasks::create()");
 
         let mut mt = Self::new(&[], &[]);
@@ -121,7 +123,7 @@ impl MonthTasks {
         Ok(mt)
     }
 
-    pub fn load_or_create(date: Option<&NanoTimestamp>, dataset_path: &Path) -> TaudResult<Self> {
+    pub fn load_or_create(date: Option<&Timestamp>, dataset_path: &Path) -> TaudResult<Self> {
         debug!(target: "tau", "MonthTasks::load_or_create()");
 
         // if a date is given we load that date's month tasks
@@ -179,7 +181,7 @@ impl MonthTasks {
     pub fn load_stop_tasks(
         dataset_path: &Path,
         ws: String,
-        date: Option<&NanoTimestamp>,
+        date: Option<&Timestamp>,
     ) -> TaudResult<Vec<TaskInfo>> {
         let mt = Self::load_or_create(date, dataset_path)?;
         Ok(mt
@@ -253,8 +255,7 @@ mod tests {
 
         mt.save(&dataset_path)?;
 
-        let mt_load =
-            MonthTasks::load_or_create(Some(&NanoTimestamp::current_time()), &dataset_path)?;
+        let mt_load = MonthTasks::load_or_create(Some(&Timestamp::current_time()), &dataset_path)?;
 
         assert_eq!(mt, mt_load);
 
@@ -262,8 +263,7 @@ mod tests {
 
         mt.save(&dataset_path)?;
 
-        let mt_load =
-            MonthTasks::load_or_create(Some(&NanoTimestamp::current_time()), &dataset_path)?;
+        let mt_load = MonthTasks::load_or_create(Some(&Timestamp::current_time()), &dataset_path)?;
 
         assert_eq!(mt, mt_load);
 
@@ -282,8 +282,7 @@ mod tests {
 
         task.save(&dataset_path)?;
 
-        let mt_load =
-            MonthTasks::load_or_create(Some(&NanoTimestamp::current_time()), &dataset_path)?;
+        let mt_load = MonthTasks::load_or_create(Some(&Timestamp::current_time()), &dataset_path)?;
 
         assert!(mt_load.active_tks.contains(&task.ref_id));
 

+ 11 - 11
bin/tau/taud/src/task_info.rs

@@ -26,7 +26,7 @@ use darkfi::{
     event_graph::gen_id,
     util::{
         file::{load_json_file, save_json_file},
-        time::NanoTimestamp,
+        time::Timestamp,
     },
 };
 
@@ -41,12 +41,12 @@ pub struct TaskEvent {
     pub action: String,
     pub author: String,
     pub content: String,
-    pub timestamp: NanoTimestamp,
+    pub timestamp: Timestamp,
 }
 
 impl TaskEvent {
     pub fn new(action: String, author: String, content: String) -> Self {
-        Self { action, author, content, timestamp: NanoTimestamp::current_time() }
+        Self { action, author, content, timestamp: Timestamp::current_time() }
     }
 }
 
@@ -54,7 +54,7 @@ impl TaskEvent {
 pub struct Comment {
     content: String,
     author: String,
-    timestamp: NanoTimestamp,
+    timestamp: Timestamp,
 }
 
 impl Comment {
@@ -62,7 +62,7 @@ impl Comment {
         Self {
             content: content.into(),
             author: author.into(),
-            timestamp: NanoTimestamp::current_time(),
+            timestamp: Timestamp::current_time(),
         }
     }
 }
@@ -89,9 +89,9 @@ pub struct TaskInfo {
     pub(crate) owner: String,
     assign: TaskAssigns,
     project: TaskProjects,
-    due: Option<NanoTimestamp>,
+    due: Option<Timestamp>,
     rank: Option<f32>,
-    created_at: NanoTimestamp,
+    created_at: Timestamp,
     state: String,
     pub(crate) events: TaskEvents,
     comments: TaskComments,
@@ -103,14 +103,14 @@ impl TaskInfo {
         title: &str,
         desc: &str,
         owner: &str,
-        due: Option<NanoTimestamp>,
+        due: Option<Timestamp>,
         rank: Option<f32>,
         dataset_path: &Path,
     ) -> TaudResult<Self> {
         // generate ref_id
         let ref_id = gen_id(30);
 
-        let created_at = NanoTimestamp::current_time();
+        let created_at = Timestamp::current_time();
 
         let task_ids: Vec<u32> =
             MonthTasks::load_current_tasks(dataset_path, workspace.clone(), false)?
@@ -121,7 +121,7 @@ impl TaskInfo {
         let id: u32 = find_free_id(&task_ids);
 
         if let Some(d) = &due {
-            if *d < NanoTimestamp::current_time() {
+            if *d < Timestamp::current_time() {
                 return Err(TaudError::InvalidDueTime)
             }
         }
@@ -237,7 +237,7 @@ impl TaskInfo {
         self.rank = r;
     }
 
-    pub fn set_due(&mut self, d: Option<NanoTimestamp>) {
+    pub fn set_due(&mut self, d: Option<Timestamp>) {
         debug!(target: "tau", "TaskInfo::set_due()");
         self.due = d;
     }

+ 28 - 44
src/util/time.rs

@@ -18,7 +18,6 @@
 
 use std::{fmt, time::UNIX_EPOCH};
 
-use chrono::{NaiveDateTime, Utc};
 use darkfi_serial::{SerialDecodable, SerialEncodable};
 use serde::{Deserialize, Serialize};
 
@@ -131,6 +130,13 @@ impl Timestamp {
     }
 }
 
+impl std::fmt::Display for Timestamp {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        let date = timestamp_to_date(self.0, DateFormat::DateTime);
+        write!(f, "{}", date)
+    }
+}
+
 // TODO: NanoTimestamp to not use chrono
 #[derive(
     Clone,
@@ -144,16 +150,16 @@ impl Timestamp {
     PartialOrd,
     Eq,
 )]
-pub struct NanoTimestamp(pub i64);
+pub struct NanoTimestamp(pub u128);
 
 impl NanoTimestamp {
     pub fn current_time() -> Self {
-        Self(Utc::now().timestamp_nanos())
+        Self(UNIX_EPOCH.elapsed().unwrap().as_nanos())
     }
 }
 impl std::fmt::Display for NanoTimestamp {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        let date = timestamp_to_date(self.0, DateFormat::Nanos);
+        let date = timestamp_to_date(self.0.try_into().unwrap(), DateFormat::Nanos);
         write!(f, "{}", date)
     }
 }
@@ -186,44 +192,44 @@ impl DateTime {
     }
 
     pub fn from_timestamp(secs: u64, nsecs: u32) -> Self {
-        let leapyear = |year| -> bool { year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) };
+        let leap_year = |year| -> bool { year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) };
 
         static MONTHS: [[u64; 12]; 2] = [
             [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
             [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
         ];
 
-        let mut datetime = DateTime::new();
+        let mut date_time = DateTime::new();
         let mut year = 1970;
 
         let time = secs % SECS_IN_DAY;
-        let mut dayno = secs / SECS_IN_DAY;
+        let mut day_number = secs / SECS_IN_DAY;
 
-        datetime.nanos = nsecs;
-        datetime.sec = (time % MIN_IN_HOUR) as u32;
-        datetime.min = ((time % SECS_IN_HOUR) / MIN_IN_HOUR) as u32;
-        datetime.hour = (time / SECS_IN_HOUR) as u32;
+        date_time.nanos = nsecs;
+        date_time.sec = (time % MIN_IN_HOUR) as u32;
+        date_time.min = ((time % SECS_IN_HOUR) / MIN_IN_HOUR) as u32;
+        date_time.hour = (time / SECS_IN_HOUR) as u32;
 
         loop {
-            let yearsize = if leapyear(year) { 366 } else { 365 };
-            if dayno >= yearsize {
-                dayno -= yearsize;
+            let year_size = if leap_year(year) { 366 } else { 365 };
+            if day_number >= year_size {
+                day_number -= year_size;
                 year += 1;
             } else {
                 break
             }
         }
-        datetime.year = year;
+        date_time.year = year;
 
         let mut month = 0;
-        while dayno >= MONTHS[if leapyear(year) { 1 } else { 0 }][month] {
-            dayno -= MONTHS[if leapyear(year) { 1 } else { 0 }][month];
+        while day_number >= MONTHS[if leap_year(year) { 1 } else { 0 }][month] {
+            day_number -= MONTHS[if leap_year(year) { 1 } else { 0 }][month];
             month += 1;
         }
-        datetime.month = month as u32 + 1;
-        datetime.day = dayno as u32 + 1;
+        date_time.month = month as u32 + 1;
+        date_time.day = day_number as u32 + 1;
 
-        datetime
+        date_time
     }
 }
 
@@ -250,33 +256,11 @@ impl fmt::Display for Date {
     }
 }
 
-pub fn timestamp_to_date(timestamp: i64, format: DateFormat) -> String {
-    if timestamp <= 0 {
+pub fn timestamp_to_date(timestamp: u64, format: DateFormat) -> String {
+    if timestamp == 0 {
         return "".to_string()
     }
 
-    match format {
-        DateFormat::Date => NaiveDateTime::from_timestamp_opt(timestamp, 0)
-            .unwrap()
-            .date()
-            .format("%-d %b")
-            .to_string(),
-        DateFormat::DateTime => NaiveDateTime::from_timestamp_opt(timestamp, 0)
-            .unwrap()
-            .format("%H:%M:%S %A %-d %B")
-            .to_string(),
-        DateFormat::Nanos => {
-            const A_BILLION: i64 = 1_000_000_000;
-            NaiveDateTime::from_timestamp_opt(timestamp / A_BILLION, (timestamp % A_BILLION) as u32)
-                .unwrap()
-                .format("%H:%M:%S.%f")
-                .to_string()
-        }
-        DateFormat::Default => "".to_string(),
-    }
-}
-
-fn _seconds_to_datetime(timestamp: u64, format: DateFormat) -> String {
     match format {
         DateFormat::Default => "".to_string(),
         DateFormat::Date => DateTime::from_timestamp(timestamp, 0).date().to_string(),