viewvc-4intranet/lib/blame.py

185 lines
5.3 KiB
Python
Raw Normal View History

#!/usr/local/bin/python
# -*-python-*-
#
# Copyright (C) 2000-2002 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewCVS
# distribution or at http://viewcvs.sourceforge.net/license-1.html.
#
# Contact information:
# Greg Stein, PO Box 760, Palo Alto, CA, 94302
# gstein@lyra.org, http://viewcvs.sourceforge.net/
#
# -----------------------------------------------------------------------
#
# blame.py: Annotate each line of a CVS file with its author,
# revision #, date, etc.
#
# -----------------------------------------------------------------------
#
# This software is being maintained as part of the ViewCVS project.
# Information is available at:
# http://viewcvs.sourceforge.net/
#
# This file is based on the cvsblame.pl portion of the Bonsai CVS tool,
# developed by Steve Lamm for Netscape Communications Corporation. More
# information about Bonsai can be found at
# http://www.mozilla.org/bonsai.html
#
# cvsblame.pl, in turn, was based on Scott Furman's cvsblame script
#
# -----------------------------------------------------------------------
#
import string
import os
import re
import time
import math
import cgi
import vclib
import vclib.ccvs.blame
re_includes = re.compile('\\#(\\s*)include(\\s*)"(.*?)"')
def link_includes(text, repos, path_parts, include_url):
match = re_includes.match(text)
if match:
incfile = match.group(3)
# check current directory and parent directory for file
for depth in (-1, -2):
include_path = path_parts[:depth] + [incfile]
try:
# will throw if path doesn't exist
if repos.itemtype(include_path) == vclib.FILE:
break
except vclib.ItemNotFound:
pass
else:
include_path = None
if include_path:
url = string.replace(include_url, '/WHERE/',
string.join(include_path, '/'))
return '#%sinclude%s<a href="%s">"%s"</a>' % \
(match.group(1), match.group(2), url, incfile)
return text
class HTMLBlameSource:
"""Wrapper around a the object by the vclib.annotate() which does
HTML escaping, diff URL generation, and #include linking."""
def __init__(self, repos, path_parts, diff_url, include_url, opt_rev=None):
self.repos = repos
self.path_parts = path_parts
self.diff_url = diff_url
self.include_url = include_url
self.annotation, self.revision = self.repos.annotate(path_parts, opt_rev)
def __getitem__(self, idx):
item = self.annotation.__getitem__(idx)
diff_url = None
if item.prev_rev:
diff_url = '%sr1=%s&amp;r2=%s' % (self.diff_url, item.prev_rev, item.rev)
thisline = link_includes(cgi.escape(item.text), self.repos,
self.path_parts, self.include_url)
return _item(text=thisline, line_number=item.line_number,
rev=item.rev, prev_rev=item.prev_rev,
diff_url=diff_url, date=item.date, author=item.author)
def blame(repos, path_parts, diff_url, include_url, opt_rev=None):
source = HTMLBlameSource(repos, path_parts, diff_url, include_url, opt_rev)
return source, source.revision
class _item:
def __init__(self, **kw):
vars(self).update(kw)
def make_html(root, rcs_path):
bs = vclib.ccvs.blame.BlameSource(os.path.join(root, rcs_path))
count = bs.num_lines
if count == 0:
count = 1
line_num_width = int(math.log10(count)) + 1
revision_width = 3
author_width = 5
line = 0
old_revision = 0
row_color = ''
inMark = 0
rev_count = 0
This patch (mostly by Marten Thavenius) upgrades ViewCVS to XHTML 1.0 Strict. Changes have been made in the EZT templates, the CSS files, HTML code embedded in the Python files as well as in the help files. The original code structure and design is the very same. No other improvements have been made to the browser code and it still uses the old layout tables to create the page grid. Apart from the XHTML/CSS code changes, the patch adds an argument (-x x) for CVSGraph in viewcvs.py in the view_cvsgraph function to tell CVSGraph to generate XHTML code. For Mozilla/Firefox to recognize the id attribute in the image map generated, the content-type must be set to application/xhtml+xml (see https://bugzilla.mozilla.org/show_bug.cgi?id=109445). This patch does however not change the content-type, but uses an ugly hack to make the CVSGraph output work in Mozilla with the current text/html content-type: a name attribute is merged into the id attribute in the map_name defined in the cvsgraph.conf.dist file. The XHTML code does not contain the standard XML declaration, just the XHTML 1.0 Strict Doctype. This is to keep ViewCVS as encoding agnostic as before and let the browser decide which encoding to use. An XML file without the encoding declared must be interpreted as UTF-8 (or UTF-16 if the byte order mark is included). * viewcvs/cvsgraph.conf.dist Add name="" hack to the 'map_name' variable so Mozilla/Firefox will work. * viewcvs/lib/ezt.py XHTML-ize sample output. * viewcvs/lib/viewcvs.py XHTML-ize hard-coded output. (view_cvsgraph): Pass "-x x" to cvsgraph to force XHTML production. * viewcvs/lib/blame.py * viewcvs/lib/debug.py * viewcvs/lib/py2html.py * viewcvs/lib/query.py * viewcvs/lib/vclib/bincvs/__init__.py * viewcvs/templates/annotate.ezt * viewcvs/templates/diff.ezt * viewcvs/templates/dir_alternate.ezt * viewcvs/templates/directory.ezt * viewcvs/templates/error.ezt * viewcvs/templates/graph.ezt * viewcvs/templates/log.ezt * viewcvs/templates/log_table.ezt * viewcvs/templates/markup.ezt * viewcvs/templates/query.ezt * viewcvs/templates/query_form.ezt * viewcvs/templates/query_results.ezt * viewcvs/templates/revision.ezt * viewcvs/templates/roots.ezt * viewcvs/templates/docroot/help_dirview.html * viewcvs/templates/docroot/help_log.html * viewcvs/templates/docroot/help_logtable.html * viewcvs/templates/docroot/help_query.html * viewcvs/templates/docroot/help_rootview.html * viewcvs/templates/docroot/styles.css * viewcvs/templates/include/branch.ezt * viewcvs/templates/include/branch_form.ezt * viewcvs/templates/include/diff_form.ezt * viewcvs/templates/include/dir_footer.ezt * viewcvs/templates/include/dir_header.ezt * viewcvs/templates/include/file_header.ezt * viewcvs/templates/include/footer.ezt * viewcvs/templates/include/header.ezt * viewcvs/templates/include/paging.ezt * viewcvs/templates/include/sort.ezt * viewcvs/templates/include/view_tag.ezt XHTML-ize hard-coded output and templatized data. * viewcvs/CHANGES Note this change. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1109 8cb11bc2-c004-0410-86c3-e597b4017df7
2005-09-28 21:06:16 +04:00
open_table_tag = '<table cellpadding="0" cellspacing="0">'
startOfRow = '<tr><td colspan="3"%s><pre>'
endOfRow = '</td></tr>'
print open_table_tag + (startOfRow % '')
for line_data in bs:
revision = line_data.rev
thisline = line_data.text
line = line_data.line_number
author = line_data.author
prev_rev = line_data.prev_rev
output = ''
if old_revision != revision and line != 1:
if row_color == '':
This patch (mostly by Marten Thavenius) upgrades ViewCVS to XHTML 1.0 Strict. Changes have been made in the EZT templates, the CSS files, HTML code embedded in the Python files as well as in the help files. The original code structure and design is the very same. No other improvements have been made to the browser code and it still uses the old layout tables to create the page grid. Apart from the XHTML/CSS code changes, the patch adds an argument (-x x) for CVSGraph in viewcvs.py in the view_cvsgraph function to tell CVSGraph to generate XHTML code. For Mozilla/Firefox to recognize the id attribute in the image map generated, the content-type must be set to application/xhtml+xml (see https://bugzilla.mozilla.org/show_bug.cgi?id=109445). This patch does however not change the content-type, but uses an ugly hack to make the CVSGraph output work in Mozilla with the current text/html content-type: a name attribute is merged into the id attribute in the map_name defined in the cvsgraph.conf.dist file. The XHTML code does not contain the standard XML declaration, just the XHTML 1.0 Strict Doctype. This is to keep ViewCVS as encoding agnostic as before and let the browser decide which encoding to use. An XML file without the encoding declared must be interpreted as UTF-8 (or UTF-16 if the byte order mark is included). * viewcvs/cvsgraph.conf.dist Add name="" hack to the 'map_name' variable so Mozilla/Firefox will work. * viewcvs/lib/ezt.py XHTML-ize sample output. * viewcvs/lib/viewcvs.py XHTML-ize hard-coded output. (view_cvsgraph): Pass "-x x" to cvsgraph to force XHTML production. * viewcvs/lib/blame.py * viewcvs/lib/debug.py * viewcvs/lib/py2html.py * viewcvs/lib/query.py * viewcvs/lib/vclib/bincvs/__init__.py * viewcvs/templates/annotate.ezt * viewcvs/templates/diff.ezt * viewcvs/templates/dir_alternate.ezt * viewcvs/templates/directory.ezt * viewcvs/templates/error.ezt * viewcvs/templates/graph.ezt * viewcvs/templates/log.ezt * viewcvs/templates/log_table.ezt * viewcvs/templates/markup.ezt * viewcvs/templates/query.ezt * viewcvs/templates/query_form.ezt * viewcvs/templates/query_results.ezt * viewcvs/templates/revision.ezt * viewcvs/templates/roots.ezt * viewcvs/templates/docroot/help_dirview.html * viewcvs/templates/docroot/help_log.html * viewcvs/templates/docroot/help_logtable.html * viewcvs/templates/docroot/help_query.html * viewcvs/templates/docroot/help_rootview.html * viewcvs/templates/docroot/styles.css * viewcvs/templates/include/branch.ezt * viewcvs/templates/include/branch_form.ezt * viewcvs/templates/include/diff_form.ezt * viewcvs/templates/include/dir_footer.ezt * viewcvs/templates/include/dir_header.ezt * viewcvs/templates/include/file_header.ezt * viewcvs/templates/include/footer.ezt * viewcvs/templates/include/header.ezt * viewcvs/templates/include/paging.ezt * viewcvs/templates/include/sort.ezt * viewcvs/templates/include/view_tag.ezt XHTML-ize hard-coded output and templatized data. * viewcvs/CHANGES Note this change. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1109 8cb11bc2-c004-0410-86c3-e597b4017df7
2005-09-28 21:06:16 +04:00
row_color = ' style="background-color:#e7e7e7"'
else:
row_color = ''
if not inMark:
output = output + endOfRow + (startOfRow % row_color)
output = output + '<a name="%d">%*d</a>' % (line, line_num_width, line)
if old_revision != revision or rev_count > 20:
revision_width = max(revision_width, len(revision))
output = output + ' '
author_width = max(author_width, len(author))
output = output + ('%-*s ' % (author_width, author))
output = output + revision
if prev_rev:
output = output + '</a>'
output = output + (' ' * (revision_width - len(revision) + 1))
old_revision = revision
rev_count = 0
else:
output = output + ' ' + (' ' * (author_width + revision_width))
rev_count = rev_count + 1
output = output + thisline
# Close the highlighted section
#if (defined $mark_cmd and mark_cmd != 'begin'):
# chop($output)
# output = output + endOfRow + (startOfRow % row_color)
# inMark = 0
print output
print endOfRow + '</table>'
def main():
import sys
if len(sys.argv) != 3:
print 'USAGE: %s cvsroot rcs-file' % sys.argv[0]
sys.exit(1)
make_html(sys.argv[1], sys.argv[2])
if __name__ == '__main__':
main()