44__copyright__ = 'Copyright (C) 2025-present, DV Klopfenstein, PhD. All rights reserved.'
55__author__ = "DV Klopfenstein, PhD"
66
7+ import os
78from os .path import exists
89from collections import namedtuple
910from datetime import timedelta
1011# https://docs.python.org/3/library/csv.html
11- from csv import writer
12+ import csv
1213
1314from timetracker .csvutils import get_hdr_itr
1415from timetracker .epoch .calc import dt_from_str
@@ -47,6 +48,7 @@ def wr_csvline(self, dta, delta, csvfields):
4748 with open (self .fcsv , 'w' , encoding = 'utf8' ) as csvfile :
4849 self .wr_hdrs (csvfile )
4950 # Print time information into csv
51+ _writer = csv .writer
5052 with open (self .fcsv , 'a' , encoding = 'utf8' ) as csvfile :
5153 # timedelta(days=0, seconds=0, microseconds=0,
5254 # milliseconds=0, minutes=0, hours=0, weeks=0)
@@ -55,20 +57,25 @@ def wr_csvline(self, dta, delta, csvfields):
5557 data = [str (dta ),
5658 str (delta ),
5759 csvfields .activity , csvfields .message , csvfields .tags ]
58- writer (csvfile , lineterminator = '\n ' ).writerow (data )
60+ _writer (csvfile , lineterminator = '\n ' ).writerow (data )
5961 return data
6062 return None
6163
6264 def wr_hdrs (self , prt ):
6365 """Write header"""
6466 print (',' .join (self .hdrs ), file = prt )
6567
68+ def get_next_start_datetime (self ):
69+ """Get the next start_datetime after the last line in a timetracker csv file"""
70+ ntd = self ._rd_last_line ()
71+ return ntd .start_datetime + ntd .duration + timedelta (seconds = 1 ) if ntd else None
72+
6673 # ------------------------------------------------------------------
6774 def _get_ntdata (self , csvlines ):
6875 """Get data where start and stop are datetimes; timdelta is calculated from them"""
6976 nto = self .nto
7077 def _get_nt (row ):
71- assert len (row ) == 5 , f' { self . fcsv } ROW[ { len ( row ) } ]: { row } '
78+ assert len (row ) == 5 , row
7279 return nto (
7380 start_datetime = dt_from_str (row [0 ]),
7481 duration = td_from_str (row [1 ]),
@@ -103,5 +110,28 @@ def _read_csv(self, fnc_csvlines):
103110 return self .ntrdcsv (results = fnc_csvlines (itr ), error = error )
104111 return self .ntrdcsv (results = None , error = error )
105112
113+ def _rd_last_line (self ):
114+ """Return the last line in the csv file"""
115+ try :
116+ fptr = open (self .fcsv , mode = 'rb' ) #encoding='utf8')
117+ except (PermissionError , OSError ) as err :
118+ print (type (err ).__name__ , err .args )
119+ else :
120+ with fptr as csvstrm :
121+ try :
122+ csvstrm .seek (- 2 , os .SEEK_END )
123+ while csvstrm .read (1 ) != b'\n ' :
124+ csvstrm .seek (- 2 , os .SEEK_CUR )
125+ except OSError :
126+ csvstrm .seek (0 )
127+ csv_line = csvstrm .readline ().decode ()
128+ csv_reader = csv .reader ([csv_line ])
129+ row = next (csv_reader )
130+ nts = self ._get_ntdata ([row ])
131+ if nts :
132+ assert len (nts ) == 1 , nts
133+ return nts [0 ]
134+ return None
135+
106136
107137# Copyright (C) 2025-present, DV Klopfenstein, PhD. All rights reserved.
0 commit comments