lib/FilePrinter.cc

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