summaryrefslogtreecommitdiff
path: root/activity/_activitybase.py
diff options
context:
space:
mode:
Diffstat (limited to 'activity/_activitybase.py')
-rw-r--r--activity/_activitybase.py161
1 files changed, 161 insertions, 0 deletions
diff --git a/activity/_activitybase.py b/activity/_activitybase.py
new file mode 100644
index 0000000..3a0255f
--- /dev/null
+++ b/activity/_activitybase.py
@@ -0,0 +1,161 @@
1import csv
2from datetime import datetime
3from cStringIO import StringIO
4
5from MoinMoin.action import ActionBase
6from MoinMoin.PageEditor import PageEditor
7
8
9class FormattedDateTime:
10
11 def __init__(self, dt):
12 self.dt = dt
13
14 @classmethod
15 def from_now(cls):
16 return cls(datetime.now())
17
18 @property
19 def time(self):
20 return self.dt.strftime('%H:%M:%S')
21
22 @property
23 def date(self):
24 return self.dt.strftime('%Y-%m-%d')
25
26
27class DataRow(list):
28
29 _attr_map = ['start_date', 'start_time', 'end_date', 'end_time', 'task']
30
31 def __setattr__(self, attr, value):
32 pos = self._attr_map.index(attr)
33 self[pos] = value
34
35 def __getattr__(self, attr):
36 pos = self._attr_map.index(attr)
37 return self[pos]
38
39 def _make_datetime(self, date, time):
40 if not date or not time:
41 return None
42
43 try:
44 return datetime.strptime(' '.join((date, time)), '%Y-%m-%d %H:%M:%S')
45 except ValueError as err:
46 return datetime.strptime(' '.join((date, time)), '%Y-%m-%d %H:%M')
47
48 @property
49 def start_datetime(self):
50 return self._make_datetime(self.start_date, self.start_time)
51
52 @property
53 def end_datetime(self):
54 return self._make_datetime(self.end_date, self.end_time)
55
56 @property
57 def has_ended(self):
58 return self.end_date != ''
59
60 def mark_ended(self, now=None):
61 if not now:
62 now = FormattedDateTime.from_now()
63
64 if not self.has_ended:
65 self.end_date = now.date
66 self.end_time = now.time
67
68
69def parse_rows(data):
70 body = StringIO(data)
71
72 if data.startswith('#'):
73 body.readline()
74
75 reader = csv.reader(body, quotechar='"')
76 return [DataRow(r) for r in reader]
77
78
79class ActivityAction(ActionBase):
80
81 def __init__(self, pagename, request):
82 ActionBase.__init__(self, pagename, request)
83
84 self.page = PageEditor(request, pagename)
85 self.use_ticket = True
86
87 def get_rows(self):
88 return parse_rows(self.page.body)
89
90 def update_page(self, rows):
91 out_page = StringIO()
92 out_page.write('#format timecsv\n')
93 csv.writer(out_page, quotechar='"').writerows(rows)
94
95 return self.page.saveText(out_page.getvalue(), self.request.rev or 0)
96
97 def start_activity(self, description):
98 rows = self.get_rows()
99 now = FormattedDateTime.from_now()
100
101 rows[-1].mark_ended(now)
102 rows.append((now.date, now.time, '', '', description))
103
104 return self.update_page(rows)
105
106 def stop_activity(self):
107 rows = self.get_rows()
108 rows[-1].mark_ended()
109 self.update_page(rows)
110
111 @property
112 def can_use_activity(self):
113 return self.page.pi['format'] == 'timecsv'
114
115
116class Analysis:
117
118 def __init__(self, data):
119 self.raw_data = data
120 self.data = {}
121 self.order = []
122
123 @staticmethod
124 def _to_time(value):
125 hours = value // 3600
126 minutes = (value // 60) - (hours * 60)
127
128 if hours == 0:
129 return '{} minutes'.format(minutes)
130 else:
131 return '{} hours {} minutes'.format(hours, minutes)
132
133 def process(self):
134 self.raw_data.sort(key=lambda i: i.start_datetime, reverse=True)
135
136 for row in self.raw_data:
137 date = row.start_datetime.date()
138 data = self.data.get(date, None)
139
140 if date not in self.order:
141 self.order.append(date)
142
143 if data is None:
144 data = self.data[date] = {}
145
146 if not data.get(row.task):
147 data[row.task] = [0, False]
148
149 if row.end_datetime:
150 data[row.task][0] += (
151 row.end_datetime - row.start_datetime).seconds
152 else:
153 data[row.task][0] += (
154 datetime.now() - row.start_datetime).seconds
155
156 if not row.has_ended:
157 data[row.task][1] = True
158
159 def __iter__(self):
160 for key in self.order:
161 yield key, dict((k, (self._to_time(v[0]), v[1])) for k, v in self.data[key].items())