source: trunk/lib/first_page.cc @ 285

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

moving first page generation to separate file.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.3 KB
Line 
1// $Id: first_page.cc 285 2007-05-06 19:03:28Z 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 "utility.h"
35#include <config.h> // this header file is created by configure
36
37#include <algorithm>
38#include <cassert>
39#include <fstream>
40#include <iostream>
41#include <sstream>
42#include <stdexcept>
43#include <string>
44#include <sys/param.h>
45#include <unistd.h>
46#include <vector>
47
48namespace theplu{
49namespace svndigest{
50
51  void print_main_page(const std::string& dir, const SVNlog& log,
52                       const Stats& stats)
53  {
54    std::string filename="index.html";
55    std::ofstream os(filename.c_str());
56    print_header(os, dir, 0, "all", "main", "index.html");
57
58    using namespace std;
59    set<string> authors;
60    authors.insert(log.author().begin(), log.author().end());
61    // erase invalid authors
62    authors.erase("");
63    authors.erase("no author");
64
65    vector<Commitment> latest_commit;
66    latest_commit.reserve(authors.size());
67    for (set<string>::const_iterator i(authors.begin()); i!=authors.end(); ++i)
68      latest_commit.push_back(log.latest_commit(*i));
69
70    print_general_information(os, log, authors.size());
71    sort(latest_commit.begin(), latest_commit.end(), GreaterRevision());
72    print_authors(os, latest_commit, stats);
73    print_recent_logs(os, log);
74    os << "<hr width=100% />";
75    print_footer(os);
76    os.close();
77
78  }
79
80  void print_general_information(std::ostream& os, const SVNlog& log, 
81                                 size_t nof_authors)
82  { 
83    Date begin(log.date()[0]);
84    if (log.date().size()>1)
85      begin = std::min(begin, Date(log.date()[1]));
86    Date end(log.date().back());
87    Date now;
88    std::string timefmt("%a, %e %b %Y");
89
90    os << "<div class=\"main\">" 
91       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
92       << "General Information"
93       << "</th></tr></thead>\n"
94       << "<tr><td>First Revision:</td><td>" 
95       << begin(timefmt) << "</td></tr>\n"
96       << "<tr><td>Latest Revision:</td><td>" 
97       << end(timefmt) << "</td></tr>\n"
98       << "<tr><td>Report Generated:</td><td>" 
99       << now(timefmt) << "</td></tr>\n"
100       << "<tr><td>Repository Age:</td><td>"; 
101    os << now.difftime(begin);
102    os << "</td></tr>\n"
103       << "<tr><td>Number of Authors:</td><td>" << nof_authors
104       << "</td></tr>\n"
105       << "<tr><td>Revisions:</td><td>" << log.revision().size() 
106       << "</td></tr>\n"
107       << "</table></div>\n";
108  }
109
110
111  void print_authors(std::ostream& os, 
112                     const std::vector<Commitment>& lc,
113                     const Stats& stats)
114  {
115    os << "<div class=\"main\">"
116       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
117       << "Authors"
118       << "</th></tr></thead>\n";
119
120    os << "<tr><td>Author</td>" 
121       << "<td>Number of Lines</td>"
122       << "<td>Code Lines</td>"
123       << "<td>Comment Lines</td>"
124       << "<td>Latest Commitment</td>"
125       <<"</tr>";
126
127    std::string timefmt("%b %d %H:%M:%S %Y");
128    using namespace std;
129    for (vector<Commitment>::const_iterator i=lc.begin(); i!=lc.end(); ++i) {
130      os << "<tr><td>" 
131         << anchor(string(i->author()+"/total/index.html"),i->author())
132         << "</td><td>" << stats.lines(i->author()) << " (" 
133         << 100*stats.lines(i->author())/stats.lines() << "%)</td>"
134         << "<td>" << stats.code(i->author()) << " (" 
135         << 100*stats.code(i->author())/stats.code() << "%)</td>"
136         << "<td>" << stats.comments(i->author()) << " (" 
137         << 100*stats.comments(i->author())/stats.comments() << "%)</td>"
138         << "<td>" << i->date()(timefmt) << "</td>"
139         <<"</tr>";
140    }
141
142    os << "</table></div>\n";
143   
144  }
145
146
147  void print_recent_logs(std::ostream& os, const SVNlog& log)
148  {
149    os << "<div class=\"main\">\n"
150       << "<table class=\"main\"><thead><tr><th colspan=\"2\">" 
151       << "Recent Log"
152       << "</th></tr></thead>\n";
153
154    std::vector<std::string>::const_reverse_iterator a=log.author().rbegin();
155    std::vector<std::string>::const_reverse_iterator d=log.date().rbegin();
156    std::vector<std::string>::const_reverse_iterator m=log.message().rbegin();
157    std::vector<size_t>::const_reverse_iterator r=log.revision().rbegin();
158    assert(log.author().size()==log.date().size());
159    assert(log.author().size()==log.message().size());
160    assert(log.author().size()==log.revision().size());
161    os << "<tr><td>Author</td><td>Date</td><td>Rev</td><td>Message</td></tr>\n";
162    HtmlStream hs(os);
163    std::string timefmt("%b %d %H:%M:%S %Y");
164    const size_t maxlength = 80;
165    const Configuration* conf = Configuration::instance();
166    for (size_t i=0; i<10 && a!=log.author().rend(); ++i) {
167      os << "<tr><td>" << anchor(*a+"/total/index.html",*a) << "</td>";
168      Date date(*d);
169      os << "<td>" << date(timefmt) << "</td>";
170      os << "<td>"; 
171      os << trac_revision(*r);
172      os << "</td>";
173      os << "<td>";
174      std::string mess = *m;
175      // replace newlines with space
176      std::replace(mess.begin(), mess.end(), '\n', ' ');
177      mess = htrim(mess);
178      // truncate message if too long
179      if (mess.size()>maxlength)
180        mess = mess.substr(0,maxlength-3) + "...";
181
182      if (conf->trac_ticket().empty())
183        hs << mess;
184      else { // make anchors to trac
185        char c;
186        std::stringstream ss(mess);
187        for (ss.get(c); ss.good(); ss.get(c)) {
188          if (c=='#') {
189            int ticket=0;
190            ss >> ticket;
191            if (!ss.fail()){
192              std::stringstream s;
193              s << ticket;
194              os << anchor(conf->trac_ticket()+s.str(),"#"+s.str()); 
195            }
196            else {
197              ss.clear(std::ios::goodbit);
198              hs << c;
199            }
200          }
201          else
202            hs << c;
203        }
204      }
205
206      os << "</td></tr>";
207      ++a;
208      ++d;
209      ++m;
210      ++r;
211    }
212    os << "</table></div>\n";
213  }
214
215
216}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.