source: trunk/lib/first_page.cc @ 497

Last change on this file since 497 was 497, checked in by Peter Johansson, 14 years ago

preparing for more statistics by adding StatsType layer in structure on top of previous structure, i.e., NewStructure? = StatsType/OldStructure?

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.8 KB
Line 
1// $Id: first_page.cc 497 2007-10-14 04:58:06Z peter $
2
3/*
4  Copyright (C) 2006 Peter Johansson
5  Copyright (C) 2007 Jari Häkkinen, Peter Johansson
6
7  This file is part of svndigest, http://trac.thep.lu.se/trac/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 2 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 this program; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22  02111-1307, USA.
23*/
24
25#include "first_page.h"
26
27#include "Commitment.h"
28#include "Configuration.h"
29#include "Date.h"
30#include "HtmlStream.h"
31#include "html_utility.h"
32#include "Stats.h"
33#include "SVNlog.h"
34#include "Trac.h"
35#include "utility.h"
36#include <config.h> // this header file is created by configure
37
38#include <algorithm>
39#include <cassert>
40#include <fstream>
41#include <iostream>
42#include <sstream>
43#include <stdexcept>
44#include <string>
45#include <sys/param.h>
46#include <unistd.h>
47#include <vector>
48
49namespace theplu{
50namespace svndigest{
51
52  void print_main_page(const std::string& dir, const SVNlog& log,
53                       const Stats& stats, std::string url)
54  {
55    std::string filename="index.html";
56    std::ofstream os(filename.c_str());
57    print_header(os, dir, 0, "all", "main", "index.html");
58
59    using namespace std;
60    set<string> authors;
61    authors.insert(log.author().begin(), log.author().end());
62    // erase invalid authors
63    authors.erase("");
64    authors.erase("no author");
65
66    vector<Commitment> latest_commit;
67    latest_commit.reserve(authors.size());
68    for (set<string>::const_iterator i(authors.begin()); i!=authors.end(); ++i)
69      latest_commit.push_back(log.latest_commit(*i));
70
71    print_summary_plot(os, stats);
72    print_general_information(os, log, authors.size(), url);
73    sort(latest_commit.begin(), latest_commit.end(), GreaterRevision());
74    print_authors(os, latest_commit, stats);
75    print_recent_logs(os, log);
76    os << "<hr width=100% />";
77    print_footer(os);
78    os.close();
79  }
80
81  void print_general_information(std::ostream& os, const SVNlog& log, 
82                                 size_t nof_authors, std::string url)
83  { 
84    assert(log.date().size());
85    Date begin(log.date()[0]);
86    Date end(log.date().back());
87    std::string timefmt("%a, %e %b %Y  %H:%M:%S");
88
89    os << "<div class=\"main\">" 
90       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
91       << "General Information"
92       << "</th></tr></thead>\n"
93       << "<tbody>\n"
94       << "<tr><td>URL:</td><td>" 
95       << url << "</td></tr>\n"
96       << "<tr><td>First Revision Date:</td><td>" 
97       << begin(timefmt) << "</td></tr>\n"
98       << "<tr><td>Latest Revision Date:</td><td>" 
99       << end(timefmt) << "</td></tr>\n"
100       << "<tr><td>Age:</td><td>"; 
101    os << end.difftime(begin);
102    os << "</td></tr>\n"
103       << "<tr><td>Smallest Revision:</td><td>" << log.revision()[0] 
104       << "</td></tr>\n"
105       << "<tr><td>Largest Revision:</td><td>" << log.revision().back() 
106       << "</td></tr>\n"
107       << "<tr><td>Revision Count:</td><td>" << log.revision().size() 
108       << "</td></tr>\n"
109       << "<tr><td>Number of Authors:</td><td>" << nof_authors
110       << "</td></tr>\n"
111       << "</tbody>\n"
112       << "</table></div>\n";
113  }
114
115
116  void print_authors(std::ostream& os, 
117                     const std::vector<Commitment>& lc,
118                     const Stats& stats)
119  {
120    os << "<div class=\"main\">"
121       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
122       << "Authors"
123       << "</th></tr></thead>\n";
124
125    os << "<tr><td>Author</td>" 
126       << "<td>Number of Lines</td>"
127       << "<td>Code Lines</td>"
128       << "<td>Comment Lines</td>"
129       << "<td>Latest Commitment</td>"
130       <<"</tr>";
131
132    std::string timefmt("%b %d %H:%M:%S %Y");
133    using namespace std;
134    for (vector<Commitment>::const_iterator i=lc.begin(); i!=lc.end(); ++i) {
135      os << "<tr><td>"; 
136      if (!stats.lines(i->author()))
137        os << i->author();
138      else
139        os << anchor(std::string("classic/"+i->author()+"/total/index.html"),
140                     i->author());
141      os << "</td><td>" << stats.lines(i->author()) << " (" 
142         << 100*stats.lines(i->author())/(stats.lines()?stats.lines():1)
143         << "%)</td><td>" << stats.code(i->author()) << " (" 
144         << 100*stats.code(i->author())/(stats.code()?stats.code():1)
145         << "%)</td><td>" << stats.comments(i->author()) << " (" 
146         << 100*stats.comments(i->author())/(stats.comments()?stats.comments():1)
147         << "%)</td><td>" << Date(i->date())(timefmt) << "</td>" <<"</tr>";
148    }
149    os << "<tr><td>Total</td>";
150    os << "<td>" << stats.lines() << "</td>"
151       << "<td>" << stats.code() << "</td>"
152       << "<td>" << stats.comments() << "</td>"
153       <<"</tr>";
154
155    os << "</table></div>\n";
156   
157  }
158
159
160  void print_recent_logs(std::ostream& os, const SVNlog& log)
161  {
162    os << "<div class=\"main\">\n"
163       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
164       << "Recent Log"
165       << "</th></tr></thead>\n";
166
167    std::vector<std::string>::const_reverse_iterator a=log.author().rbegin();
168    std::vector<std::string>::const_reverse_iterator d=log.date().rbegin();
169    std::vector<std::string>::const_reverse_iterator m=log.message().rbegin();
170    std::vector<size_t>::const_reverse_iterator r=log.revision().rbegin();
171    assert(log.author().size()==log.date().size());
172    assert(log.author().size()==log.message().size());
173    assert(log.author().size()==log.revision().size());
174    os << "<tr><td>Author</td><td>Date</td><td>Rev</td><td>Message</td></tr>\n";
175    HtmlStream hs(os);
176    std::string timefmt("%b %d %H:%M:%S %Y");
177    const size_t maxlength = 80;
178    const Configuration& conf = Configuration::instance();
179    for (size_t i=0; i<10 && a!=log.author().rend(); ++i) {
180      os << "<tr><td>" 
181         << anchor(std::string("classic/")+*a+"/total/index.html",*a) 
182         << "</td>";
183      Date date(*d);
184      os << "<td>" << date(timefmt) << "</td>";
185      os << "<td>"; 
186      os << trac_revision(*r);
187      os << "</td>";
188      os << "<td>";
189      std::string mess = *m;
190      // replace newlines with space
191      std::replace(mess.begin(), mess.end(), '\n', ' ');
192      mess = htrim(mess);
193
194      if (conf.trac_root().empty()) {
195        // truncate message if too long
196        if (mess.size()>maxlength)
197          mess = mess.substr(0,maxlength-3) + "...";
198        hs << mess;
199      }
200      else {// make anchors to trac
201        Trac trac(hs);
202        trac.print(mess, maxlength);
203      }
204
205      os << "</td></tr>\n";
206      ++a;
207      ++d;
208      ++m;
209      ++r;
210    }
211    os << "</table></div>\n";
212  }
213
214
215  void print_summary_plot(std::ostream& os, const Stats& stats)
216  {
217    std::string name("summary_plot.png");
218    stats.plot_summary(name);
219    os << "<div class=\"main\">\n";
220    os << "<img src='" << name << "' alt='[plot]'/>"; 
221    os << "</div>";
222  }
223
224}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.