|
|
@@ -104,6 +104,10 @@ class DataCollector:
|
|
104
|
104
|
def getActivityByHourOfDay(self):
|
|
105
|
105
|
return {}
|
|
106
|
106
|
|
|
|
107
|
+ # : get a dictionary of domains
|
|
|
108
|
+ def getDomainInfo(self, domain):
|
|
|
109
|
+ return None
|
|
|
110
|
+
|
|
107
|
111
|
##
|
|
108
|
112
|
# Get a list of authors
|
|
109
|
113
|
def getAuthors(self):
|
|
|
@@ -164,6 +168,9 @@ class GitDataCollector(DataCollector):
|
|
164
|
168
|
|
|
165
|
169
|
self.authors = {} # name -> {commits, first_commit_stamp, last_commit_stamp, last_active_day, active_days, lines_added, lines_removed}
|
|
166
|
170
|
|
|
|
171
|
+ # domains
|
|
|
172
|
+ self.domains = {} # domain -> commits
|
|
|
173
|
+
|
|
167
|
174
|
# author of the month
|
|
168
|
175
|
self.author_of_month = {} # month -> author -> commits
|
|
169
|
176
|
self.author_of_year = {} # year -> author -> commits
|
|
|
@@ -221,7 +228,7 @@ class GitDataCollector(DataCollector):
|
|
221
|
228
|
|
|
222
|
229
|
# Collect revision statistics
|
|
223
|
230
|
# Outputs "<stamp> <author>"
|
|
224
|
|
- lines = getpipeoutput(['git rev-list --pretty=format:"%at %ai %an" HEAD', 'grep -v ^commit']).split('\n')
|
|
|
231
|
+ lines = getpipeoutput(['git rev-list --pretty=format:"%at %ai %aE %an" HEAD', 'grep -v ^commit']).split('\n')
|
|
225
|
232
|
for line in lines:
|
|
226
|
233
|
parts = line.split(' ')
|
|
227
|
234
|
author = ''
|
|
|
@@ -230,8 +237,9 @@ class GitDataCollector(DataCollector):
|
|
230
|
237
|
except ValueError:
|
|
231
|
238
|
stamp = 0
|
|
232
|
239
|
timezone = parts[3]
|
|
233
|
|
- if len(parts) > 4:
|
|
234
|
|
- author = ' '.join(parts[4:])
|
|
|
240
|
+ domain = parts[4].rsplit('@', 1)[1]
|
|
|
241
|
+ if len(parts) > 5:
|
|
|
242
|
+ author = ' '.join(parts[5:])
|
|
235
|
243
|
date = datetime.datetime.fromtimestamp(float(stamp))
|
|
236
|
244
|
|
|
237
|
245
|
# First and last commit stamp
|
|
|
@@ -251,6 +259,12 @@ class GitDataCollector(DataCollector):
|
|
251
|
259
|
day = date.weekday()
|
|
252
|
260
|
self.activity_by_day_of_week[day] = self.activity_by_day_of_week.get(day, 0) + 1
|
|
253
|
261
|
|
|
|
262
|
+ # domain stats
|
|
|
263
|
+ if domain not in self.domains:
|
|
|
264
|
+ self.domains[domain] = {}
|
|
|
265
|
+ # commits
|
|
|
266
|
+ self.domains[domain]['commits'] = self.domains[domain].get('commits', 0) + 1
|
|
|
267
|
+
|
|
254
|
268
|
# hour of week
|
|
255
|
269
|
if day not in self.activity_by_hour_of_week:
|
|
256
|
270
|
self.activity_by_hour_of_week[day] = {}
|
|
|
@@ -437,6 +451,12 @@ class GitDataCollector(DataCollector):
|
|
437
|
451
|
|
|
438
|
452
|
def getCommitDeltaDays(self):
|
|
439
|
453
|
return (self.last_commit_stamp - self.first_commit_stamp) / 86400
|
|
|
454
|
+
|
|
|
455
|
+ def getDomainInfo(self, domain):
|
|
|
456
|
+ return self.domains[domain]
|
|
|
457
|
+
|
|
|
458
|
+ def getDomains(self):
|
|
|
459
|
+ return self.domains.keys()
|
|
440
|
460
|
|
|
441
|
461
|
def getFilesInCommit(self, rev):
|
|
442
|
462
|
try:
|
|
|
@@ -636,6 +656,27 @@ class HTMLReportCreator(ReportCreator):
|
|
636
|
656
|
f.write('<img src="day_of_week.png" alt="Day of Week" />')
|
|
637
|
657
|
fp.close()
|
|
638
|
658
|
|
|
|
659
|
+ # Domains
|
|
|
660
|
+ f.write(html_header(2, 'Commits by Domains'))
|
|
|
661
|
+ domains_by_commits = getkeyssortedbyvaluekey(data.domains, 'commits')
|
|
|
662
|
+ domains_by_commits.reverse() # most first
|
|
|
663
|
+ f.write('<div class="vtable"><table>')
|
|
|
664
|
+ f.write('<tr><th>Domains</th><th>Total (%)</th></tr>')
|
|
|
665
|
+ fp = open(path + '/domains.dat', 'w')
|
|
|
666
|
+ n = 0
|
|
|
667
|
+ max_domains = 10
|
|
|
668
|
+ for domain in domains_by_commits:
|
|
|
669
|
+ if n == max_domains:
|
|
|
670
|
+ break
|
|
|
671
|
+ commits = 0
|
|
|
672
|
+ n += 1
|
|
|
673
|
+ info = data.getDomainInfo(domain)
|
|
|
674
|
+ fp.write('%s %d %d\n' % (domain, n , info['commits']))
|
|
|
675
|
+ f.write('<tr><th>%s</th><td>%d (%.2f%%)</td></tr>' % (domain, info['commits'], (100.0 * info['commits'] / totalcommits)))
|
|
|
676
|
+ f.write('</table></div>')
|
|
|
677
|
+ f.write('<img src="domains.png" alt="Commits by Domains" />')
|
|
|
678
|
+ fp.close()
|
|
|
679
|
+
|
|
639
|
680
|
# Hour of Week
|
|
640
|
681
|
f.write(html_header(2, 'Hour of Week'))
|
|
641
|
682
|
f.write('<table>')
|
|
|
@@ -889,6 +930,20 @@ plot 'day_of_week.dat' using 1:2:(0.5) w boxes fs solid
|
|
889
|
930
|
""")
|
|
890
|
931
|
f.close()
|
|
891
|
932
|
|
|
|
933
|
+ # Domains
|
|
|
934
|
+ f = open(path + '/domains.plot', 'w')
|
|
|
935
|
+ f.write(GNUPLOT_COMMON)
|
|
|
936
|
+ f.write(
|
|
|
937
|
+"""
|
|
|
938
|
+set output 'domains.png'
|
|
|
939
|
+unset key
|
|
|
940
|
+unset xtics
|
|
|
941
|
+set grid y
|
|
|
942
|
+set ylabel "Commits"
|
|
|
943
|
+plot 'domains.dat' using 2:3:(0.5) with boxes fs solid, '' using 2:3:1 with labels rotate by 45 offset 0,1
|
|
|
944
|
+""")
|
|
|
945
|
+ f.close()
|
|
|
946
|
+
|
|
892
|
947
|
# Month of Year
|
|
893
|
948
|
f = open(path + '/month_of_year.plot', 'w')
|
|
894
|
949
|
f.write(GNUPLOT_COMMON)
|