File: today.py

package info (click to toggle)
gtimelog 0.12.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,008 kB
  • sloc: python: 4,530; xml: 171; makefile: 93
file content (148 lines) | stat: -rwxr-xr-x 4,220 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/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()