Changeset 235


Ignore:
Timestamp:
Apr 21, 2007, 3:39:50 PM (16 years ago)
Author:
Peter Johansson
Message:

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

Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/svndigest.cc

    r234 r235  
    159159                                 +tree.name()+"'");
    160160  print_css("svndigest.css");
    161   print_main_page(tree.name(), svnlog, stats);
     161  SVNlog local_log(option->root());
     162  print_main_page(tree.name(), local_log, stats);
    162163  mkdir("all");
     164  mkdir("images");
    163165  for (std::set<std::string>::const_iterator i = stats.authors().begin();
    164166       i!=stats.authors().end(); ++i) {
  • trunk/lib/Directory.cc

    r234 r235  
    153153
    154154    mkdir(outdir);
     155    std::string imagedir = "images/"+line_type+"/"+local_path_;
     156    if (user=="all")
     157      mkdir(imagedir);
     158
    155159    std::string html_name = outdir+"/index.html";
    156160    std::ofstream os(html_name.c_str());
     
    162166                   local_path()+"/index.html");
    163167    path_anchor(os);
    164     os << "<p align=center>\n<img src='"
    165        << file_name(stats_.plot(outdir+"/index.png", local_path(),line_type))
    166        << "' alt='[plot]' border=0><br>\n";
     168    os << "<p align=center>\n<img src='";
     169    for (size_t i=0; i<level_; ++i)
     170      os << "../";
     171    os << "../../";
     172    if (user=="all")
     173      os << stats_.plot(imagedir+"/index.png", local_path(),line_type);
     174    else
     175      os << imagedir << "/index.png";
     176    os << "' alt='[plot]' border=0><br>\n";
    167177    os << "<table class=\"listings\">\n";
    168178    os << "<thead>";
     
    182192      os << "<tr class=\"light\">\n";
    183193      os << "<td class=\"directory\" colspan=\"6\">";
    184       anchor(os, "../index.html", "../");
     194      os << anchor("../index.html", "../");
    185195      os << "</td>\n</tr>\n";
    186196      color = "dark";
     
    213223    os << "</tr>\n";
    214224    os << "</table>\n";
    215     print_author_summary(os);
     225    print_author_summary(os, line_type);
    216226    os << "</p>\n";
    217227    print_footer(os);
  • trunk/lib/File.cc

    r234 r235  
    6464  {
    6565    std::string outpath = user+"/"+line_type+"/"+local_path();
     66    std::string imagefile = "images/"+line_type+"/"+local_path_+".png";
    6667    std::string html_name(outpath + ".html");
    6768    std::ofstream os(html_name.c_str());
    6869    print_header(os, name(), level_+2, user, line_type, local_path()+".html");
    6970    path_anchor(os);
    70     os << "<p align=center>\n<img src='"
    71        << file_name(stats_.plot(outpath+".png",local_path(),line_type))
    72        << "' alt='[plot]' border=0>\n</p>";
    73 
    74     print_author_summary(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);
    7582    os << "</p>\n";
    7683
     
    137144        // else insert user name
    138145        copyright[timeinfo->tm_year].insert(*author);
    139         std::cerr << "Warning: no alias found for `" << *author << "`\n";
     146        std::cerr << "svndigest: warning: no copyright alias found for `"
     147                  << *author << "`\n";
    140148        // insert alias to avoid multiple warnings.
    141149        alias.insert(name, std::make_pair(*author, *author));
  • trunk/lib/HtmlStream.cc

    r234 r235  
    6161  {
    6262    char c;
    63     while (ss.good()){
     63    while (true){
    6464      ss.get(c);
     65      if (!ss.good())
     66        return;
    6567      std::map<char, std::string>::const_iterator i = map_.find(c);
    6668      if (i==map_.end())
  • trunk/lib/Node.cc

    r234 r235  
    7474        words.push_back(word);
    7575    if (words.size()==1)
    76       anchor(os, "index.html", Node::project_,0, "View " + Node::project_);
     76      os << anchor("index.html", Node::project_,0, "View " + Node::project_);
    7777    else {
    7878      for (size_t i=0; i<words.size()-1; ++i){
    79         anchor(os,"index.html", words[i], level_-i, "View " + words[i]);
     79        os << anchor("index.html", words[i], level_-i, "View " + words[i]);
    8080        os << "<span class=\"sep\">/</span>\n";
    8181      }
    82       anchor(os,href(), words.back(), level_+2-words.size(),
     82      os << anchor(href(), words.back(), level_+2-words.size(),
    8383             "View " + words.back());
    8484    }
     
    101101      os << name();
    102102    else
    103       anchor(os,href(), name());
     103      os << anchor(href(), name());
    104104    os << "</td>\n";
    105105    if (user=="all") {
     
    121121
    122122
    123   void Node::print_author_summary(std::ostream& os) const
     123  void Node::print_author_summary(std::ostream& os, std::string line_type) const
    124124  {
    125125    os << "<table class=\"listings\">\n";
     
    135135    os << "<tr class=\"light\">\n";
    136136    os << "<td class=\"directory\" colspan=\"5\">";
    137     anchor(os, "index.html", "../");
     137    if (!dir())
     138      os << anchor("index.html", "../");
    138139    os << "</td>\n</tr>\n";
    139140       
     
    142143    for (std::set<std::string>::const_iterator i=stats_.authors().begin();
    143144         i!=stats_.authors().end(); ++i){
    144       os << "<tr class=\"" << color << "\"><td>" << *i
    145          << "</td><td>" << stats_.lines(*i)
     145      os << "<tr class=\"" << color << "\"><td>";
     146      if (dir())
     147        os << anchor(*i+"/"+line_type+"/"+local_path()+"/index.html"
     148                     ,*i, level_+2, "View statistics for "+*i);
     149      else
     150        os << anchor(*i+"/"+line_type+"/"+local_path()+".html"
     151                     ,*i, level_+2, "View statistics for "+*i);
     152      os << "</td><td>" << stats_.lines(*i)
    146153         << "</td><td>" << stats_.code(*i)
    147154         << "</td><td>" << stats_.comments(*i)
     
    154161
    155162    os << "<tr class=\"" << color << "\">\n";
    156     os << "<td>Total</td>\n";
     163    os << "<td>";
     164    if (dir())
     165      os << anchor("all/"+line_type+"/"+local_path()+"/index.html"
     166                   ,"Total", level_+2, "View statistics for all");
     167    else
     168      os << anchor("all/"+line_type+"/"+local_path()+".html"
     169                   ,"Total", level_+2, "View statistics for all");
     170    os << "</td>\n";
    157171    os << "<td>" << stats_.lines() << "</td>\n";
    158172    os << "<td>" << stats_.code() << "</td>\n";
  • trunk/lib/Node.h

    r234 r235  
    142142    virtual void print(const bool verbose=false) const=0;
    143143
    144     void print_author_summary(std::ostream&) const;
     144    void print_author_summary(std::ostream&, std::string) const;
    145145
    146146    virtual void
  • trunk/lib/html_utility.cc

    r234 r235  
    2424#include "html_utility.h"
    2525
     26#include "Date.h"
    2627#include "HtmlStream.h"
    2728#include "Stats.h"
     
    4344namespace svndigest{
    4445
    45   void anchor(std::ostream& os, const std::string& href,
    46               const std::string& name, u_int level,
    47               const std::string& title)
    48   {
    49     os << "<a title=\"" << title << "\" href=\"" ;
     46  std::string anchor(const std::string& href,
     47                     const std::string& name, u_int level,
     48                     const std::string& title)
     49  {
     50    std::stringstream ss;
     51    HtmlStream hs(ss);
     52    ss << "<a title=\"";
     53    hs << title;
     54    ss << "\" href=\"";
    5055    for (size_t i=0; i<level; ++i)
    51       os << "../";
    52     os << href << "\">" << name << "</a>";
     56      ss << "../";
     57    hs << href;
     58    ss << "\">";
     59    hs << name;
     60    ss << "</a>";
     61    return ss.str();
    5362  }
    5463
     
    230239
    231240    using namespace std;
    232     map<string, time_t> latest_commit_date;
     241    map<string, Date> latest_commit_date;
    233242    assert(log.author().size()==log.date().size());
    234243    typedef vector<string>::const_iterator iter;
     
    236245    for (iter a=log.author().begin();
    237246         a!=log.author().end(); ++a, ++d) {
    238       latest_commit_date[*a]=str2time(*d);
     247      latest_commit_date[*a]=Date(*d);
    239248    }
    240249    // erase invalid authors
     
    243252
    244253    // vector of authors & date sorted with respect to date
    245     typedef vector<pair<string, time_t> > vector;
     254    typedef vector<pair<string, Date> > vector;
    246255    vector author_date;
    247256    author_date.reserve(latest_commit_date.size());
     
    249258    copy(latest_commit_date.begin(), latest_commit_date.end(), i);
    250259    sort(author_date.begin(), author_date.end(),
    251          pair_value_compare<string,time_t>());
     260         pair_value_compare<string,Date>());
    252261
    253262    print_general_information(os, log, author_date.size());
     
    263272                                 size_t nof_authors)
    264273  {
    265     time_t first = str2time(log.date()[1]);
    266     std::string first_date = asctime(gmtime(&first));
    267     time_t last = str2time(log.date().back());
    268     std::string last_date = asctime(gmtime(&last));
    269    
    270     u_int years = 0;
    271     u_int months  = 0;
    272     u_int days = 0;
    273     // No support in std for diffing two tm structs
    274     time_t now = time(NULL);
    275     tm* timeinfo = gmtime(&now);
    276     std::string now_date = asctime(timeinfo);
    277     while (difftime(now,first)>0){
    278       --timeinfo->tm_year;
    279       now = mktime(timeinfo);
    280       ++years;
    281     }
    282     --years;
    283     ++timeinfo->tm_year;
    284     now = mktime(timeinfo);
    285    
    286     while (difftime(now,first)>0){
    287       if (timeinfo->tm_mon>0)
    288         --timeinfo->tm_mon;
    289       else{
    290         timeinfo->tm_mon=11;
    291         --timeinfo->tm_year;
    292       }
    293       now = mktime(timeinfo);
    294       ++months;
    295     }
    296     --months;
    297     ++timeinfo->tm_mon;
    298     if (timeinfo->tm_mon>11){
    299       timeinfo->tm_mon=0;
    300       ++timeinfo->tm_year;
    301     }
    302     now = mktime(timeinfo);
    303    
    304     days = (now - first)/60/60/24;
    305 
    306     now = time(NULL);
     274    Date begin(log.date()[0]);
     275    if (log.date().size()>1)
     276      begin = std::min(begin, Date(log.date()[1]));
     277    Date end(log.date().back());
     278    Date now;
     279    std::string timefmt("%a, %e %b %Y");
     280
    307281    os << "<div class=\"main\">"
    308282       << "<table class=\"main\"><thead><tr><th colspan=\"2\">"
     
    310284       << "</th></tr></thead>\n"
    311285       << "<tr><td>First Revision:</td><td>"
    312        << first_date << "</td></tr>\n"
     286       << begin(timefmt) << "</td></tr>\n"
    313287       << "<tr><td>Latest Revision:</td><td>"
    314        << last_date << "</td></tr>\n"
     288       << end(timefmt) << "</td></tr>\n"
    315289       << "<tr><td>Report Generated:</td><td>"
    316        <<  now_date << "</td></tr>\n"
     290       << now(timefmt) << "</td></tr>\n"
    317291       << "<tr><td>Repository Age:</td><td>";
    318     if (years){
    319       os << years << " year";
    320       if (years>1)
    321         os << "s";
    322       os << " ";
    323     }
    324     if (months){
    325       os << months << " month";
    326       if (months>1)
    327         os << "s";
    328       os << " ";
    329     }
    330     if (months || years)
    331       os << "and ";
    332     os << days << " day";
    333     if (days>1)
    334       os << "s";
    335      
     292    os << now.difftime(begin);
    336293    os << "</td></tr>\n"
    337294       << "<tr><td>Number of Authors:</td><td>" << nof_authors
    338295       << "</td></tr>\n"
    339        << "<tr><td>Revisions:</td><td>" << log.revision().size()-1
     296       << "<tr><td>Revisions:</td><td>" << log.revision().back()
    340297       << "</td></tr>\n"
    341298       << "</table></div>\n";
     
    345302  void print_footer(std::ostream& os)
    346303  {
    347    
    348     time_t rawtime;
    349     struct tm * timeinfo;
    350     time ( &rawtime );
    351     timeinfo =  gmtime ( &rawtime );
     304    Date date;
    352305    os << "<p align=center><font size=-2>\nGenerated on "
    353        << asctime (timeinfo) << " (UTC) by ";
    354     anchor(os, "http://lev.thep.lu.se/trac/svndigest/", PACKAGE_STRING, 0, "");
    355     os << "</font>\n</p>\n</div>\n</body>\n</html>\n";
     306       << date("%a %b %d %H:%M:%S %Y") << " (UTC) by "
     307       << anchor("http://lev.thep.lu.se/trac/svndigest/",
     308                 PACKAGE_STRING, 0, "")
     309       << "</font>\n</p>\n</div>\n</body>\n</html>\n";
    356310  }
    357311
     
    380334    else
    381335      os << "<li>";
    382     anchor(os, "index.html", "Main", level, "Main page");
     336    os << anchor("index.html", "Main", level, "Main page");
    383337    os << "</li>";
    384338
     
    387341    else
    388342      os << "<li>";
    389     anchor(os, user+"/total/"+path, "Total", level,
     343    os << anchor(user+"/total/"+path, "Total", level,
    390344           "View statistics of all lines");
    391345    os << "</li>";
     
    395349    else
    396350      os << "<li>";
    397     anchor(os, user+"/code/"+path, "Code", level,
    398           "View statistics of code lines");
     351    os << anchor(user+"/code/"+path, "Code", level,
     352                "View statistics of code lines");
    399353    os << "</li>";
    400354
     
    403357    else
    404358      os << "<li>";
    405     anchor(os, user+"/comments/"+path, "Comment", level,
    406           "View statistics of comment lines");
     359    os << anchor(user+"/comments/"+path, "Comment", level,
     360                "View statistics of comment lines");
    407361    os << "</li>";
    408362
     
    412366    else
    413367      os << "<li>";
    414     anchor(os, user+"/empty/"+path, "Empty", level,
    415           "View statistics of empty lines");
     368    os << anchor(user+"/empty/"+path, "Empty", level,
     369                "View statistics of empty lines");
    416370    os << "</li>"
    417371       << "</ul></div>"
     
    421375
    422376  void print_authors(std::ostream& os,
    423                      const std::vector<std::pair<std::string,time_t> >& ad,
     377                     const std::vector<std::pair<std::string,Date> >& auth_date,
    424378                     const SVNlog& log, const Stats& stats)
    425379  {
     
    436390       <<"</tr>";
    437391
     392    std::string timefmt("%b %d %H:%M:%S %Y");
    438393    using namespace std;
    439     for (vector<pair<string,time_t> >::const_reverse_iterator i=ad.rbegin();
    440          i!=ad.rend(); ++i) {
    441       os << "<tr><td>";
    442       anchor(os, string(i->first+"/total/index.html"),i->first);
    443       os << "</td><td>" << stats.lines(i->first) << " ("
     394    for (vector<pair<string,Date> >::const_reverse_iterator i=auth_date.rbegin();
     395         i!=auth_date.rend(); ++i) {
     396      os << "<tr><td>"
     397         << anchor(string(i->first+"/total/index.html"),i->first)
     398        << "</td><td>" << stats.lines(i->first) << " ("
    444399         << 100*stats.lines(i->first)/stats.lines() << "%)</td>"
    445400         << "<td>" << stats.code(i->first) << " ("
     
    447402         << "<td>" << stats.comments(i->first) << " ("
    448403         << 100*stats.comments(i->first)/stats.comments() << "%)</td>"
    449          << "<td>" << asctime(gmtime(&i->second)) << "</td>"
     404         << "<td>" << i->second(timefmt) << "</td>"
    450405         <<"</tr>";
    451406    }
     
    466421    std::vector<std::string>::const_reverse_iterator d=log.date().rbegin();
    467422    std::vector<std::string>::const_reverse_iterator m=log.message().rbegin();
     423    std::vector<size_t>::const_reverse_iterator r=log.revision().rbegin();
    468424    assert(log.author().size()==log.date().size());
    469425    assert(log.author().size()==log.message().size());
     426    assert(log.author().size()==log.revision().size());
     427    os << "<tr><td>Author</td><td>Date</td><td>Rev</td><td>Message</td></tr>\n";
    470428    HtmlStream hs(os);
     429    std::string timefmt("%b %d %H:%M:%S %Y");
     430    const size_t maxlength = 80;
    471431    for (size_t i=0; i<10 && a!=log.author().rend(); ++i) {
    472       os << "<tr><td>" << *a << "</td>";
    473       time_t date = str2time(*d);
    474       os << "<td>" << asctime(gmtime(&date)) << "</td>";
     432      os << "<tr><td>" << anchor(*a+"/total/index.html",*a) << "</td>";
     433      Date date(*d);
     434      os << "<td>" << date(timefmt) << "</td>";
     435      os << "<td>" << *r << "</td>";
    475436      os << "<td>";
    476       hs << *m;
     437      std::string mess = *m;
     438      // replace newlines with space
     439      std::replace(mess.begin(), mess.end(), '\n', ' ');
     440      mess = htrim(mess);
     441      // trunctate message if too long
     442      if (mess.size()>maxlength)
     443        mess = mess.substr(0,maxlength-3) + "...";
     444      hs << mess;
    477445      os << "</td></tr>";
    478446      ++a;
    479447      ++d;
    480448      ++m;
     449      ++r;
    481450    }
    482451    os << "</table></div>\n";
  • trunk/lib/html_utility.h

    r234 r235  
    3535namespace svndigest{
    3636
     37  class Date;
    3738  class Stats;
    3839  class SVNlog;
    3940
    4041  ///
    41   /// @brief send anchor to stream @a os
     42  /// @brief create anchor
    4243  ///
    4344  /// @param href address to link to
     
    4647  /// @param title title of anchor
    4748  ///
    48   void anchor(std::ostream& os, const std::string& href,
    49               const std::string& name, u_int level=0,
    50               const std::string& title="");
     49  std::string anchor(const std::string& href,
     50                     const std::string& name, u_int level=0,
     51                     const std::string& title="");
    5152
    5253  ///
     
    5657
    5758  void print_authors(std::ostream& os,
    58                      const std::vector<std::pair<std::string, time_t> >&,
     59                     const std::vector<std::pair<std::string, Date> >&,
    5960                     const SVNlog&, const Stats& stats);
    6061
Note: See TracChangeset for help on using the changeset viewer.