"Fossies" - the Fresh Open Source Software Archive

Member "viewvc-1.2.1/lib/blame.py" (26 Mar 2020, 4814 Bytes) of package /linux/misc/viewvc-1.2.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "blame.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.1.28_vs_1.2.1.

    1 #!/usr/bin/env python
    2 # -*-python-*-
    3 #
    4 # Copyright (C) 1999-2020 The ViewCVS Group. All Rights Reserved.
    5 # Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
    6 #
    7 # By using this file, you agree to the terms and conditions set forth in
    8 # the LICENSE.html file which can be found at the top level of the ViewVC
    9 # distribution or at http://viewvc.org/license-1.html.
   10 #
   11 # For more information, visit http://viewvc.org/
   12 #
   13 # -----------------------------------------------------------------------
   14 #
   15 # blame.py: Annotate each line of a CVS file with its author,
   16 #           revision #, date, etc.
   17 #
   18 # -----------------------------------------------------------------------
   19 #
   20 # This file is based on the cvsblame.pl portion of the Bonsai CVS tool,
   21 # developed by Steve Lamm for Netscape Communications Corporation.  More
   22 # information about Bonsai can be found at
   23 #    http://www.mozilla.org/bonsai.html
   24 #
   25 # cvsblame.pl, in turn, was based on Scott Furman's cvsblame script
   26 #
   27 # -----------------------------------------------------------------------
   28 
   29 import sys
   30 import os
   31 import re
   32 import time
   33 import math
   34 
   35 from common import _item
   36 import vclib
   37 import sapi
   38 
   39 re_includes = re.compile('\\#(\\s*)include(\\s*)"(.*?)"')
   40 
   41 def link_includes(text, repos, path_parts, include_url):
   42   match = re_includes.match(text)
   43   if match:
   44     incfile = match.group(3)
   45     include_path_parts = path_parts[:-1]
   46     for part in filter(None, incfile.split('/')):
   47       if part == "..":
   48         if not include_path_parts:
   49           # nothing left to pop; don't bother marking up this include.
   50           return text
   51         include_path_parts.pop()
   52       elif part and part != ".":
   53         include_path_parts.append(part)
   54 
   55     include_path = None
   56     try:
   57       if repos.itemtype(include_path_parts, None) == vclib.FILE:
   58         include_path = '/'.join(include_path_parts)
   59     except vclib.ItemNotFound:
   60       pass
   61 
   62     if include_path:
   63       return '#%sinclude%s<a href="%s">"%s"</a>' % \
   64              (match.group(1), match.group(2),
   65               include_url.replace('/WHERE/', include_path), incfile)
   66     
   67   return text
   68 
   69 
   70 class HTMLBlameSource:
   71   """Wrapper around a the object by the vclib.annotate() which does
   72   HTML escaping, diff URL generation, and #include linking."""
   73   def __init__(self, repos, path_parts, diff_url, include_url, opt_rev=None):
   74     self.repos = repos
   75     self.path_parts = path_parts
   76     self.diff_url = diff_url
   77     self.include_url = include_url
   78     self.annotation, self.revision = self.repos.annotate(path_parts, opt_rev,
   79                                                          True)
   80 
   81   def __getitem__(self, idx):
   82     item = self.annotation.__getitem__(idx)
   83     diff_url = None
   84     if item.prev_rev:
   85       diff_url = '%sr1=%s&amp;r2=%s' % (self.diff_url, item.prev_rev, item.rev)
   86     thisline = link_includes(sapi.escape(item.text), self.repos,
   87                              self.path_parts, self.include_url)
   88     return _item(text=thisline, line_number=item.line_number,
   89                  rev=item.rev, prev_rev=item.prev_rev,
   90                  diff_url=diff_url, date=item.date, author=item.author)
   91 
   92 
   93 def blame(repos, path_parts, diff_url, include_url, opt_rev=None):
   94   source = HTMLBlameSource(repos, path_parts, diff_url, include_url, opt_rev)
   95   return source, source.revision
   96 
   97 
   98 def make_html(root, rcs_path):
   99   import vclib.ccvs.blame
  100   bs = vclib.ccvs.blame.BlameSource(os.path.join(root, rcs_path))
  101 
  102   line = 0
  103   old_revision = 0
  104   row_color = 'ffffff'
  105   rev_count = 0
  106 
  107   align = ' style="text-align: %s;"'
  108 
  109   sys.stdout.write('<table cellpadding="2" cellspacing="2" style="font-family: monospace; whitespace: pre;">\n')
  110   for line_data in bs:
  111     revision = line_data.rev
  112     thisline = line_data.text
  113     line = line_data.line_number
  114     author = line_data.author
  115     prev_rev = line_data.prev_rev
  116 
  117     if old_revision != revision and line != 1:
  118       if row_color == 'ffffff':
  119         row_color = 'e7e7e7'
  120       else:
  121         row_color = 'ffffff'
  122 
  123     sys.stdout.write('<tr id="l%d" style="background-color: #%s; vertical-align: center;">' % (line, row_color))
  124     sys.stdout.write('<td%s>%d</td>' % (align % 'right', line))
  125 
  126     if old_revision != revision or rev_count > 20:
  127       sys.stdout.write('<td%s>%s</td>' % (align % 'right', author or '&nbsp;'))
  128       sys.stdout.write('<td%s>%s</td>' % (align % 'left', revision))
  129       old_revision = revision
  130       rev_count = 0
  131     else:
  132       sys.stdout.write('<td>&nbsp;</td><td>&nbsp;</td>')
  133     rev_count = rev_count + 1
  134 
  135     sys.stdout.write('<td%s>%s</td></tr>\n' % (align % 'left', thisline.rstrip() or '&nbsp;'))
  136   sys.stdout.write('</table>\n')
  137 
  138 
  139 def main():
  140   import sys
  141   if len(sys.argv) != 3:
  142     print 'USAGE: %s cvsroot rcs-file' % sys.argv[0]
  143     sys.exit(1)
  144   make_html(sys.argv[1], sys.argv[2])
  145 
  146 if __name__ == '__main__':
  147   main()