source: trunk/lib/first_page.cc @ 363

Last change on this file since 363 was 363, checked in by Peter Johansson, 16 years ago

modifying general info fixes #206

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.6 KB
Line 
1// $Id: first_page.cc 363 2007-06-10 23:20:01Z peter $
2
3/*
4  Copyright (C) 2006, 2007 Peter Johansson
5
6  This file is part of svndigest, http://lev.thep.lu.se/trac/svndigest
7
8  svndigest is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  svndigest is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "first_page.h"
25
26#include "html_utility.h"
27
28#include "Commitment.h"
29#include "Configuration.h"
30#include "Date.h"
31#include "HtmlStream.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
82  void print_general_information(std::ostream& os, const SVNlog& log, 
83                                 size_t nof_authors, std::string url)
84  { 
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       << "<tr><td>URL:</td><td>" 
94       << url << "</td></tr>\n"
95       << "<tr><td>First Revision Date:</td><td>" 
96       << begin(timefmt) << "</td></tr>\n"
97       << "<tr><td>Latest Revision Date:</td><td>" 
98       << end(timefmt) << "</td></tr>\n"
99       << "<tr><td>Age:</td><td>"; 
100    os << end.difftime(begin);
101    os << "</td></tr>\n"
102       << "<tr><td>Smallest Revision:</td><td>" << log.revision()[0] 
103       << "</td></tr>\n"
104       << "<tr><td>Biggest Revision:</td><td>" << log.revision().back() 
105       << "</td></tr>\n"
106       << "<tr><td>Revision Count:</td><td>" << log.revision().size() 
107       << "</td></tr>\n"
108       << "<tr><td>Number of Authors:</td><td>" << nof_authors
109       << "</td></tr>\n"
110       << "</table></div>\n";
111  }
112
113
114  void print_authors(std::ostream& os, 
115                     const std::vector<Commitment>& lc,
116                     const Stats& stats)
117  {
118    os << "<div class=\"main\">"
119       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
120       << "Authors"
121       << "</th></tr></thead>\n";
122
123    os << "<tr><td>Author</td>" 
124       << "<td>Number of Lines</td>"
125       << "<td>Code Lines</td>"
126       << "<td>Comment Lines</td>"
127       << "<td>Latest Commitment</td>"
128       <<"</tr>";
129
130    std::string timefmt("%b %d %H:%M:%S %Y");
131    using namespace std;
132    for (vector<Commitment>::const_iterator i=lc.begin(); i!=lc.end(); ++i) {
133      os << "<tr><td>"; 
134      if (!stats.lines(i->author()))
135        os << i->author();
136      else
137        os << anchor(string(i->author()+"/total/index.html"),i->author());
138      os << "</td><td>" << stats.lines(i->author()) << " (" 
139         << 100*stats.lines(i->author())/stats.lines() << "%)</td>"
140         << "<td>" << stats.code(i->author()) << " (" 
141         << 100*stats.code(i->author())/stats.code() << "%)</td>"
142         << "<td>" << stats.comments(i->author()) << " (" 
143         << 100*stats.comments(i->author())/stats.comments() << "%)</td>"
144         << "<td>" << i->date()(timefmt) << "</td>"
145         <<"</tr>";
146    }
147    os << "<tr><td>Total</td>";
148    os << "<td>" << stats.lines() << "</td>"
149       << "<td>" << stats.code() << "</td>"
150       << "<td>" << stats.comments() << "</td>"
151       <<"</tr>";
152
153    os << "</table></div>\n";
154   
155  }
156
157
158  void print_recent_logs(std::ostream& os, const SVNlog& log)
159  {
160    os << "<div class=\"main\">\n"
161       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
162       << "Recent Log"
163       << "</th></tr></thead>\n";
164
165    std::vector<std::string>::const_reverse_iterator a=log.author().rbegin();
166    std::vector<std::string>::const_reverse_iterator d=log.date().rbegin();
167    std::vector<std::string>::const_reverse_iterator m=log.message().rbegin();
168    std::vector<size_t>::const_reverse_iterator r=log.revision().rbegin();
169    assert(log.author().size()==log.date().size());
170    assert(log.author().size()==log.message().size());
171    assert(log.author().size()==log.revision().size());
172    os << "<tr><td>Author</td><td>Date</td><td>Rev</td><td>Message</td></tr>\n";
173    HtmlStream hs(os);
174    std::string timefmt("%b %d %H:%M:%S %Y");
175    const size_t maxlength = 80;
176    const Configuration& conf = Configuration::instance();
177    for (size_t i=0; i<10 && a!=log.author().rend(); ++i) {
178      os << "<tr><td>" << anchor(*a+"/total/index.html",*a) << "</td>";
179      Date date(*d);
180      os << "<td>" << date(timefmt) << "</td>";
181      os << "<td>"; 
182      os << trac_revision(*r);
183      os << "</td>";
184      os << "<td>";
185      std::string mess = *m;
186      // replace newlines with space
187      std::replace(mess.begin(), mess.end(), '\n', ' ');
188      mess = htrim(mess);
189
190      if (conf.trac_root().empty()) {
191        // truncate message if too long
192        if (mess.size()>maxlength)
193          mess = mess.substr(0,maxlength-3) + "...";
194        hs << mess;
195      }
196      else {// make anchors to trac
197        Trac trac(hs);
198        trac.print(mess, maxlength);
199      }
200
201      os << "</td></tr>";
202      ++a;
203      ++d;
204      ++m;
205      ++r;
206    }
207    os << "</table></div>\n";
208  }
209
210
211  void print_summary_plot(std::ostream& os, const Stats& stats)
212  {
213    std::string name("summary_plot.png");
214    stats.plot_summary(name);
215    os << "<div class=\"main\">\n";
216    os << "<img src='" << name << "' alt='[plot]'>"; 
217    os << "</div>";
218  }
219
220}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.