|
|
@@ -737,7 +737,7 @@ class HTMLReportCreator(ReportCreator):
|
|
737
|
737
|
binarypath = os.path.dirname(os.path.abspath(__file__))
|
|
738
|
738
|
secondarypath = os.path.join(binarypath, '..', 'share', 'gitstats')
|
|
739
|
739
|
basedirs = [binarypath, secondarypath, '/usr/share/gitstats']
|
|
740
|
|
- for file in (conf['style'], 'sortable.js', 'arrow-up.gif', 'arrow-down.gif', 'arrow-none.gif'):
|
|
|
740
|
+ for file in ('bootstrap.js','bootstrap.css','gitstats.css', 'sortable.js', 'arrow-up.gif', 'arrow-down.gif', 'arrow-none.gif'):
|
|
741
|
741
|
for base in basedirs:
|
|
742
|
742
|
src = base + '/' + file
|
|
743
|
743
|
if os.path.exists(src):
|
|
|
@@ -754,7 +754,7 @@ class HTMLReportCreator(ReportCreator):
|
|
754
|
754
|
|
|
755
|
755
|
self.printNav(f)
|
|
756
|
756
|
|
|
757
|
|
- f.write('<dl>')
|
|
|
757
|
+ f.write('<div><div class="card-body"><dl>')
|
|
758
|
758
|
f.write('<dt>Project name</dt><dd>%s</dd>' % (data.projectname))
|
|
759
|
759
|
f.write('<dt>Generated</dt><dd>%s (in %d seconds)</dd>' % (datetime.datetime.now().strftime(format), time.time() - data.getStampCreated()))
|
|
760
|
760
|
f.write('<dt>Generator</dt><dd><a href="http://gitstats.sourceforge.net/">GitStats</a> (version %s), %s, %s</dd>' % (getversion(), getgitversion(), getgnuplotversion()))
|
|
|
@@ -764,7 +764,7 @@ class HTMLReportCreator(ReportCreator):
|
|
764
|
764
|
f.write('<dt>Total Lines of Code</dt><dd>%s (%d added, %d removed)</dd>' % (data.getTotalLOC(), data.total_lines_added, data.total_lines_removed))
|
|
765
|
765
|
f.write('<dt>Total Commits</dt><dd>%s (average %.1f commits per active day, %.1f per all days)</dd>' % (data.getTotalCommits(), float(data.getTotalCommits()) / len(data.getActiveDays()), float(data.getTotalCommits()) / data.getCommitDeltaDays()))
|
|
766
|
766
|
f.write('<dt>Authors</dt><dd>%s (average %.1f commits per author)</dd>' % (data.getTotalAuthors(), (1.0 * data.getTotalCommits()) / data.getTotalAuthors()))
|
|
767
|
|
- f.write('</dl>')
|
|
|
767
|
+ f.write('</dl></div')
|
|
768
|
768
|
|
|
769
|
769
|
f.write('</body>\n</html>')
|
|
770
|
770
|
f.close()
|
|
|
@@ -795,7 +795,7 @@ class HTMLReportCreator(ReportCreator):
|
|
795
|
795
|
stampcur -= deltaweek
|
|
796
|
796
|
|
|
797
|
797
|
# top row: commits & bar
|
|
798
|
|
- f.write('<table class="noborders"><tr>')
|
|
|
798
|
+ f.write('<div><div class="card-body"><table class="noborders"><tr>')
|
|
799
|
799
|
for i in range(0, WEEKS):
|
|
800
|
800
|
commits = 0
|
|
801
|
801
|
if weeks[i] in data.activity_by_year_week:
|
|
|
@@ -811,12 +811,12 @@ class HTMLReportCreator(ReportCreator):
|
|
811
|
811
|
f.write('</tr><tr>')
|
|
812
|
812
|
for i in range(0, WEEKS):
|
|
813
|
813
|
f.write('<td>%s</td>' % (WEEKS - i))
|
|
814
|
|
- f.write('</tr></table>')
|
|
|
814
|
+ f.write('</tr></table></div>')
|
|
815
|
815
|
|
|
816
|
816
|
# Hour of Day
|
|
817
|
817
|
f.write(html_header(2, 'Hour of Day'))
|
|
818
|
818
|
hour_of_day = data.getActivityByHourOfDay()
|
|
819
|
|
- f.write('<table><tr><th>Hour</th>')
|
|
|
819
|
+ f.write('<div><div class="card-body"><table><tr><th>Hour</th>')
|
|
820
|
820
|
for i in range(0, 24):
|
|
821
|
821
|
f.write('<th>%d</th>' % i)
|
|
822
|
822
|
f.write('</tr>\n<tr><th>Commits</th>')
|
|
|
@@ -838,8 +838,8 @@ class HTMLReportCreator(ReportCreator):
|
|
838
|
838
|
f.write('<td style="background-color: rgb(%d, 0, 0)">%.2f</td>' % (r, (100.0 * hour_of_day[i]) / totalcommits))
|
|
839
|
839
|
else:
|
|
840
|
840
|
f.write('<td>0.00</td>')
|
|
841
|
|
- f.write('</tr></table>')
|
|
842
|
|
- f.write('<img src="hour_of_day.png" alt="Hour of Day">')
|
|
|
841
|
+ f.write('</tr></table></div>')
|
|
|
842
|
+ f.write('<img src="hour_of_day.png" alt="Hour of Day" />')
|
|
843
|
843
|
fg = open(path + '/hour_of_day.dat', 'w')
|
|
844
|
844
|
for i in range(0, 24):
|
|
845
|
845
|
if i in hour_of_day:
|
|
|
@@ -872,7 +872,7 @@ class HTMLReportCreator(ReportCreator):
|
|
872
|
872
|
|
|
873
|
873
|
# Hour of Week
|
|
874
|
874
|
f.write(html_header(2, 'Hour of Week'))
|
|
875
|
|
- f.write('<table>')
|
|
|
875
|
+ f.write('<div><div class="card-body"><table>')
|
|
876
|
876
|
|
|
877
|
877
|
f.write('<tr><th>Weekday</th>')
|
|
878
|
878
|
for hour in range(0, 24):
|
|
|
@@ -895,7 +895,7 @@ class HTMLReportCreator(ReportCreator):
|
|
895
|
895
|
f.write('<td></td>')
|
|
896
|
896
|
f.write('</tr>')
|
|
897
|
897
|
|
|
898
|
|
- f.write('</table>')
|
|
|
898
|
+ f.write('</table></div>')
|
|
899
|
899
|
|
|
900
|
900
|
# Month of Year
|
|
901
|
901
|
f.write(html_header(2, 'Month of Year'))
|
|
|
@@ -938,7 +938,7 @@ class HTMLReportCreator(ReportCreator):
|
|
938
|
938
|
|
|
939
|
939
|
# Commits by timezone
|
|
940
|
940
|
f.write(html_header(2, 'Commits by Timezone'))
|
|
941
|
|
- f.write('<table><tr>')
|
|
|
941
|
+ f.write('<div><div class="card-body"><table><tr>')
|
|
942
|
942
|
f.write('<th>Timezone</th><th>Commits</th>')
|
|
943
|
943
|
f.write('</tr>')
|
|
944
|
944
|
max_commits_on_tz = max(data.commits_by_timezone.values())
|
|
|
@@ -946,8 +946,7 @@ class HTMLReportCreator(ReportCreator):
|
|
946
|
946
|
commits = data.commits_by_timezone[i]
|
|
947
|
947
|
r = 127 + int((float(commits) / max_commits_on_tz) * 128)
|
|
948
|
948
|
f.write('<tr><th>%s</th><td style="background-color: rgb(%d, 0, 0)">%d</td></tr>' % (i, r, commits))
|
|
949
|
|
- f.write('</table>')
|
|
950
|
|
-
|
|
|
949
|
+ f.write('</tr></table></div>')
|
|
951
|
950
|
f.write('</body></html>')
|
|
952
|
951
|
f.close()
|
|
953
|
952
|
|
|
|
@@ -962,12 +961,12 @@ class HTMLReportCreator(ReportCreator):
|
|
962
|
961
|
# Authors :: List of authors
|
|
963
|
962
|
f.write(html_header(2, 'List of Authors'))
|
|
964
|
963
|
|
|
965
|
|
- f.write('<table class="authors sortable" id="authors">')
|
|
|
964
|
+ f.write('<div><div class="card-body"><table class="authors sortable" id="authors">')
|
|
966
|
965
|
f.write('<tr><th>Author</th><th>Commits (%)</th><th>+ lines</th><th>- lines</th><th>First commit</th><th>Last commit</th><th class="unsortable">Age</th><th>Active days</th><th># by commits</th></tr>')
|
|
967
|
966
|
for author in data.getAuthors(conf['max_authors']):
|
|
968
|
967
|
info = data.getAuthorInfo(author)
|
|
969
|
968
|
f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td></tr>' % (author, info['commits'], info['commits_frac'], info['lines_added'], info['lines_removed'], info['date_first'], info['date_last'], info['timedelta'], len(info['active_days']), info['place_by_commits']))
|
|
970
|
|
- f.write('</table>')
|
|
|
969
|
+ f.write('</table></div>')
|
|
971
|
970
|
|
|
972
|
971
|
allauthors = data.getAuthors()
|
|
973
|
972
|
if len(allauthors) > conf['max_authors']:
|
|
|
@@ -1018,7 +1017,7 @@ class HTMLReportCreator(ReportCreator):
|
|
1018
|
1017
|
|
|
1019
|
1018
|
# Authors :: Author of Month
|
|
1020
|
1019
|
f.write(html_header(2, 'Author of Month'))
|
|
1021
|
|
- f.write('<table class="sortable" id="aom">')
|
|
|
1020
|
+ f.write('<div><div class="card-body"><table class="sortable" id="aom">')
|
|
1022
|
1021
|
f.write('<tr><th>Month</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
|
|
1023
|
1022
|
for yymm in reversed(sorted(data.author_of_month.keys())):
|
|
1024
|
1023
|
authordict = data.author_of_month[yymm]
|
|
|
@@ -1028,10 +1027,10 @@ class HTMLReportCreator(ReportCreator):
|
|
1028
|
1027
|
next = ', '.join(authors[1:conf['authors_top']+1])
|
|
1029
|
1028
|
f.write('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yymm, authors[0], commits, (100.0 * commits) / data.commits_by_month[yymm], data.commits_by_month[yymm], next, len(authors)))
|
|
1030
|
1029
|
|
|
1031
|
|
- f.write('</table>')
|
|
|
1030
|
+ f.write('</table></div>')
|
|
1032
|
1031
|
|
|
1033
|
1032
|
f.write(html_header(2, 'Author of Year'))
|
|
1034
|
|
- f.write('<table class="sortable" id="aoy"><tr><th>Year</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
|
|
|
1033
|
+ f.write('<div><div class="card-body"><table class="sortable" id="aoy"><tr><th>Year</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
|
|
1035
|
1034
|
for yy in reversed(sorted(data.author_of_year.keys())):
|
|
1036
|
1035
|
authordict = data.author_of_year[yy]
|
|
1037
|
1036
|
authors = getkeyssortedbyvalues(authordict)
|
|
|
@@ -1039,7 +1038,7 @@ class HTMLReportCreator(ReportCreator):
|
|
1039
|
1038
|
commits = data.author_of_year[yy][authors[0]]
|
|
1040
|
1039
|
next = ', '.join(authors[1:conf['authors_top']+1])
|
|
1041
|
1040
|
f.write('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yy, authors[0], commits, (100.0 * commits) / data.commits_by_year[yy], data.commits_by_year[yy], next, len(authors)))
|
|
1042
|
|
- f.write('</table>')
|
|
|
1041
|
+ f.write('</table></div>')
|
|
1043
|
1042
|
|
|
1044
|
1043
|
# Domains
|
|
1045
|
1044
|
f.write(html_header(2, 'Commits by Domains'))
|
|
|
@@ -1071,14 +1070,14 @@ class HTMLReportCreator(ReportCreator):
|
|
1071
|
1070
|
f.write('<h1>Files</h1>')
|
|
1072
|
1071
|
self.printNav(f)
|
|
1073
|
1072
|
|
|
1074
|
|
- f.write('<dl>\n')
|
|
|
1073
|
+ f.write('<div><div class="card-body"><dl>\n')
|
|
1075
|
1074
|
f.write('<dt>Total files</dt><dd>%d</dd>' % data.getTotalFiles())
|
|
1076
|
1075
|
f.write('<dt>Total lines</dt><dd>%d</dd>' % data.getTotalLOC())
|
|
1077
|
1076
|
try:
|
|
1078
|
1077
|
f.write('<dt>Average file size</dt><dd>%.2f bytes</dd>' % (float(data.getTotalSize()) / data.getTotalFiles()))
|
|
1079
|
1078
|
except ZeroDivisionError:
|
|
1080
|
1079
|
pass
|
|
1081
|
|
- f.write('</dl>\n')
|
|
|
1080
|
+ f.write('</dl></div>\n')
|
|
1082
|
1081
|
|
|
1083
|
1082
|
# Files :: File count by date
|
|
1084
|
1083
|
f.write(html_header(2, 'File count by date'))
|
|
|
@@ -1101,7 +1100,7 @@ class HTMLReportCreator(ReportCreator):
|
|
1101
|
1100
|
|
|
1102
|
1101
|
# Files :: Extensions
|
|
1103
|
1102
|
f.write(html_header(2, 'Extensions'))
|
|
1104
|
|
- f.write('<table class="sortable" id="ext"><tr><th>Extension</th><th>Files (%)</th><th>Lines (%)</th><th>Lines/file</th></tr>')
|
|
|
1103
|
+ f.write('<div><div class="card-body"><table class="sortable" id="ext"><tr><th>Extension</th><th>Files (%)</th><th>Lines (%)</th><th>Lines/file</th></tr>')
|
|
1105
|
1104
|
for ext in sorted(data.extensions.keys()):
|
|
1106
|
1105
|
files = data.extensions[ext]['files']
|
|
1107
|
1106
|
lines = data.extensions[ext]['lines']
|
|
|
@@ -1110,7 +1109,7 @@ class HTMLReportCreator(ReportCreator):
|
|
1110
|
1109
|
except ZeroDivisionError:
|
|
1111
|
1110
|
loc_percentage = 0
|
|
1112
|
1111
|
f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d (%.2f%%)</td><td>%d</td></tr>' % (ext, files, (100.0 * files) / data.getTotalFiles(), lines, loc_percentage, lines / files))
|
|
1113
|
|
- f.write('</table>')
|
|
|
1112
|
+ f.write('</table></div>')
|
|
1114
|
1113
|
|
|
1115
|
1114
|
f.write('</body></html>')
|
|
1116
|
1115
|
f.close()
|
|
|
@@ -1122,9 +1121,9 @@ class HTMLReportCreator(ReportCreator):
|
|
1122
|
1121
|
f.write('<h1>Lines</h1>')
|
|
1123
|
1122
|
self.printNav(f)
|
|
1124
|
1123
|
|
|
1125
|
|
- f.write('<dl>\n')
|
|
|
1124
|
+ f.write('<div><div class="card-body"><dl>\n')
|
|
1126
|
1125
|
f.write('<dt>Total lines</dt><dd>%d</dd>' % data.getTotalLOC())
|
|
1127
|
|
- f.write('</dl>\n')
|
|
|
1126
|
+ f.write('</dl></div>\n')
|
|
1128
|
1127
|
|
|
1129
|
1128
|
f.write(html_header(2, 'Lines of Code'))
|
|
1130
|
1129
|
f.write('<img src="lines_of_code.png" alt="Lines of Code">')
|
|
|
@@ -1144,13 +1143,13 @@ class HTMLReportCreator(ReportCreator):
|
|
1144
|
1143
|
f.write('<h1>Tags</h1>')
|
|
1145
|
1144
|
self.printNav(f)
|
|
1146
|
1145
|
|
|
1147
|
|
- f.write('<dl>')
|
|
|
1146
|
+ f.write('<div><div class="card-body"><dl>')
|
|
1148
|
1147
|
f.write('<dt>Total tags</dt><dd>%d</dd>' % len(data.tags))
|
|
1149
|
1148
|
if len(data.tags) > 0:
|
|
1150
|
1149
|
f.write('<dt>Average commits per tag</dt><dd>%.2f</dd>' % (1.0 * data.getTotalCommits() / len(data.tags)))
|
|
1151
|
|
- f.write('</dl>')
|
|
|
1150
|
+ f.write('</dl></div>')
|
|
1152
|
1151
|
|
|
1153
|
|
- f.write('<table class="tags">')
|
|
|
1152
|
+ f.write('<div><div class="card-body"><table class="tags">')
|
|
1154
|
1153
|
f.write('<tr><th>Name</th><th>Date</th><th>Commits</th><th>Authors</th></tr>')
|
|
1155
|
1154
|
# sort the tags by date desc
|
|
1156
|
1155
|
tags_sorted_by_date_desc = map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), data.tags.items()))))
|
|
|
@@ -1160,7 +1159,7 @@ class HTMLReportCreator(ReportCreator):
|
|
1160
|
1159
|
for i in reversed(self.authors_by_commits):
|
|
1161
|
1160
|
authorinfo.append('%s (%d)' % (i, data.tags[tag]['authors'][i]))
|
|
1162
|
1161
|
f.write('<tr><td>%s</td><td>%s</td><td>%d</td><td>%s</td></tr>' % (tag, data.tags[tag]['date'], data.tags[tag]['commits'], ', '.join(authorinfo)))
|
|
1163
|
|
- f.write('</table>')
|
|
|
1162
|
+ f.write('</table></div>')
|
|
1164
|
1163
|
|
|
1165
|
1164
|
f.write('</body></html>')
|
|
1166
|
1165
|
f.close()
|
|
|
@@ -1379,25 +1378,27 @@ plot """
|
|
1379
|
1378
|
<head>
|
|
1380
|
1379
|
<meta charset="UTF-8">
|
|
1381
|
1380
|
<title>GitStats - %s</title>
|
|
1382
|
|
- <link rel="stylesheet" href="%s" type="text/css">
|
|
1383
|
|
- <meta name="generator" content="GitStats %s">
|
|
|
1381
|
+ <link rel="stylesheet" href="%s" type="text/css" />
|
|
|
1382
|
+ <link rel="stylesheet" href="bootstrap.css" type="text/css" />
|
|
|
1383
|
+ <meta name="generator" content="GitStats %s" />
|
|
1384
|
1384
|
<script type="text/javascript" src="sortable.js"></script>
|
|
|
1385
|
+ <script type="text/javascript" src="bootstrap.js"></script>
|
|
1385
|
1386
|
</head>
|
|
1386
|
1387
|
<body>
|
|
1387
|
1388
|
""" % (self.title, conf['style'], getversion()))
|
|
1388
|
1389
|
|
|
1389
|
1390
|
def printNav(self, f):
|
|
1390
|
1391
|
f.write("""
|
|
1391
|
|
-<div class="nav">
|
|
1392
|
|
-<ul>
|
|
1393
|
|
-<li><a href="index.html">General</a></li>
|
|
1394
|
|
-<li><a href="activity.html">Activity</a></li>
|
|
1395
|
|
-<li><a href="authors.html">Authors</a></li>
|
|
1396
|
|
-<li><a href="files.html">Files</a></li>
|
|
1397
|
|
-<li><a href="lines.html">Lines</a></li>
|
|
1398
|
|
-<li><a href="tags.html">Tags</a></li>
|
|
1399
|
|
-</ul>
|
|
1400
|
|
-</div>
|
|
|
1392
|
+<nav aria-label="breadcrumb">
|
|
|
1393
|
+<ol class="breadcrumb">
|
|
|
1394
|
+ <li class="breadcrumb-item" aria-current="page"><a href="index.html">General</a></li>
|
|
|
1395
|
+ <li class="breadcrumb-item" aria-current="page"><a href="activity.html">Activity</a></li>
|
|
|
1396
|
+ <li class="breadcrumb-item" aria-current="page"><a href="authors.html">Authors</a></li>
|
|
|
1397
|
+ <li class="breadcrumb-item" aria-current="page"><a href="files.html">Files</a></li>
|
|
|
1398
|
+ <li class="breadcrumb-item" aria-current="page"><a href="lines.html">Lines</a></li>
|
|
|
1399
|
+ <li class="breadcrumb-item" aria-current="page"><a href="tags.html">Tags</a></li>
|
|
|
1400
|
+</ol>
|
|
|
1401
|
+</nav>
|
|
1401
|
1402
|
""")
|
|
1402
|
1403
|
|
|
1403
|
1404
|
def usage():
|