Below is the file 'render.py' from this revision. You can also download the file.

# Copyright (C) 2005 Grahame Bowland <grahame@angrygoats.net>
#
# This program is made available under the GNU GPL version 2.0 or
# greater. See the accompanying file COPYING for details.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.

import cgi, urllib, web
import mtn, release, config, common

hq = cgi.escape

def quicklog(changelog, max_size=None):
    interesting_line = None
    for line in changelog:
        line = line.strip()
        if line:
            interesting_line = line
            break
    if not interesting_line:
        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 timecert(certs):
    revdate = None
    for cert in certs:
        if cert[4] == 'name' and cert[5] == 'date':
            revdate = common.parse_timecert(cert[7])
    return revdate

def normalise_changelog(changelog):
    changelog = map(hq, changelog.split('\n'))
    if changelog and changelog[-1] == '':
        changelog = changelog[:-1]
    return changelog

class Diff(object):
    def __init__(self, from_rev, to_rev, fname=None):
        self.obj_type = 'diff'
        self.fname = fname
        self.from_rev = from_rev
        self.to_rev = to_rev

def prettify(s):
    return '&nbsp;'.join([hq(x[0].upper() + x[1:]) for x in s.replace("_", "").split(" ")])

def certs_for_template(ctxt, cert_gen):
    for cert in cert_gen:
        if cert[0] == 'key' and len(cert) != 10:
            raise Exception("Not a correctly formatted certificate: %s" % cert)
        if cert[3] != 'ok':
            raise Exception("Certificate failed check.")

        key = cert[1]
        name = cert[5]
        value = cert[7]
        if name == "branch":
            value = ctxt.link(mtn.Branch(value)).html()
        else:
            value = '<br />'.join(map(hq, value.split('\n')))

        yield { 'key' : key,
                'name' : prettify(name),
                'value' : value }

def revisions_for_template(ctxt, revision, rev_gen):
    old_revisions = []
    stanzas = []
    grouping = None
    for stanza in rev_gen:
        stanza_type = stanza[0]
        description, value = prettify(stanza_type), None

        if grouping == None:
            grouping = description
        if description != grouping:
            if len(stanzas) > 0:
                yield grouping, stanzas
            grouping, stanzas = description, []

        if stanza_type == "format_version" or \
                stanza_type == "new_manifest":
            continue
        elif stanza_type == "patch":
            fname, from_id, to_id = stanza[1], stanza[3], stanza[5]
            # if from_id is null, this is a new file
            # since we're showing that information under "Add", so
            # skip it here
            if not from_id:
                continue
            diff_links = ','.join([ctxt.link(Diff(old_revision, revision, fname)).html() for old_revision in old_revisions])
            value = "Patch file %s (%s)" % (ctxt.link(mtn.File(fname, revision)).html(), diff_links)
        elif stanza_type == "old_revision":
            old_revision = mtn.Revision(stanza[1])
            if old_revision.is_empty:
                value = "This revision is has no ancestor."
            else:
                old_revisions.append(old_revision)
                value = "Old revision is: %s (%s)" % (ctxt.link(old_revision).html(), ctxt.link(Diff(old_revision, revision)).html())
        elif stanza_type == "add_file":
            fname = stanza[1]
            value = "Add file: %s" % (ctxt.link(mtn.File(fname, revision)).html())
        elif stanza_type == "add_dir":
            dname = stanza[1]
            value = "Add directory: %s" % (hq(dname))
        elif stanza_type == "delete":
            fname = stanza[1]
            value = "Delete: %s" % (hq(fname))
        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), ctxt.link(mtn.File(fname, revision)).html())
        elif stanza_type == "rename":
            oldname, newname = stanza[1], stanza[3]
            value = "Rename %s to %s" % (hq(oldname), ctxt.link(mtn.File(newname, revision)).html())
        else:
            value = "(this stanza type is not explicitly rendered; please report this.)\n%s" % hq(str(stanza))

        if description != None:
            stanzas.append(value)

    if len(stanzas) > 0:
        yield grouping, stanzas


class Renderer(object):
    def __init__(self, **kwargs):
        # any templates that can be inherited from, should be added to the list here
        self.templates = [ ('base.html', 'base'),
                           ('revision.html', 'revision'),
                           ('branch.html', 'branch'),
                           ('revisionfile.html', 'revisionfile'),
                           ('revisionfileview.html', 'revisionfileview') ]
        self._templates_loaded = False

        # these variables will be available to any template
        self.terms = {
            'dynamic_uri_path' : config.dynamic_uri_path,
            'urllib_quote' : urllib.quote,
            'static_uri_path' : config.static_uri_path,
            'version' : release.version,
            }
        self.terms.update(kwargs)

    def load_templates(self):
        if self._templates_loaded: return
        for template, mod_name in self.templates:
            web.render(template, None, True, mod_name)
        self._templates_loaded = True

    def render(self, ctxt, template, **kwargs):
        self.load_templates()
        terms = self.terms.copy()
        terms.update(kwargs)
        terms['link'] = ctxt.link
        terms['perdb_join'] = ctxt.perdb_join
        terms['nodb_join'] = ctxt.nodb_join
        terms['static_join'] = ctxt.static_join
        web.render(template, terms)