|
|
@@ -84,6 +84,7 @@ class GitDataCollector(DataCollector):
|
|
84
|
84
|
self.activity_by_hour_of_day = {} # hour -> commits
|
|
85
|
85
|
self.activity_by_day_of_week = {} # day -> commits
|
|
86
|
86
|
self.activity_by_month_of_year = {} # month [1-12] -> commits
|
|
|
87
|
+ self.activity_by_hour_of_week = {} # weekday -> hour -> commits
|
|
87
|
88
|
|
|
88
|
89
|
self.authors = {} # name -> {commits, first_commit_stamp, last_commit_stamp}
|
|
89
|
90
|
|
|
|
@@ -114,7 +115,8 @@ class GitDataCollector(DataCollector):
|
|
114
|
115
|
self.tags[tag] = { 'stamp': stamp, 'hash' : hash, 'date' : datetime.datetime.fromtimestamp(stamp).strftime('%Y-%m-%d') }
|
|
115
|
116
|
pass
|
|
116
|
117
|
|
|
117
|
|
- # TODO also collect statistics for "last 30 days"/"last 12 months"
|
|
|
118
|
+ # Collect revision statistics
|
|
|
119
|
+ # Outputs "<stamp> <author>"
|
|
118
|
120
|
lines = getoutput('git-rev-list --pretty=format:"%at %an" HEAD |grep -v ^commit').split('\n')
|
|
119
|
121
|
for line in lines:
|
|
120
|
122
|
# linux-2.6 says "<unknown>" for one line O_o
|
|
|
@@ -141,13 +143,21 @@ class GitDataCollector(DataCollector):
|
|
141
|
143
|
else:
|
|
142
|
144
|
self.activity_by_hour_of_day[hour] = 1
|
|
143
|
145
|
|
|
144
|
|
- # day
|
|
|
146
|
+ # day of week
|
|
145
|
147
|
day = date.weekday()
|
|
146
|
148
|
if day in self.activity_by_day_of_week:
|
|
147
|
149
|
self.activity_by_day_of_week[day] += 1
|
|
148
|
150
|
else:
|
|
149
|
151
|
self.activity_by_day_of_week[day] = 1
|
|
150
|
152
|
|
|
|
153
|
+ # hour of week
|
|
|
154
|
+ if day not in self.activity_by_hour_of_week:
|
|
|
155
|
+ self.activity_by_hour_of_week[day] = {}
|
|
|
156
|
+ if hour not in self.activity_by_hour_of_week[day]:
|
|
|
157
|
+ self.activity_by_hour_of_week[day][hour] = 1
|
|
|
158
|
+ else:
|
|
|
159
|
+ self.activity_by_hour_of_week[day][hour] += 1
|
|
|
160
|
+
|
|
151
|
161
|
# month of year
|
|
152
|
162
|
month = date.month
|
|
153
|
163
|
if month in self.activity_by_month_of_year:
|
|
|
@@ -367,6 +377,30 @@ class HTMLReportCreator(ReportCreator):
|
|
367
|
377
|
f.write('<img src="day_of_week.png" alt="Day of Week" />')
|
|
368
|
378
|
fp.close()
|
|
369
|
379
|
|
|
|
380
|
+ # Hour of Week
|
|
|
381
|
+ f.write('\n<h2>Hour of Week</h2>\n\n')
|
|
|
382
|
+ f.write('<table>')
|
|
|
383
|
+
|
|
|
384
|
+ f.write('<tr><th>Weekday</th>')
|
|
|
385
|
+ for hour in range(0, 24):
|
|
|
386
|
+ f.write('<th>%d</th>' % (hour + 1))
|
|
|
387
|
+ f.write('</tr>')
|
|
|
388
|
+
|
|
|
389
|
+ for weekday in range(0, 7):
|
|
|
390
|
+ f.write('<tr><th>%d</th>' % (weekday + 1))
|
|
|
391
|
+ for hour in range(0, 24):
|
|
|
392
|
+ try:
|
|
|
393
|
+ commits = data.activity_by_hour_of_week[weekday][hour]
|
|
|
394
|
+ except KeyError:
|
|
|
395
|
+ commits = 0
|
|
|
396
|
+ if commits != 0:
|
|
|
397
|
+ f.write('<td>%d</td>' % commits)
|
|
|
398
|
+ else:
|
|
|
399
|
+ f.write('<td></td>')
|
|
|
400
|
+ f.write('</tr>')
|
|
|
401
|
+
|
|
|
402
|
+ f.write('</table>')
|
|
|
403
|
+
|
|
370
|
404
|
# Month of Year
|
|
371
|
405
|
f.write('\n<h2>Month of Year</h2>\n\n')
|
|
372
|
406
|
f.write('<div class="vtable"><table>')
|