timetracker/timetracker.py

117 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
import fileinput
import math
import re
import sys
import time
def nearest(hr):
return round(hr*4)/4
# Variables
start = {} # Data structure for storing the beginning of a time frame
finish = {} # Data structure for storing the end of a time frame
ind = {} # Data structure for storing individual timecards
misc = {} # Data structure for storing miscellaneous timecards
empty = re.compile("^\s*$") # regex for finding empty lines (and skipping them)
comment = re.compile("^\s*#") # regex for finding empty lines (and skipping them)
delim = re.compile(":\s{2}") # regex for splitting timestamp entry
begin = re.compile("^Begin\s+(?P<action>.*)\s*$")
end = re.compile("^End\s+(?P<action>.*)\s*$")
#case = re.compile("^(PDROP|CHG)-?\d+")
for line in fileinput.input():
if empty.match(line) or comment.match(line): # if the current line is empty
continue # skip to the next line
(datetime,entry) = delim.split(line.strip())
timestamp = time.mktime(time.strptime(datetime,"%Y-%m-%d %H:%M:%S"))
if begin.match(entry):
action = begin.sub("\g<action>",entry)
if action not in start:
start[action] = []
start[action].append(timestamp)
if end.match(entry):
action = end.sub("\g<action>",entry)
if action not in finish:
finish[action] = []
finish[action].append(timestamp)
# We're here, we've captured all of the data
gtoth = 0
gtot = 0
for act in sorted(start.keys()):
if act in start:
bc = len(start[act])
else: bc = 0
if act in finish:
ec = len(finish[act])
else: ec = 0
if bc - ec > 1:
print("ERROR: Missing more than one End", file=sys.stderr)
sys.exit(2)
elif bc > ec: # bc should be exactly one greater
start[act].pop()
elif ec > bc:
print("ERROR: Missing a Begin", file=sys.stderr)
sys.exit(1)
delta = 0
while (len(start[act]) > 0 and len(finish[act]) > 0):
beg = start[act].pop(0)
en = finish[act].pop(0)
delta += en - beg
ind[act] = delta
gtot += delta
if delta <= 288:
gtoth += 0.08
else:
gtoth += nearest(delta/3600.00)
#ttot = 0
#utot = 0
table = "{a:<50} {f:>10}"
for act in sorted(ind.keys()):
#minutes = "{:d}min".format(int(ind[act]%3600/60))
#hrs = "{:d}hrs".format(int(nearest(ind[act]/3600)))
if ind[act] <= 288:
fhrs = "{:.2f}hrs".format(0.08)
else:
fhrs = "{:.2f}hrs".format(nearest(ind[act]/3600.00))
#sec = "{:d}s".format(int(ind[act]))
#print table.format(a=act, s=sec, h=hrs, m=minutes, f=fhrs)
print(table.format(a=act, f=fhrs))
# if case.match(act):
# ttot += ind[act]
# else:
# utot += ind[act]
total = "{t:<20} {h:>10}"
#ttots = "{:d}s".format(int(ttot))
#utots = "{:d}s".format(int(utot))
#ttoth = "{:3.2f}hrs".format(nearest(ttot / 3600))
#utoth = "{:3.2f}hrs".format(nearest(utot / 3600))
#gtots = "{:d}s".format(int(gtot))
gtoth = "{:3.2f}hrs".format(gtoth)
print()
#print total.format(t="Incident total:", s=ttots, h=ttoth)
#print total.format(t="Unnumbered total:", s=utots, h=utoth)
print(total.format(t="Section total:", h=gtoth))