7 |
30 Dec 05 |
jari |
// $Id$ |
4 |
29 Dec 05 |
peter |
2 |
|
84 |
13 Mar 06 |
jari |
3 |
/* |
978 |
12 Dec 09 |
peter |
Copyright (C) 2005, 2006, 2007, 2008, 2009 Jari Häkkinen, Peter Johansson |
1635 |
30 Mar 23 |
peter |
Copyright (C) 2010, 2011, 2012, 2023 Peter Johansson |
84 |
13 Mar 06 |
jari |
6 |
|
687 |
04 Aug 08 |
peter |
This file is part of svndigest, http://dev.thep.lu.se/svndigest |
84 |
13 Mar 06 |
jari |
8 |
|
149 |
12 Aug 06 |
jari |
svndigest is free software; you can redistribute it and/or modify it |
84 |
13 Mar 06 |
jari |
under the terms of the GNU General Public License as published by |
693 |
11 Sep 08 |
jari |
the Free Software Foundation; either version 3 of the License, or |
84 |
13 Mar 06 |
jari |
(at your option) any later version. |
84 |
13 Mar 06 |
jari |
13 |
|
149 |
12 Aug 06 |
jari |
svndigest is distributed in the hope that it will be useful, but |
84 |
13 Mar 06 |
jari |
WITHOUT ANY WARRANTY; without even the implied warranty of |
149 |
12 Aug 06 |
jari |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
84 |
13 Mar 06 |
jari |
General Public License for more details. |
84 |
13 Mar 06 |
jari |
18 |
|
84 |
13 Mar 06 |
jari |
You should have received a copy of the GNU General Public License |
693 |
11 Sep 08 |
jari |
along with svndigest. If not, see <http://www.gnu.org/licenses/>. |
84 |
13 Mar 06 |
jari |
21 |
*/ |
84 |
13 Mar 06 |
jari |
22 |
|
1619 |
12 Mar 23 |
peter |
23 |
#include <config.h> |
1619 |
12 Mar 23 |
peter |
24 |
|
1290 |
12 Nov 10 |
peter |
25 |
#include "FilePrinter.h" |
1290 |
12 Nov 10 |
peter |
26 |
|
4 |
29 Dec 05 |
peter |
27 |
#include "File.h" |
303 |
11 May 07 |
peter |
28 |
|
303 |
11 May 07 |
peter |
29 |
#include "Alias.h" |
963 |
09 Dec 09 |
peter |
30 |
#include "Colors.h" |
446 |
16 Aug 07 |
peter |
31 |
#include "Configuration.h" |
380 |
21 Jun 07 |
jari |
32 |
#include "Date.h" |
858 |
19 Nov 09 |
jari |
33 |
#include "Graph.h" |
181 |
03 Sep 06 |
peter |
34 |
#include "html_utility.h" |
380 |
21 Jun 07 |
jari |
35 |
#include "HtmlStream.h" |
1234 |
23 Oct 10 |
peter |
36 |
#include "NodeVisitor.h" |
14 |
30 Dec 05 |
peter |
37 |
#include "Stats.h" |
1290 |
12 Nov 10 |
peter |
38 |
#include "StatsPlotter.h" |
380 |
21 Jun 07 |
jari |
39 |
#include "SVNblame.h" |
234 |
09 Apr 07 |
peter |
40 |
#include "SVNlog.h" |
1234 |
23 Oct 10 |
peter |
41 |
#include "TinyStats.h" |
1321 |
28 Nov 10 |
peter |
42 |
#include "utility.h" |
4 |
29 Dec 05 |
peter |
43 |
|
579 |
18 Mar 08 |
peter |
44 |
#include <algorithm> |
206 |
10 Sep 06 |
jari |
45 |
#include <cassert> |
462 |
21 Aug 07 |
jari |
46 |
#include <cstdio> |
225 |
11 Mar 07 |
peter |
47 |
#include <ctime> |
4 |
29 Dec 05 |
peter |
48 |
#include <fstream> |
4 |
29 Dec 05 |
peter |
49 |
#include <iostream> |
226 |
11 Mar 07 |
peter |
50 |
#include <map> |
622 |
23 Apr 08 |
peter |
51 |
#include <stdexcept> |
4 |
29 Dec 05 |
peter |
52 |
#include <string> |
864 |
20 Nov 09 |
jari |
53 |
#include <sstream> |
424 |
29 Jun 07 |
peter |
54 |
#include <sys/stat.h> |
4 |
29 Dec 05 |
peter |
55 |
|
4 |
29 Dec 05 |
peter |
56 |
namespace theplu{ |
149 |
12 Aug 06 |
jari |
57 |
namespace svndigest{ |
4 |
29 Dec 05 |
peter |
58 |
|
1513 |
23 Sep 12 |
peter |
59 |
FilePrinter::FilePrinter(const File& file) |
1290 |
12 Nov 10 |
peter |
60 |
: NodePrinter(), file_(file) |
343 |
19 May 07 |
peter |
61 |
{ |
343 |
19 May 07 |
peter |
62 |
} |
307 |
12 May 07 |
peter |
63 |
|
307 |
12 May 07 |
peter |
64 |
|
1290 |
12 Nov 10 |
peter |
65 |
std::string FilePrinter::blame_output_file_name(void) const |
750 |
12 Jan 09 |
peter |
66 |
{ |
1290 |
12 Nov 10 |
peter |
67 |
return "blame_output/" + node().local_path() + ".html"; |
750 |
12 Jan 09 |
peter |
68 |
} |
750 |
12 Jan 09 |
peter |
69 |
|
750 |
12 Jan 09 |
peter |
70 |
|
1290 |
12 Nov 10 |
peter |
71 |
const Node& FilePrinter::node(void) const |
834 |
07 Nov 09 |
peter |
72 |
{ |
1290 |
12 Nov 10 |
peter |
73 |
return file_; |
834 |
07 Nov 09 |
peter |
74 |
} |
834 |
07 Nov 09 |
peter |
75 |
|
834 |
07 Nov 09 |
peter |
76 |
|
1537 |
07 Oct 12 |
peter |
77 |
std::string FilePrinter::out_name(const std::string& stats_type, |
1537 |
07 Oct 12 |
peter |
78 |
const std::string& user, |
1537 |
07 Oct 12 |
peter |
79 |
const std::string& line_type) const |
1537 |
07 Oct 12 |
peter |
80 |
{ |
1537 |
07 Oct 12 |
peter |
81 |
std::string lpath = node().local_path(); |
1537 |
07 Oct 12 |
peter |
82 |
if (lpath.empty()) |
1537 |
07 Oct 12 |
peter |
83 |
lpath = "index"; |
1537 |
07 Oct 12 |
peter |
84 |
return stats_type + "/" + user + "/" + line_type + "/" + lpath + ".html"; |
1537 |
07 Oct 12 |
peter |
85 |
} |
1537 |
07 Oct 12 |
peter |
86 |
|
1537 |
07 Oct 12 |
peter |
87 |
|
1290 |
12 Nov 10 |
peter |
88 |
std::string FilePrinter::output_path(void) const |
447 |
16 Aug 07 |
peter |
89 |
{ |
1290 |
12 Nov 10 |
peter |
90 |
return output_dir()+node().name()+".html"; |
447 |
16 Aug 07 |
peter |
91 |
} |
447 |
16 Aug 07 |
peter |
92 |
|
447 |
16 Aug 07 |
peter |
93 |
|
1290 |
12 Nov 10 |
peter |
94 |
void FilePrinter::print_blame(std::ofstream& os) const |
182 |
03 Sep 06 |
peter |
95 |
{ |
1290 |
12 Nov 10 |
peter |
96 |
os << "<br /><h3>" << node().local_path() << "</h3>"; |
831 |
29 Oct 09 |
peter |
97 |
os << "<div class=\"blame_legend\">\n"; |
831 |
29 Oct 09 |
peter |
98 |
os << "<dl>\n"; |
831 |
29 Oct 09 |
peter |
99 |
os << "<dt class=\"code\"></dt><dd>Code</dd>\n"; |
831 |
29 Oct 09 |
peter |
100 |
os << "<dt class=\"comment\"></dt><dd>Comments</dd>\n"; |
831 |
29 Oct 09 |
peter |
101 |
os << "<dt class=\"other\"></dt><dd>Other</dd>\n"; |
831 |
29 Oct 09 |
peter |
102 |
os << "</dl>\n</div>\n"; |
207 |
11 Sep 06 |
peter |
103 |
os << "<table class=\"blame\">\n"; |
379 |
20 Jun 07 |
jari |
104 |
os << "<thead>\n"; |
379 |
20 Jun 07 |
jari |
105 |
os << "<tr>\n"; |
403 |
28 Jun 07 |
peter |
106 |
os << "<th class=\"rev\">Rev</th>\n"; |
380 |
21 Jun 07 |
jari |
107 |
os << "<th class=\"date\">Date</th>\n"; |
380 |
21 Jun 07 |
jari |
108 |
os << "<th class=\"author\">Author</th>\n"; |
403 |
28 Jun 07 |
peter |
109 |
os << "<th class=\"line\">Line</th>\n"; |
401 |
28 Jun 07 |
jari |
110 |
os << "<th></th>\n"; |
379 |
20 Jun 07 |
jari |
111 |
os << "</tr>\n</thead>\n"; |
379 |
20 Jun 07 |
jari |
112 |
os << "<tbody>\n"; |
380 |
21 Jun 07 |
jari |
113 |
HtmlStream hs(os); |
1290 |
12 Nov 10 |
peter |
114 |
SVNblame blame(node().path_); |
1290 |
12 Nov 10 |
peter |
115 |
LineTypeParser parser(node().path_); |
536 |
27 Dec 07 |
peter |
116 |
while (blame.valid()) { |
536 |
27 Dec 07 |
peter |
117 |
parser.parse(blame.line()); |
536 |
27 Dec 07 |
peter |
118 |
blame.next_line(); |
536 |
27 Dec 07 |
peter |
119 |
} |
536 |
27 Dec 07 |
peter |
120 |
blame.reset(); |
536 |
27 Dec 07 |
peter |
121 |
|
1513 |
23 Sep 12 |
peter |
122 |
std::vector<LineTypeParser::line_type>::const_iterator |
403 |
28 Jun 07 |
peter |
123 |
line_type(parser.type().begin()); |
399 |
27 Jun 07 |
peter |
124 |
int last=0; |
399 |
27 Jun 07 |
peter |
125 |
int first=0; |
399 |
27 Jun 07 |
peter |
126 |
bool using_dates=true; |
858 |
19 Nov 09 |
jari |
127 |
if (!Graph::date_xticks()) { |
399 |
27 Jun 07 |
peter |
128 |
using_dates=false; |
1287 |
09 Nov 10 |
peter |
129 |
first = Graph::rev_min(); |
1287 |
09 Nov 10 |
peter |
130 |
last = Graph::rev_max(); |
399 |
27 Jun 07 |
peter |
131 |
} |
399 |
27 Jun 07 |
peter |
132 |
else { |
1330 |
27 Jan 11 |
peter |
133 |
first = Graph::dates()[Graph::rev_min()]; |
1418 |
25 Oct 11 |
peter |
134 |
assert(static_cast<size_t>(Graph::rev_max()) < Graph::dates().size()); |
1330 |
27 Jan 11 |
peter |
135 |
last = Graph::dates()[Graph::rev_max()]; |
399 |
27 Jun 07 |
peter |
136 |
} |
1287 |
09 Nov 10 |
peter |
137 |
assert(last>first); |
395 |
26 Jun 07 |
peter |
// color is calculated linearly on time, c = kt + m |
395 |
26 Jun 07 |
peter |
// brightest color (for oldest rev in log) is set to 192. |
399 |
27 Jun 07 |
peter |
140 |
double k = 192.0/(first-last); |
1513 |
23 Sep 12 |
peter |
141 |
double m = -last*k; |
381 |
21 Jun 07 |
jari |
142 |
while (blame.valid()) { |
399 |
27 Jun 07 |
peter |
143 |
std::string color; |
1286 |
09 Nov 10 |
peter |
144 |
Date date(blame.date()); |
399 |
27 Jun 07 |
peter |
145 |
if (using_dates) |
1286 |
09 Nov 10 |
peter |
146 |
color = hex(static_cast<int>(k*date.seconds()+m),2); |
399 |
27 Jun 07 |
peter |
147 |
else |
400 |
28 Jun 07 |
peter |
148 |
color = hex(static_cast<int>(k*blame.revision()+m),2); |
498 |
14 Oct 07 |
peter |
149 |
os << "<tr>\n<td class=\"rev\">"; |
498 |
14 Oct 07 |
peter |
150 |
std::stringstream color_ss; |
1513 |
23 Sep 12 |
peter |
151 |
color_ss << "#" << color << color << color; |
498 |
14 Oct 07 |
peter |
152 |
os << "<font color=\"" << color_ss.str() << "\">" |
498 |
14 Oct 07 |
peter |
153 |
<< trac_revision(blame.revision(), color_ss.str()) |
1513 |
23 Sep 12 |
peter |
154 |
<< "</font></td>\n<td class=\"date\"><font color=\"#" << color |
401 |
28 Jun 07 |
jari |
155 |
<< color << color << "\">" ; |
1286 |
09 Nov 10 |
peter |
156 |
hs << date("%d %b %y"); |
401 |
28 Jun 07 |
jari |
157 |
os << "</font></td>\n<td class=\"author\">"; |
1513 |
23 Sep 12 |
peter |
158 |
const std::string& author_color = |
963 |
09 Dec 09 |
peter |
159 |
Colors::instance().color_str(blame.author()); |
963 |
09 Dec 09 |
peter |
160 |
assert(!author_color.empty()); |
963 |
09 Dec 09 |
peter |
161 |
os << "<font color=\"#" << author_color << "\">"; |
381 |
21 Jun 07 |
jari |
162 |
hs << blame.author(); |
403 |
28 Jun 07 |
peter |
163 |
os << "</td>\n<td class=\""; |
403 |
28 Jun 07 |
peter |
164 |
assert(line_type!=parser.type().end()); |
552 |
08 Jan 08 |
peter |
165 |
if (*line_type==LineTypeParser::other) |
403 |
28 Jun 07 |
peter |
166 |
os << "line-other"; |
1513 |
23 Sep 12 |
peter |
167 |
else if (*line_type==LineTypeParser::comment || |
1513 |
23 Sep 12 |
peter |
168 |
*line_type==LineTypeParser::copyright) |
403 |
28 Jun 07 |
peter |
169 |
os << "line-comment"; |
622 |
23 Apr 08 |
peter |
170 |
else if (*line_type==LineTypeParser::code) |
622 |
23 Apr 08 |
peter |
171 |
os << "line-code"; |
623 |
23 Apr 08 |
peter |
172 |
else { |
1290 |
12 Nov 10 |
peter |
173 |
std::string msg="FilePrinter::print_blame(): unexpected line type found"; |
623 |
23 Apr 08 |
peter |
174 |
throw std::runtime_error(msg); |
623 |
23 Apr 08 |
peter |
175 |
} |
403 |
28 Jun 07 |
peter |
176 |
os << "\">" << blame.line_no()+1 |
401 |
28 Jun 07 |
jari |
177 |
<< "</td>\n<td>"; |
381 |
21 Jun 07 |
jari |
178 |
hs << blame.line(); |
380 |
21 Jun 07 |
jari |
179 |
os << "</td>\n</tr>\n"; |
381 |
21 Jun 07 |
jari |
180 |
blame.next_line(); |
403 |
28 Jun 07 |
peter |
181 |
++line_type; |
380 |
21 Jun 07 |
jari |
182 |
} |
379 |
20 Jun 07 |
jari |
183 |
os << "</tbody>\n"; |
207 |
11 Sep 06 |
peter |
184 |
os << "</table>\n"; |
207 |
11 Sep 06 |
peter |
185 |
} |
207 |
11 Sep 06 |
peter |
186 |
|
207 |
11 Sep 06 |
peter |
187 |
|
1513 |
23 Sep 12 |
peter |
188 |
void FilePrinter::print_core(const bool verbose) const |
379 |
20 Jun 07 |
jari |
189 |
{ |
1288 |
09 Nov 10 |
peter |
190 |
if (!Configuration::instance().output_blame_information()) |
1288 |
09 Nov 10 |
peter |
191 |
return; |
1234 |
23 Oct 10 |
peter |
192 |
mkdir_p(directory_name(blame_output_file_name())); |
750 |
12 Jan 09 |
peter |
193 |
std::ofstream os(blame_output_file_name().c_str()); |
750 |
12 Jan 09 |
peter |
194 |
assert(os.good()); |
1538 |
07 Oct 12 |
peter |
195 |
print_html_start(os, "svndigest", file_.level_+1,file_.revision_min()); |
1288 |
09 Nov 10 |
peter |
196 |
print_blame(os); |
750 |
12 Jan 09 |
peter |
197 |
print_footer(os); |
750 |
12 Jan 09 |
peter |
198 |
os.close(); |
379 |
20 Jun 07 |
jari |
199 |
} |
379 |
20 Jun 07 |
jari |
200 |
|
379 |
20 Jun 07 |
jari |
201 |
|
1513 |
23 Sep 12 |
peter |
202 |
void FilePrinter::print_core(const std::string& stats_type, |
1537 |
07 Oct 12 |
peter |
203 |
const std::string& user, |
1537 |
07 Oct 12 |
peter |
204 |
const std::string& line_type, |
1537 |
07 Oct 12 |
peter |
205 |
const SVNlog& log) const |
379 |
20 Jun 07 |
jari |
206 |
{ |
1290 |
12 Nov 10 |
peter |
207 |
std::string lpath = node().local_path(); |
635 |
23 May 08 |
peter |
208 |
if (lpath.empty()) |
635 |
23 May 08 |
peter |
209 |
lpath = "index"; |
1007 |
03 Jan 10 |
peter |
210 |
std::string imagefile = stats_type+"/"+"images/"+line_type+"/"+lpath; |
1537 |
07 Oct 12 |
peter |
211 |
std::string html_name = out_name(stats_type, user, line_type); |
1234 |
23 Oct 10 |
peter |
212 |
mkdir_p(directory_name(html_name)); |
1234 |
23 Oct 10 |
peter |
213 |
mkdir_p(directory_name(imagefile)); |
379 |
20 Jun 07 |
jari |
214 |
std::ofstream os(html_name.c_str()); |
1234 |
23 Oct 10 |
peter |
215 |
assert(os); |
1537 |
07 Oct 12 |
peter |
216 |
print_header(os, node().name(), file_.level_+3, user, line_type, |
1538 |
07 Oct 12 |
peter |
217 |
lpath+".html", stats_type, file_.revision_min()); |
379 |
20 Jun 07 |
jari |
218 |
path_anchor(os); |
864 |
20 Nov 09 |
jari |
219 |
|
864 |
20 Nov 09 |
jari |
220 |
std::stringstream ss; |
1290 |
12 Nov 10 |
peter |
221 |
for (size_t i=0; i<file_.level_; ++i) |
864 |
20 Nov 09 |
jari |
222 |
ss << "../"; |
864 |
20 Nov 09 |
jari |
223 |
ss << "../../../"; |
379 |
20 Jun 07 |
jari |
224 |
if (user=="all") |
1614 |
15 Feb 23 |
peter |
225 |
ss << StatsPlotter(file_.stats_[stats_type]).plot(imagefile,line_type, |
1614 |
15 Feb 23 |
peter |
226 |
file_.local_path()); |
379 |
20 Jun 07 |
jari |
227 |
else |
864 |
20 Nov 09 |
jari |
228 |
ss << imagefile; |
1513 |
23 Sep 12 |
peter |
229 |
os << "<p class=\"plot\">\n"; |
1024 |
10 Jan 10 |
peter |
230 |
os << image(ss.str()); |
864 |
20 Nov 09 |
jari |
231 |
os << "</p>\n"; |
379 |
20 Jun 07 |
jari |
232 |
|
1290 |
12 Nov 10 |
peter |
233 |
print_author_summary(os, file_.stats_[stats_type], line_type, log); |
400 |
28 Jun 07 |
peter |
234 |
os << "\n"; |
1288 |
09 Nov 10 |
peter |
235 |
if (Configuration::instance().output_blame_information()) |
1288 |
09 Nov 10 |
peter |
236 |
os << "<h3>" |
1513 |
23 Sep 12 |
peter |
237 |
<< anchor(blame_output_file_name(), "Blame Information", file_.level_+3) |
1288 |
09 Nov 10 |
peter |
238 |
<< "</h3>\n"; |
379 |
20 Jun 07 |
jari |
239 |
|
379 |
20 Jun 07 |
jari |
240 |
print_footer(os); |
1513 |
23 Sep 12 |
peter |
241 |
os.close(); |
379 |
20 Jun 07 |
jari |
242 |
} |
379 |
20 Jun 07 |
jari |
243 |
|
1234 |
23 Oct 10 |
peter |
244 |
|
149 |
12 Aug 06 |
jari |
245 |
}} // end of namespace svndigest and namespace theplu |