#! /usr/bin/env python
import argparse
from datetime import datetime, timedelta
import os
import sys


DATETIME_FORMAT = '%Y%m%dT%H:%M:%S'


def parse_line(line):
    dt, comments = line.split('-')
    dt = datetime.strptime(dt.strip(), DATETIME_FORMAT)
    return dt, comments.strip()


def get_timecard_lines(file_):
    with open(file_) as fp:
        lines = fp.readlines()
    return [parse_line(line) for line in lines]


def count_time(lines, before=None, after=None):
    running_total = 0
    working = False
    last_in_dt = datetime(2015, 1, 1)  # arbitrary dt
    for dt, comments in lines:
        if (after and dt < after) or (before and dt > before):
            continue
        if not working and comments.startswith('in'):
            working = True
            last_in_dt = dt
        elif working and comments.startswith('out'):
            running_total += (dt - last_in_dt).total_seconds()
            working = False

    if working:
        now = datetime.utcnow()
        running_total += (now - last_in_dt).total_seconds()

    return running_total, working


def print_work_today(lines):
    now = datetime.utcnow()
    day_start = now.replace(hour=8, minute=0, second=0, microsecond=0)
    if now.hour < 8:
        day_start -= timedelta(days=1)
    seconds, _ = count_time(lines, after=day_start)
    print('Work today (since {} UTC): {:.3} hours'
          ''.format(day_start, seconds / 3600))


def print_work_this_week(lines):
    # get most recent Monday morning
    now = datetime.utcnow()
    monday = now - timedelta(days=now.weekday())
    monday = monday.replace(hour=8, minute=0, second=0, microsecond=0)
    seconds, _ = count_time(lines, after=monday)
    print('Work in past week (since {} UTC): {:.3} hours'
          ''.format(monday, seconds / 3600))


def print_status(lines):
    print('NOW {} (UTC)'.format(datetime.utcnow()))
    is_in = is_checked_in(lines)
    print('Currently CHECKED {}'.format('IN' if is_in else 'OUT'))
    print_work_today(lines)
    print_work_this_week(lines)


def check_in(timecard_file, comment):
    comment = ' '.join(comment)
    dt_string = '{}'.format(datetime.utcnow().strftime(DATETIME_FORMAT))
    with open(timecard_file, 'a') as fp:
        fp.write(dt_string + ' - in ' + comment + '\n')


def check_out(timecard_file, comment):
    comment = ' '.join(comment)
    dt_string = '{}'.format(datetime.utcnow().strftime(DATETIME_FORMAT))
    with open(timecard_file, 'a') as fp:
        fp.write(dt_string + ' - out ' + comment + '\n')


def is_checked_in(lines):
    _, working = count_time(lines)
    return working


def switch(timecard_file, args):
    lines = get_timecard_lines(timecard_file)

    if args.cmd in ('in', 'out'):
        is_in = is_checked_in(lines)
        if args.cmd == 'in' and not is_in:
            check_in(timecard_file, args.comment)
        elif args.cmd == 'out' and is_in:
            check_out(timecard_file, args.comment)
        else:
            sys.stderr.write('Can not check {0}. You are already checked {0}.\n'
                             ''.format(args.cmd.upper()))
            sys.exit(1)

    elif args.cmd != 'st':
        sys.stderr.write('Invalid command: {}\n')
        sys.exit(1)

    lines = get_timecard_lines(timecard_file)
    print_status(lines)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('cmd')
    parser.add_argument('comment', nargs=argparse.REMAINDER)
    args = parser.parse_args()

    timecard_file = os.path.expanduser('~/.timecard/timecard.txt')
    if not timecard_file:
        sys.stderr.write('No timecard file found.\n')
        sys.exit(1)

    switch(timecard_file, args)


if __name__ == '__main__':
    main()


@@ -680,16 +680,17 @@
 ontinue%0A
+%0A
         
@@ -942,16 +942,31 @@
 %0A    if 
+not before and 
 working:
@@ -1428,32 +1428,493 @@
 onds / 3600))%0A%0A%0A
+def print_work_last_week(lines):%0A    # get most recent Monday morning%0A    now = datetime.utcnow()%0A    monday = now - timedelta(days=now.weekday())%0A    monday = monday.replace(hour=8, minute=0, second=0, microsecond=0)%0A    last_week_monday = monday - timedelta(days=7)%0A    seconds, _ = count_time(lines, after=last_week_monday, before=monday)%0A    print('Work last week (%7B%7D - %7B%7D UTC): %7B:.3%7D hours'%0A          ''.format(last_week_monday, monday, seconds / 3600))%0A%0A%0A
 def print_work_t
@@ -2504,24 +2504,249 @@
 ek(lines)%0A%0A%0A
+def print_status_for_last_week(lines):%0A    print('NOW %7B%7D (UTC)'.format(datetime.utcnow()))%0A    is_in = is_checked_in(lines)%0A    print('Currently CHECKED %7B%7D'.format('IN' if is_in else 'OUT'))%0A    print_work_last_week(lines)%0A%0A%0A
 def check_in
@@ -3824,29 +3824,167 @@
     
-elif args.cmd != 'st'
+    print_status(lines)%0A%0A    elif args.cmd == 'lw':%0A        print_status_for_last_week(lines)%0A%0A    elif args.cmd == 'st':%0A        print_status(lines)%0A%0A    else
 :%0A  
@@ -4029,16 +4029,33 @@
 d: %7B%7D%5Cn'
+.format(args.cmd)
 )%0A      
@@ -4073,79 +4073,8 @@
 1)%0A%0A
-    lines = get_timecard_lines(timecard_file)%0A    print_status(lines)%0A%0A
 %0Adef

Add a last week hour counter