# # # patch "templates/revisioninfo.html" # from [3e952d4ed26f5e0a2172bef6049b7eb16008bb3d] # to [6486f9dbdf014ab396b25b2d79983ab5612c8142] # # patch "viewmtn.py" # from [3c6bfb2f2ac0ffdb7d8df467af5f4ce179a4927a] # to [ad68c6d55d3ea60cb1bc9274829e978061a5f9db] # ============================================================ --- templates/revisioninfo.html 3e952d4ed26f5e0a2172bef6049b7eb16008bb3d +++ templates/revisioninfo.html 6486f9dbdf014ab396b25b2d79983ab5612c8142 @@ -21,9 +21,7 @@ #end for - -

Revision Details

============================================================ --- viewmtn.py 3c6bfb2f2ac0ffdb7d8df467af5f4ce179a4927a +++ viewmtn.py ad68c6d55d3ea60cb1bc9274829e978061a5f9db @@ -7,6 +7,7 @@ import struct import sys import web import struct +import string import rfc822 import config import common @@ -17,6 +18,7 @@ import cStringIO import tempfile import datetime import cStringIO +from colorsys import hls_to_rgb hq = cgi.escape import web @@ -245,6 +247,9 @@ def revisions_for_template(revision, rev elif stanza_type == "set": fname, attr, value = stanza[1], stanza[3], stanza[5] value = "Set attribute '%s' to '%s' upon %s" % (hq(attr), hq(value), link(mtn.File(fname, revision)).html()) + elif stanza_type == "rename": + oldname, newname = stanza[1], stanza[3] + value = "Rename %s to %s" % (hq(oldname), link(mtn.File(newname, revision)).html()) else: value = "(this stanza type is not explicitly rendered; please report this.)\n%s" % hq(str(stanza)) @@ -712,6 +717,11 @@ def ancestry_dot(revision): permitted=string.digits + string.letters + ' -<>-:,address@hidden&.+_~?/' return ''.join([t for t in s if t in permitted]) revision = mtn.Revision(revision) + original_branches = [] + for cert in ops.certs(revision): + if cert[4] == 'name' and cert[5] == 'branch': + original_branches.append(cert[7]) + # strategy: we want to show information about this revision's place # in the overall graph, both forward and back, for revision_count # revisions in both directions (if possible) @@ -774,18 +784,54 @@ digraph ancestry { edge [dir=forward]; ''' + # for each node, let's figure out it's colour, whether or not it's in our branch, + # and the label we'd give it; we need to look at all the nodes, as we need to know + # if off-screen nodes are propogates + + node_colour = {} + node_label = {} + node_in_branch = {} + + for node in nodes: + author, date = '', '' + branches = [] + for cert in ops.certs(node): + if cert[4] == 'name' and cert[5] == 'date': + date = cert[7] + elif cert[4] == 'name' and cert[5] == 'author': + author = cert[7] + elif cert[4] == 'name' and cert[5] == 'branch': + branches.append(cert[7]) + node_label[node] = '%s on %s\\n%s' % (node.abbrev(), + dot_escape(date), + dot_escape(author)) + node_colour[node] = colour_from_string(author) + for branch in original_branches: + if branch in branches: + node_in_branch[node] = True + break + # draw visited nodes; other nodes are not actually shown for node in visited: line = ' "%s" ' % (node) options = [] nodeopts = config.graphopts['nodeopts'] for option in nodeopts: - options.append('%s="%s"' % (option, nodeopts[option])) - options.append('label="%s"' % node.abbrev()) + if option == 'fillcolor' and node_colour.has_key(node): + value = '#'+node_colour[node] + elif option == 'shape' and node == revision: + value = 'hexagon' + else: + value = nodeopts[option] + options.append('%s="%s"' % (option, value)) + options.append('label="%s"' % (node_label[node])) options.append('href="%s"' % link(node).uri()) line += '[' + ','.join(options) + ']' graph += line + '\n' + for node in (nodes - visited): + graph += ' "%s" [style="invis",label=""]\n' % (node) + for (from_node, to_node) in arcs: graph += ' "%s"->"%s"\n' % (from_node, to_node) graph += '}' @@ -802,9 +848,7 @@ def ancestry_graph(revision): output_png = os.path.join(output_directory, 'graph.png') output_imagemap = os.path.join(output_directory, 'imagemap.txt') must_exist = (output_png, output_imagemap, dot_file) - debug("here we are..") if filter(lambda fname: not os.access(fname, os.R_OK), must_exist): - debug("and here we are too") open(dot_file, 'w').write(dot_data) command = "%s -Tcmapx -o %s -Tpng -o %s %s" % (config.graphopts['dot'], output_imagemap, @@ -829,7 +873,6 @@ class BranchHead: class BranchHead: def GET(self, head_method, proxy_to, branch): branch = mtn.Branch(branch) - debug("here we are, ladies and gents") valid = ('browse', 'file', 'downloadfile', 'info', 'tar', 'graph') if not proxy_to in valid: return web.notfound() @@ -839,7 +882,6 @@ class BranchHead: def proxyurl(revision): return dynamic_join('/revision/' + proxy_to + '/' + revision) if len(heads) == 1 or head_method == 'anyhead': - debug(proxyurl(heads[0])) web.redirect(proxyurl(heads[0])) else: # present an option to the user to choose the head