#!/usr/bin/python import re import os import sys import getopt import datetime def read_timelog(filename): return file(filename) def todays_entries(today, lines): # assume "day turnover" at 2 am min = datetime.datetime.combine(today, datetime.time(2, 0)) max = min + datetime.timedelta(1) for line in lines: time = line.split(': ', 1)[0] try: time = parse_datetime(time) except ValueError: pass else: if min <= time < max: yield line def parse_date(dt): m = re.match(r'^(\d+)-(\d+)-(\d+)$', dt) if not m: raise ValueError('bad date: ', dt) year, month, day = map(int, m.groups()) return datetime.date(year, month, day) def parse_datetime(dt): m = re.match(r'^(\d+)-(\d+)-(\d+) (\d+):(\d+)$', dt) if not m: raise ValueError('bad date time: ', dt) year, month, day, hour, min = map(int, m.groups()) return datetime.datetime(year, month, day, hour, min) def calculate_diffs(lines): last_time = None for line in lines: time, action = line.split(': ', 1) time = parse_datetime(time) if last_time is None: delta = None else: delta = time - last_time yield last_time, time, delta, action.strip() last_time = time def format_time(t): h, m = divmod(t, 60) if h and m: return '%d hour%s %d min' % (h, h != 1 and "s" or "", m) elif h: return '%d hour%s' % (h, h != 1 and "s" or "") else: return '%d min' % m def print_diff(last_time, time, delta, action): time = time.strftime('%H:%M') if delta is None: delta = "" else: delta = format_time(delta.seconds / 60) # format 1 ## print "%s%15s %s" % (time, delta, action) # format 2 action = action[:1].title() + action[1:] if not delta: print "%s at %s\n" % (action, time) else: print "%-62s %s" % (action, delta) def print_diffs(iter): first_time = None time = None total_time = total_slack = datetime.timedelta(0) for last_time, time, delta, action in iter: if first_time is None: first_time = time print_diff(last_time, time, delta, action) if delta is not None: if '**' in action: total_slack += delta else: total_time += delta return first_time, time, total_time, total_slack def main(argv=sys.argv): filename = 'timelog.txt' opts, args = getopt.getopt(argv[1:], 'hf:', ['help']) for k, v in opts: if k == '-f': filename = v if len(args) > 1: print >> sys.stderr, "too many arguments" elif len(args) == 1: if args[0] == 'yesterday': today = datetime.date.today() - datetime.timedelta(1) else: today = parse_date(args[0]) else: if os.path.basename(argv[0]).replace('.py', '') == 'yesterday': today = datetime.date.today() - datetime.timedelta(1) else: today = datetime.date.today() title = "Today, %s" % today.strftime('%Y-%m-%d') print title print "-" * len(title) chain = read_timelog(filename) chain = todays_entries(today, chain) chain = calculate_diffs(chain) first_time, last_time, total_time, total_slack = print_diffs(chain) now = datetime.datetime.now() print "" print "Total work done: %s" % format_time(total_time.seconds / 60) print "Time spent slacking: %s" % format_time(total_slack.seconds / 60) print "" print "Time now: %s" % now.strftime('%H:%M') if last_time is not None: delta = now - last_time print "Time since last entry: %s" % format_time(delta.seconds / 60) delta = now - first_time print "Time since first entry: %s" % format_time(delta.seconds / 60) est_end_of_work = last_time + datetime.timedelta(hours=8) - total_time delta = est_end_of_work - now print "Time left at work: %s (til %s)" % ( format_time(delta.seconds / 60), est_end_of_work.strftime("%H:%M")) if __name__ == '__main__': main()