source: trunk/lib/Directory.cc @ 303

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

Sorting authors in copyright statement in same order as stated in config file. fixes #172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.5 KB
Line 
1// $Id: Directory.cc 303 2007-05-11 20:13:00Z peter $
2
3/*
4  Copyright (C) 2005, 2006 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2007 Peter Johansson
6
7  This file is part of svndigest, http://lev.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 "Directory.h"
26
27#include "Alias.h"
28#include "File.h"
29#include "html_utility.h"
30#include "Node.h"
31#include "SVN.h"
32#include "SVNlog.h"
33#include "utility.h"
34
35#include <algorithm>
36#include <cassert>
37#include <fstream>
38#include <functional>
39#include <iostream>
40#include <iterator>
41#include <list>
42#include <map>
43
44#include <cerrno> // Needed to check error state below.
45#include <dirent.h>
46#include <sys/stat.h>
47
48namespace theplu{
49namespace svndigest{
50
51
52  Directory::Directory(const u_int level, const std::string& path, 
53                       const std::string& output)
54    : Node(level,path,output)
55  {
56    using namespace std;
57    DIR* directory=opendir(path.c_str());    // C API from dirent.h
58    if (!directory)
59      throw NodeException("ERROR: opendir() failed; " + path +
60                          " is not a directory");
61    list<string> entries;
62    struct dirent* entry;
63    errno=0;  // Global variable used by C to track errors, from errno.h
64    while ((entry=readdir(directory)))       // C API from dirent.h
65      entries.push_back(string(entry->d_name));
66    if (errno)
67      throw NodeException("ERROR: readdir() failed on " + path);
68    closedir(directory);
69
70    SVN* svn=SVN::instance();
71    for (list<string>::iterator i=entries.begin(); i!=entries.end(); ++i)
72      if ((*i)!=string(".") && (*i)!=string("..") && (*i)!=string(".svn")) {
73        string fullpath(path_+'/'+(*i));
74        switch (svn->version_controlled(fullpath)) {
75        case SVN::uptodate:
76          struct stat nodestat;                // C api from sys/stat.h
77          lstat(fullpath.c_str(),&nodestat);   // C api from sys/stat.h
78          if (S_ISDIR(nodestat.st_mode))       // C api from sys/stat.h
79            daughters_.push_back(new Directory(level_+1,fullpath,local_path()));
80          else
81            daughters_.push_back(new File(level_,fullpath,local_path()));
82          break;
83        case SVN::unresolved:
84          throw NodeException(fullpath+" is not up to date");
85        case SVN::unversioned: ; // do nothing
86        }
87      }
88    daughters_.sort(NodePtrLess());
89  }
90
91
92  Directory::~Directory(void)
93  {
94    for (NodeIterator i=daughters_.begin(); i!=daughters_.end(); ++i)
95      delete *i;
96  }
97
98  bool Directory::dir(void) const
99  {
100    return true;
101  }
102
103  std::string Directory::href(void) const
104  { 
105    return name() + "/index.html";
106  }
107
108  const Stats& Directory::parse(const bool verbose)
109  {
110    stats_.reset();
111    // Directories themselved give no contribution to statistics.
112    for (NodeIterator i=daughters_.begin(); i!=daughters_.end(); ++i)
113      if (!(*i)->ignore())
114        stats_ += (*i)->parse(verbose);
115    return stats_;
116  }
117
118
119  const std::string Directory::node_type(void) const
120  {
121    return std::string("directory");
122  }
123
124
125  void Directory::print_core(const bool verbose) const
126  {
127    // print daughter nodes, i.e., this function is recursive
128    for (NodeConstIterator i=daughters_.begin(); i!=daughters_.end(); ++i)
129      (*i)->print(verbose);
130  }
131
132
133  void Directory::print_core(const std::string& user, 
134                             const std::string& line_type,
135                             const SVNlog& log) const
136  {
137
138    std::string outdir = user+"/"+line_type+"/"+local_path_;
139    if (local_path_=="")
140      outdir = user+"/"+line_type;
141
142    mkdir(outdir);
143    std::string imagedir = "images/"+line_type+"/"+local_path_;
144    if (user=="all")
145      mkdir(imagedir);
146
147    std::string html_name = outdir+"/index.html";
148    std::ofstream os(html_name.c_str());
149    assert(os.good());
150    if (local_path().empty())
151      print_header(os, name(), level_+2, user, line_type, "index.html");
152    else
153      print_header(os, name(), level_+2, user, line_type, 
154                   local_path()+"/index.html");
155    path_anchor(os);
156    os << "<p align=center>\n<img src='"; 
157    for (size_t i=0; i<level_; ++i)
158      os << "../";
159    os << "../../";
160    if (user=="all")
161      os << stats_.plot(imagedir+"/index.png", line_type);
162    else
163      os << imagedir << "/index.png";
164    os << "' alt='[plot]' border=0><br>\n";
165    os << "<h3>File Summary";
166    if (user!="all")
167      os << " for " << user;
168    os << "</h3>";     
169    os << "<table class=\"listings\">\n";
170    os << "<thead>";
171    os << "<tr>\n";
172    os << "<th>Node</th>\n";
173    os << "<th>Lines</th>\n";
174    os << "<th>Code</th>\n";
175    os << "<th>Comments</th>\n";
176    os << "<th>Other</th>\n";
177    os << "<th>Revision</th>\n";
178    os << "<th>Author</th>\n";
179    os << "</tr>\n</thead>\n";
180    os << "<tbody>";
181
182    std::string color("light");
183    if (level_){
184      os << "<tr class=\"light\">\n";
185      os << "<td class=\"directory\" colspan=\"6\">";
186      os << anchor("../index.html", "../");
187      os << "</td>\n</tr>\n";
188      color = "dark";
189    }
190
191    // print html links to daughter nodes
192    for (NodeConstIterator d = daughters_.begin(); d!=daughters_.end(); ++d) {
193      (*d)->html_tablerow(os,color, user);
194      if (color=="dark")
195        color = "light";
196      else
197        color = "dark";
198    }
199    os << "<tr class=\"" << color << "\">\n";
200    os << "<td>Total</td>\n";
201    if (user=="all"){
202      os << "<td>" << stats_.lines() << "</td>\n";
203      os << "<td>" << stats_.code() << "</td>\n";
204      os << "<td>" << stats_.comments() << "</td>\n";
205      os << "<td>" << stats_.empty() << "</td>\n";
206    }
207    else {
208      os << "<td>" << stats_.lines(user) << "</td>\n";
209      os << "<td>" << stats_.code(user) << "</td>\n";
210      os << "<td>" << stats_.comments(user) << "</td>\n";
211      os << "<td>" << stats_.empty(user) << "</td>\n";
212    }
213    os << "<td>" << trac_revision(stats_.last_changed_rev()) << "</td>\n";
214    os << "<td>" << author() << "</td>\n";
215    os << "</tr>\n";
216    os << "</table>\n";
217    print_author_summary(os, line_type, log);
218    os << "</p>\n";
219    print_footer(os);
220    os.close(); 
221  }
222
223
224  void Directory::print_copyright(std::map<std::string, Alias>& alias) const {
225    if (!ignore()){
226      // print daughter nodes, i.e, this function is recursive
227      for (NodeConstIterator i = daughters_.begin(); i!=daughters_.end(); ++i)
228        (*i)->print_copyright(alias);
229    }
230  }
231
232}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.