Mon Sep 19 02:50:04 UTC 2005 Alberto Bertogli <albertogli@telpin.com.ar>
* Implement annotate.
Finally!
{
hunk ./darcsweb.cgi 264
+ if f and h:
+ print """
+| <a href="%(myreponame)s;a=annotate;f=%(fname)s;h=%(hash)s">annotate</a>
+ """ % {
+ 'myreponame': config.myreponame,
+ 'hash': h,
+ 'fname': f
+ }
+ elif f:
+ print """
+| <a href="%(myreponame)s;a=annotate;f=%(fname)s">annotate</a>
+ """ % { "myreponame": config.myreponame, 'fname': f }
+
hunk ./darcsweb.cgi 281
- # TODO: annotate, when it's implemented
hunk ./darcsweb.cgi 351
+ elif f and h and action == "annotate":
+ # same for annotate
+ print """
+<a href="%(myreponame)s;a=annotate_plain;f=%(fname)s;h=%(hash)s">plain</a>
+ """ % {
+ "myreponame": config.myreponame,
+ "fname": f,
+ "hash": h
+ }
hunk ./darcsweb.cgi 655
+
+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)
+
+
+
hunk ./darcsweb.cgi 939
+def print_annotate(ann):
+ print '<div class="page_body">'
+ if isbinary(ann.fname):
+ print """
+<i>This is a binary file and it's contents will not be displayed.</i>
+</div>
+ """
+ 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 """\
+<div class="pre">\
+<a href="%(link)s" class="linenr">%(c)4d</a> \
+<a href="%(link)s" class="line">%(text)s</a>\
+</div>
+ """ % {
+ 'c': count,
+ 'text': text,
+ 'link': link
+ }
+
+ count += 1
+
+ print '</div>'
+
hunk ./darcsweb.cgi 1308
- <a href="%(myreponame)s;a=filehistory;f=%(file)s">history</a>
+ <a href="%(myreponame)s;a=filehistory;f=%(file)s">history</a> |
+ <a href="%(myreponame)s;a=annotate;h=%(hash)s;f=%(file)s">annotate</a>
hunk ./darcsweb.cgi 1390
- <a href="%(myrname)s;a=headblob;f=%(fullf)s">headblob</a>
+ <a href="%(myrname)s;a=headblob;f=%(fullf)s">headblob</a> |
+ <a href="%(myrname)s;a=annotate;f=%(fullf)s">annotate</a>
hunk ./darcsweb.cgi 1423
- # TODO: when we have annotate, put some links around here.
hunk ./darcsweb.cgi 1432
+
+
+def do_annotate(fname, phash):
+ print_header()
+ ann = get_annotate(fname, phash)
+ print_navbar(f = fname, h = ann.lastchange_hash)
+
+
+ print """
+<div>
+ <a class="title" href="%(myreponame)s;a=commit;h=%(hash)s">%(name)s</a>
+</div>
+<div class="page_path"><b>
+ Annotate for file %(fname)s
+</b></div>
+ """ % {
+ '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)
hunk ./darcsweb.cgi 1761
+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)
hunk ./darcsweb.cgi 1819
+
hunk ./style.css 128
+a.line {
+ text-decoration:none;
+ color:#000000;
+}
+
+a.line:hover {
+ text-decoration:none;
+ color:#880000;
+}
+
}