/
pomodoro_daily_chart.py
executable file
·146 lines (122 loc) · 4.59 KB
/
pomodoro_daily_chart.py
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
#!/usr/bin/python
#
# pomodoro_daily_chart.py
#
# Author: Brett Hutley <brett@hutley.net>
#
# This code is to extract the list of Pomodoros from my Mac OS/X calendar
# using the program 'callistevents' https://github.com/bhutley/callistevents
# and then create a bar-chart aggregating the work done each hour, in order
# to show how my productivity looks during the day.
#
# By default it will create a chart called pomodoro_daily_chart.png in
# the current directory. You can specify a different output file using
# the '-o' command-line option.
#
import os, sys
import subprocess
import datetime
import argparse
# This is the path to the callistevents program
# MODIFY THIS TO POINT TO THE RIGHT LOCATION FOR YOU
callistevents_prog = os.path.expanduser('~/my/bin/callistevents')
parser = argparse.ArgumentParser(description="Generate a bar-chart of your hourly productivity by processing all the Pomodoro entries in your Pomodoro calendar for the current day")
parser.add_argument('-o', nargs='?',
dest='outfile',
default='pomodoro_daily_chart.png',
help='The PNG file containing the chart')
parser.add_argument('-W', nargs='?',
dest='width',
type=int,
default=600,
help='The width in pixels of the PNG file')
parser.add_argument('-H', nargs='?',
dest='height',
type=int,
default=400,
help='The height in pixels of the PNG file')
args = parser.parse_args()
time_buckets = [0.0 for i in xrange(0, 24)]
colours_to_use = [
'#000000',
'#990000',
'#CC0000',
'#994C00',
'#CC6600',
'#999900',
'#FFFF00',
'#009900',
'#00CC00',
'#00FF00',
'#33FF33',
]
ttl_mins_worked = 0
start_date = datetime.date.today()
start_date_str = ("%d-%02d-%02d" % (start_date.year, start_date.month, start_date.day, ))
p = subprocess.Popen([callistevents_prog, '-c', 'Pomodoros', '-s', start_date_str ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
lines = out.split("\n")
for line in lines:
fields = line.split("\t")
if len(fields) >= 3:
sta = fields[1]
end = fields[2]
if len(sta) == 16 and len(end) == 16:
sta_hr = int(sta[11:13])
sta_mn = int(sta[14:])
end_hr = int(end[11:13])
end_mn = int(end[14:])
if sta_hr == end_hr:
mins = end_mn - sta_mn
ttl_mins_worked += mins
time_buckets[sta_hr] += float(mins) / 60.0
else:
for h in xrange(sta_hr, end_hr+1):
if h == sta_hr:
mins = 60.0 - sta_mn
ttl_mins_worked += mins
time_buckets[sta_hr] += float(mins) / 60.0
elif h == end_hr:
mins = end_mn
ttl_mins_worked += mins
time_buckets[end_hr] += float(mins) / 60.0
else:
ttl_mins_worked += 60
time_buckets[h] += 1.0
## OK, the code following is for generating the plot.
# The code above has no dependencies on matplotlib
import numpy as n
from pylab import figure, show
import matplotlib.cm as cm
import matplotlib.colors as colors
width = 1.0
fig = figure(1, figsize=(float(args.width) / 100.0, float(args.height) / 100.0))
ax = fig.add_subplot(111)
rects1 = ax.bar(xrange(0, 24), time_buckets, width,
color='r')
cc = colors.ColorConverter()
for i in xrange(0, len(time_buckets)):
offset = int(round(time_buckets[i] * 10.0))
if offset >= len(colours_to_use):
offset = len(colours_to_use)-1
r = rects1[i]
r.set_color( cc.to_rgb(colours_to_use[offset]) )
ax.set_ylabel('Productivity')
ax.set_xlabel('Hour')
ax.set_title('Productivity for %s' % (start_date_str, ))
ax.set_axis_bgcolor('#EEE9E9')
ax.set_ylim(0, 1.0)
ax.set_xticks(xrange(0, 24))
hours_worked = int(float(ttl_mins_worked) / 60.0)
minutes_worked = (ttl_mins_worked % 60)
ax.text(0.5, 0.9, "Time worked: %d:%02d" % (hours_worked, minutes_worked ), color='#2f4f4f' )
for tick in ax.xaxis.get_major_ticks():
#tick.label.set_fontsize(14)
# specify integer or one of preset strings, e.g.
tick.label.set_fontsize('x-small')
tick.label.set_rotation('vertical')
for tick in ax.yaxis.get_major_ticks():
#tick.label.set_fontsize(14)
# specify integer or one of preset strings, e.g.
tick.label.set_fontsize('x-small')
fig.savefig(args.outfile, format="png", dpi=100)