source: trunk/lib/FilePrinter.cc @ 1330

Last change on this file since 1330 was 1330, checked in by Peter Johansson, 11 years ago

change confusing function and variable from xticks to dates (the vector holds the date/time for each revision).

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