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 ' '.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)