# # # patch "common.py" # from [dee058e73c68b381c4c9c4343fc7d74e3b26479e] # to [3f13b48c9393d3d7b2cf98e6c41fb750f6980f12] # # patch "mtn.py" # from [ef35d2dfd3db51e1dfe9231c0afd315570fab28e] # to [e65ea7979a3cbfe80bd49a6cbd83ca69f28e270f] # # patch "templates/revisionbrowse.html" # from [6b09eeedff5f706aeec8cc0372596cf537550fcb] # to [e2cbeec9a51d57941e238432870701b13f1e5bbc] # # patch "viewmtn.py" # from [78f8a8a5059ca314bea367c341c121db7bbddb84] # to [2bad66fa28530d9215ebc88db099b5d3886917da] # ============================================================ --- common.py dee058e73c68b381c4c9c4343fc7d74e3b26479e +++ common.py 3f13b48c9393d3d7b2cf98e6c41fb750f6980f12 @@ -34,18 +34,15 @@ def ago(event): now = datetime.datetime.utcnow() ago = now - event if ago.days > 0: - rv = "%s, %s" % (plural(ago.days, "day", "days"), - plural(ago.seconds / 3600, "hour", "hours")) + rv = "%s" % (plural(ago.days, "day", "days")) elif ago.seconds > 3600: hours = ago.seconds / 3600 minutes = (ago.seconds - (hours * 3600)) / 60 - rv = "%s, %s" % (plural(hours, "hour", "hours"), - plural(minutes, "minute", "minutes")) + rv = "%s" % (plural(hours, "hour", "hours")) else: minutes = ago.seconds / 60 seconds = (ago.seconds - (minutes * 60)) - rv = "%s, %s" % (plural(minutes, "minute", "minutes"), - plural(seconds, "second", "seconds")) + rv = "%s" % (plural(minutes, "minute", "minutes")) return rv # is it binary? ============================================================ --- mtn.py ef35d2dfd3db51e1dfe9231c0afd315570fab28e +++ mtn.py e65ea7979a3cbfe80bd49a6cbd83ca69f28e270f @@ -29,7 +29,7 @@ class Revision(str): class Revision(str): def __init__(self, v): - # special case that must be handled: empty (initial) revisino ID '' + # special case that must be handled: empty (initial) revision ID '' str.__init__(v) self.obj_type = "revision" if v != '' and not revision_re_c.match(self): @@ -37,6 +37,11 @@ class Revision(str): def abbrev(self): return '[' + self[:8] + '..]' +class Author(str): + def __init__(self, v): + str.__init__(v) + self.obj_type = "author" + class Runner: def __init__(self, monotone, database): self.base_command = [monotone, "--db=%s" % pipes.quote(database)] ============================================================ --- templates/revisionbrowse.html 6b09eeedff5f706aeec8cc0372596cf537550fcb +++ templates/revisionbrowse.html e2cbeec9a51d57941e238432870701b13f1e5bbc @@ -44,8 +44,9 @@ $branch_links #filter Filter - $author - #filter WebSafe + $link($author).html() + #filter WebSafe + $shortlog ============================================================ --- viewmtn.py 78f8a8a5059ca314bea367c341c121db7bbddb84 +++ viewmtn.py 2bad66fa28530d9215ebc88db099b5d3886917da @@ -1,8 +1,9 @@ import web #!/usr/bin/env python2.4 import cgi import mtn import web +import rfc822 import config import common import urllib @@ -39,7 +40,7 @@ static_join = lambda path: urlparse.urlj dynamic_join = lambda path: urlparse.urljoin(config.dynamic_uri_path, path) static_join = lambda path: urlparse.urljoin(config.static_uri_path, path) -def quicklog(changelog): +def quicklog(changelog, max_size=None): interesting_line = None for line in changelog: line = line.strip() @@ -50,6 +51,12 @@ def quicklog(changelog): return "" if interesting_line.startswith('*'): interesting_line = interesting_line[1:].strip() + if max_size and len(interesting_line) > max_size: + interesting_line = interesting_line[:max_size] + r_wspc = interesting_line.rfind(' ') + if r_wspc <> -1: + interesting_line = interesting_line[:r_wspc] + interesting_line += '..' return interesting_line def nbhq(s): @@ -63,6 +70,7 @@ class Link: class Link: def __init__(self, description=None, link_type=None, **kwargs): + self.absolute_uri = None self.relative_uri = None self.description = description def uri(self): @@ -75,9 +83,24 @@ class Link: d = hq(override_description) else: d = self.description - return '%s' % (dynamic_join(self.relative_uri), - d) + if self.relative_uri: + uri = dynamic_join(self.relative_uri) + elif self.absolute_uri: + uri = self.absolute_uri + else: + return self.description + return '%s' % (uri, d) +class AuthorLink(Link): + def __init__(self, author, **kwargs): + Link.__init__(*(self, ), **kwargs) + name, email = rfc822.parseaddr(author) + if name and email: + self.absolute_uri = "mailto:%s" % urllib.quote(email) + self.description = hq(email) + else: + self.description = author + class RevisionLink(Link): def __init__(self, revision, **kwargs): link_type = kwargs.get("link_type") @@ -214,10 +237,11 @@ type_to_link_class = { yield grouping, stanzas type_to_link_class = { + 'author' : AuthorLink, 'branch' : BranchLink, 'diff' : DiffLink, + 'dir' : DirLink, 'file' : FileLink, - 'dir' : DirLink, 'revision' : RevisionLink, 'tag' : TagLink, } @@ -334,7 +358,7 @@ class BranchChanges: rv = [] for rev, certs in revs: rev_branch = "" - revision, diffs, ago, author, changelog, shortlog, when = mtn.Revision(rev), [], "", "", "", "", "" + revision, diffs, ago, author, changelog, shortlog, when = mtn.Revision(rev), [], "", mtn.Author(""), "", "", "" for cert in certs: if cert[4] != 'name': continue @@ -345,7 +369,7 @@ class BranchChanges: revdate = common.parse_timecert(when) ago = common.ago(revdate) elif cert[5] == 'author': - author = cert[7] + author = mtn.Author(cert[7]) elif cert[5] == 'changelog': changelog = normalise_changelog(cert[7]) shortlog = quicklog(changelog) @@ -360,7 +384,7 @@ class BranchChanges: diffs = '| ' + ', '.join(map(lambda d: link(d).html('diff'), diffs)) else: diffs = '' - rv.append((revision, diffs, ago, author, '\n'.join(changelog), shortlog, when)) + rv.append((revision, diffs, ago, mtn.Author(author), '\n'.join(changelog), shortlog, when)) return rv branch = mtn.Branch(branch) @@ -558,12 +582,12 @@ class RevisionBrowse(RevisionPage): continue name, value = cert[5], cert[7] if name == "author": - author = value + author = mtn.Author(value) elif name == "date": revdate = common.parse_timecert(value) ago = common.ago(revdate) elif name == "changelog": - shortlog = quicklog(normalise_changelog(value)) + shortlog = quicklog(normalise_changelog(value), 40) to_return = (author, ago, shortlog) return [t or "" for t in to_return] @@ -582,12 +606,12 @@ class RevisionBrowse(RevisionPage): content_mark = mtn.Revision(content_marks[0]) author, ago, shortlog = get_certinfo(content_mark) else: - author, ago, shortlog, content_mark = "", "", "", None + author, ago, shortlog, content_mark = mtn.Author(""), "", "", None if stanza_type == "file": file_obj = mtn.File(this_path, revision) else: file_obj = mtn.Dir(this_path, revision) - yield (stanza_type, file_obj, nbhq(author), ago, content_mark, shortlog) + yield (stanza_type, file_obj, author, ago, content_mark, shortlog) def path_links(components): # we always want a link to '/'