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