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
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 138     // color is calculated linearly on time, c = kt + m
395 26 Jun 07 peter 139     // 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