source: trunk/lib/File.cc @ 235

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

added Date class
changed date format on first page
fixed plotting only once (fixes #113)
changed interface to anchor class
more anchors to users
removed anchor to '../' in author summary in dirs
anchors are filtered through HtmlStream?
log messages are truncated and newlines are replaced with spaces

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.9 KB
Line 
1// $Id: File.cc 235 2007-04-21 13:39:50Z 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 "File.h"
26#include "html_utility.h"
27#include "Stats.h"
28#include "SVNlog.h"
29
30#include <cassert>
31#include <ctime>
32#include <fstream>
33#include <iostream>
34#include <map>
35#include <string>
36
37namespace theplu{
38namespace svndigest{
39
40
41  std::string File::href(void) const
42  { 
43    return name()+".html"; 
44  }
45
46
47  const std::string File::node_type(void) const
48  {
49    return std::string("file");
50  }
51
52
53  const Stats& File::parse(const bool verbose)
54  {
55    if (verbose)
56      std::cout << "Parsing " << path_ << std::endl; 
57    stats_.reset();
58    stats_.parse(path_);
59    return stats_;
60  }
61
62
63  void File::print(const std::string& user, const std::string& line_type) const 
64  {
65    std::string outpath = user+"/"+line_type+"/"+local_path();
66    std::string imagefile = "images/"+line_type+"/"+local_path_+".png";
67    std::string html_name(outpath + ".html");
68    std::ofstream os(html_name.c_str());
69    print_header(os, name(), level_+2, user, line_type, local_path()+".html");
70    path_anchor(os);
71    os << "<p align=center>\n<img src='"; 
72    for (size_t i=0; i<level_; ++i)
73      os << "../";
74    os << "../../";
75    if (user=="all")
76      os << stats_.plot(imagefile, local_path(),line_type);
77    else
78      os << imagefile;
79    os << "' alt='[plot]' border=0>\n</p>";
80
81    print_author_summary(os, line_type);
82    os << "</p>\n";
83
84    print_footer(os);
85    os.close(); 
86  }
87
88
89  void File::print(const bool verbose) const 
90  {
91    // no output page for binary files
92    if (ignore())
93      return;
94    if (verbose)
95      std::cout << "Printing output for " << path_ << std::endl;
96    print("all", "total");
97    print("all", "code");
98    print("all", "comments");
99    print("all", "empty");
100
101    for (std::set<std::string>::const_iterator i = stats_.authors().begin();
102         i!=stats_.authors().end(); ++i) {
103      print(*i, "total");
104      print(*i, "code");
105      print(*i, "comments");
106      print(*i, "empty");
107    }
108
109  }
110
111
112  void File::print_blame(std::ofstream& os, const std::string line_type) const
113  {
114    os << "<table class=\"blame\">\n";
115
116    os << "</table>\n";
117  }
118
119
120  void File::print_copyright (std::map<std::string,std::string>& alias) const{
121    if (ignore())
122      return;
123    using namespace std;
124
125    SVNlog log(path());
126
127    typedef map<int, set<string> > Container;
128    Container copyright;
129
130   
131    assert(log.author().size()==log.date().size());
132    vector<string>::const_iterator author=log.author().begin();
133    for (vector<string>::const_iterator date=log.date().begin();
134         date!=log.date().end(); ++date, ++author) {
135      time_t sec = str2time(*date);
136      tm* timeinfo = gmtime(&sec);
137
138      // find username in map of aliases
139      map<string, string>::iterator name = alias.lower_bound(*author);
140      // if alias exist insert alias
141      if (name != alias.end() && name->first==*author)
142        copyright[timeinfo->tm_year].insert(name->second);
143      else {
144        // else insert user name
145        copyright[timeinfo->tm_year].insert(*author);
146        std::cerr << "svndigest: warning: no copyright alias found for `" 
147                  << *author << "`\n";
148        // insert alias to avoid multiple warnings.
149        alias.insert(name, std::make_pair(*author, *author));
150      }
151    }
152
153
154    // Code copied from Gnuplot -r70
155    char tmpname[]="/tmp/svndigestXXXXXX";
156    int fd=mkstemp(tmpname);  // mkstemp return a file descriptor
157    if (fd == -1)
158      throw std::runtime_error(std::string("Failed to get unique filename: ") +
159                               tmpname);
160    // Jari would like to do something like 'std::ofstream tmp(fd);'
161    // but has to settle for (which is stupid since the file is
162    // already open for writing.
163    std::ofstream tmp(tmpname);
164
165    ifstream is(path().c_str());
166    assert(is.good());
167    string line;
168    bool found_copyright = false;
169    bool after_copyright = false;
170    string prefix;
171    while(getline(is, line)){
172      if (after_copyright) 
173        tmp << line << "\n";
174      else if (found_copyright){
175        // check if line is end of copyright statement, i.e. contains
176        // no alphanumerical character
177        after_copyright = true;
178        for (size_t i=0; i<line.size()&&after_copyright; ++i)
179          if (isalnum(line[i]))
180            after_copyright = false;
181        if (after_copyright)
182          tmp << line << "\n";
183         
184      }
185      else {
186        // check whether copyright starts on this line
187        string::iterator i = search(line.begin(), line.end(), "Copyright (C)");
188        if (i==line.end()) {
189          tmp << line << "\n";
190        }     
191        else {
192          prefix = line.substr(0, distance(line.begin(), i));
193          found_copyright = true;
194          // Printing copyright statement
195          for (Container::const_iterator i=copyright.begin();
196               i!=copyright.end();) {
197            tmp << prefix << "Copyright (C) "
198                << 1900+i->first;
199            Container::const_iterator j = i;
200            assert(i!=copyright.end());
201            while (++j!=copyright.end() && i->second == j->second){
202              tmp << ", " << 1900+(j->first);
203            }
204            // printing authors
205            for (set<string>::iterator a=i->second.begin();
206                 a!=i->second.end(); ++a){
207              if (a!=i->second.begin())
208                tmp << ",";
209              tmp << " " << *a;
210            }
211            tmp << "\n";
212            i = j;
213          }
214        }
215      }
216    }
217    is.close();
218    tmp.close();
219    close(fd);
220    // finally move printed temporary file to original file
221    rename(tmpname, path().c_str());
222  }
223}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.