Mon Sep 19 02:50:04 UTC 2005 Alberto Bertogli * Implement annotate. Finally! diff -rN -u old-darcsweb/darcsweb.cgi new-darcsweb/darcsweb.cgi --- old-darcsweb/darcsweb.cgi 2015-04-18 08:11:24.000000000 +0000 +++ new-darcsweb/darcsweb.cgi 2015-04-18 08:11:24.000000000 +0000 @@ -261,11 +261,23 @@ realf = filter_file(config.repodir + '/_darcs/current/' + f) + if f and h: + print """ +| annotate + """ % { + 'myreponame': config.myreponame, + 'hash': h, + 'fname': f + } + elif f: + print """ +| annotate + """ % { "myreponame": config.myreponame, 'fname': f } + if f and os.path.isfile(realf): print """ | headblob """ % { "myreponame": config.myreponame, 'fname': f } - # TODO: annotate, when it's implemented if f and os.path.isdir(realf): print """ @@ -336,6 +348,15 @@ print """ plain """ % { "myreponame": config.myreponame, "fname": f } + elif f and h and action == "annotate": + # same for annotate + print """ +plain + """ % { + "myreponame": config.myreponame, + "fname": f, + "hash": h + } print '
' print '' @@ -631,6 +652,92 @@ cmd += ' "%s"' % fname return run_darcs(cmd) + +class Annotate: + def __init__(self): + self.fname = "" + self.creator_hash = "" + self.created_as = "" + self.lastchange_hash = "" + self.lastchange_author = "" + self.lastchange_name = "" + self.lines = [] + + class Line: + def __init__(self): + self.text = "" + self.phash = None + self.pauthor = None + +def parse_annotate(src): + import xml.dom.minidom + + annotate = Annotate() + dom = xml.dom.minidom.parse(src) + + file = dom.getElementsByTagName("file")[0] + annotate.fname = file.getAttribute("name") + + createinfo = dom.getElementsByTagName("created_as")[0] + annotate.created_as = createinfo.getAttribute("original_name") + + creator = createinfo.getElementsByTagName("patch")[0] + annotate.creator_hash = creator.getAttribute("hash") + + mod = dom.getElementsByTagName("modified")[0] + lastpatch = mod.getElementsByTagName("patch")[0] + annotate.lastchange_hash = lastpatch.getAttribute("hash") + annotate.lastchange_author = lastpatch.getAttribute("author") + + lastname = lastpatch.getElementsByTagName("name")[0] + lastname = lastname.childNodes[0].wholeText + annotate.lastchange_name = lastname + + file = dom.getElementsByTagName("file")[0] + + for l in file.childNodes: + # we're only intrested in normal and added lines + if l.nodeName not in ["normal_line", "added_line"]: + continue + line = Annotate.Line() + + if l.nodeName == "normal_line": + patch = l.getElementsByTagName("patch")[0] + phash = patch.getAttribute("hash") + pauthor = patch.getAttribute("author") + else: + # added lines inherit the creation from the annotate + # patch + phash = annotate.lastchange_hash + pauthor = annotate.lastchange_author + + text = "" + for node in l.childNodes: + if node.nodeType == node.TEXT_NODE: + text += node.wholeText + + # strip all "\n"s at the beginning; because the way darcs + # formats the xml output it makes the DOM parser to add "\n"s + # in front of it + text = text.lstrip("\n") + + line.text = text + line.phash = phash + line.pauthor = pauthor + annotate.lines.append(line) + + return annotate + +def get_annotate(fname, hash = None): + cmd = 'annotate --xml-output' + if hash: + cmd += ' --match="hash %s"' % hash + cmd += ' %s' % fname + out = run_darcs(cmd) + return parse_annotate(out) + + + # # specific html functions # @@ -829,6 +936,39 @@ count += 1 print '' +def print_annotate(ann): + print '
' + if isbinary(ann.fname): + print """ +This is a binary file and it's contents will not be displayed. +
+ """ + return + + count = 1 + for l in ann.lines: + text = fixu8(escape(l.text)) + text = text.rstrip() + + link = "%(myrname)s;a=commit;h=%(hash)s" % { + 'myrname': config.myreponame, + 'hash': l.phash + } + print """\ +
\ +%(c)4d \ +%(text)s\ +
+ """ % { + 'c': count, + 'text': text, + 'link': link + } + + count += 1 + + print '' + # # available actions @@ -1165,7 +1305,8 @@ print """ diff | - history + history | + annotate """ % { 'myreponame': config.myreponame, @@ -1246,7 +1387,8 @@ %(f)s history | - headblob + headblob | + annotate """ % { 'myrname': config.myreponame, @@ -1278,7 +1420,6 @@ print '' - # TODO: when we have annotate, put some links around here. print_blob(fname) print_footer() @@ -1290,6 +1431,36 @@ sys.stdout.write(l) +def do_annotate(fname, phash): + print_header() + ann = get_annotate(fname, phash) + print_navbar(f = fname, h = ann.lastchange_hash) + + + print """ +
+ %(name)s +
+
+ Annotate for file %(fname)s +
+ """ % { + 'myreponame': config.myreponame, + 'hash': ann.lastchange_hash, + 'name': ann.lastchange_name, + 'fname': fname, + } + + print_annotate(ann) + print_footer() + +def do_annotate_plain(fname, phash): + print_plain_header() + ann = get_annotate(fname, phash) + for l in ann.lines: + sys.stdout.write(l.text) + + def do_shortlog(topi): print_header() print_navbar() @@ -1587,6 +1758,20 @@ fname = filter_file(form["f"].value) do_darcs_fileheaddiff(phash, fname) +elif action == "annotate": + fname = filter_file(form["f"].value) + if form.has_key("h"): + phash = filter_hash(form["h"].value) + else: + phash = None + do_annotate(fname, phash) +elif action == "annotate_plain": + fname = filter_file(form["f"].value) + if form.has_key("h"): + phash = filter_hash(form["h"].value) + else: + phash = None + do_annotate_plain(fname, phash) elif action == "shortlog": if form.has_key("topi"): @@ -1633,3 +1818,4 @@ do_die() + diff -rN -u old-darcsweb/style.css new-darcsweb/style.css --- old-darcsweb/style.css 2015-04-18 08:11:24.000000000 +0000 +++ new-darcsweb/style.css 2015-04-18 08:11:24.000000000 +0000 @@ -125,6 +125,16 @@ color:#880000; } +a.line { + text-decoration:none; + color:#000000; +} + +a.line:hover { + text-decoration:none; + color:#880000; +} + table { padding:8px 4px; }