source: branches/0.6-stable/lib/first_page.cc

Last change on this file was 731, checked in by Peter Johansson, 13 years ago

update copyright statements

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