# HG changeset patch # User Vadim Gelfer # Date 1140987568 28800 # Node ID f8f818a04f5bb16ca727b16bac6f838344b477a9 # Parent 414e81ae971f1751995b71cf082e2f98256f677a move hgweb template code out to templater diff --git a/mercurial/hgweb.py b/mercurial/hgweb.py --- a/mercurial/hgweb.py +++ b/mercurial/hgweb.py @@ -6,12 +6,12 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. -import os, cgi, sys, urllib +import os, cgi, sys import mimetypes from demandload import demandload demandload(globals(), "mdiff time re socket zlib errno ui hg ConfigParser") demandload(globals(), "zipfile tempfile StringIO tarfile BaseHTTPServer util") -demandload(globals(), "mimetypes") +demandload(globals(), "mimetypes templater") from node import * from i18n import gettext as _ @@ -21,39 +21,6 @@ def templatepath(): if os.path.isdir(p): return os.path.normpath(p) -def age(x): - def plural(t, c): - if c == 1: - return t - return t + "s" - def fmt(t, c): - return "%d %s" % (c, plural(t, c)) - - now = time.time() - then = x[0] - delta = max(1, int(now - then)) - - scales = [["second", 1], - ["minute", 60], - ["hour", 3600], - ["day", 3600 * 24], - ["week", 3600 * 24 * 7], - ["month", 3600 * 24 * 30], - ["year", 3600 * 24 * 365]] - - scales.reverse() - - for t, s in scales: - n = delta / s - if n >= 2 or s == 1: - return fmt(t, n) - -def nl2br(text): - return text.replace('\n', '
\n') - -def obfuscate(text): - return ''.join(['&#%d;' % ord(c) for c in text]) - def up(p): if p[0] != "/": p = "/" + p @@ -132,78 +99,6 @@ class hgrequest(object): headers.append(('Content-length', str(size))) self.header(headers) -class templater(object): - def __init__(self, mapfile, filters={}, defaults={}): - self.cache = {} - self.map = {} - self.base = os.path.dirname(mapfile) - self.filters = filters - self.defaults = defaults - - for l in file(mapfile): - m = re.match(r'(\S+)\s*=\s*"(.*)"$', l) - if m: - self.cache[m.group(1)] = m.group(2) - else: - m = re.match(r'(\S+)\s*=\s*(\S+)', l) - if m: - self.map[m.group(1)] = os.path.join(self.base, m.group(2)) - else: - raise LookupError(_("unknown map entry '%s'") % l) - - def __call__(self, t, **map): - m = self.defaults.copy() - m.update(map) - try: - tmpl = self.cache[t] - except KeyError: - tmpl = self.cache[t] = file(self.map[t]).read() - return self.template(tmpl, self.filters, **m) - - def template(self, tmpl, filters={}, **map): - while tmpl: - m = re.search(r"#([a-zA-Z0-9]+)((%[a-zA-Z0-9]+)*)((\|[a-zA-Z0-9]+)*)#", tmpl) - if m: - yield tmpl[:m.start(0)] - v = map.get(m.group(1), "") - v = callable(v) and v(**map) or v - - format = m.group(2) - fl = m.group(4) - - if format: - q = v.__iter__ - for i in q(): - lm = map.copy() - lm.update(i) - yield self(format[1:], **lm) - - v = "" - - elif fl: - for f in fl.split("|")[1:]: - v = filters[f](v) - - yield v - tmpl = tmpl[m.end(0):] - else: - yield tmpl - return - -common_filters = { - "escape": lambda x: cgi.escape(x, True), - "urlescape": urllib.quote, - "strip": lambda x: x.strip(), - "age": age, - "date": lambda x: util.datestr(x), - "addbreaks": nl2br, - "obfuscate": obfuscate, - "short": (lambda x: x[:12]), - "firstline": (lambda x: x.splitlines(1)[0]), - "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"), - "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"), - } - class hgweb(object): def __init__(self, repo, name=None): if type(repo) == type(""): @@ -910,12 +805,12 @@ class hgweb(object): self.reponame = (self.repo.ui.config("web", "name") or uri.strip('/') or self.repo.root) - self.t = templater(m, common_filters, - {"url": url, - "repo": self.reponame, - "header": header, - "footer": footer, - }) + self.t = templater.templater(m, templater.common_filters, + {"url": url, + "repo": self.reponame, + "header": header, + "footer": footer, + }) if not req.form.has_key('cmd'): req.form['cmd'] = [self.t.cache['default'],] diff --git a/mercurial/templater.py b/mercurial/templater.py new file mode 100644 --- /dev/null +++ b/mercurial/templater.py @@ -0,0 +1,107 @@ +from demandload import demandload +demandload(globals(), "cgi os re time urllib util") + +class templater(object): + def __init__(self, mapfile, filters={}, defaults={}): + self.cache = {} + self.map = {} + self.base = os.path.dirname(mapfile) + self.filters = filters + self.defaults = defaults + + for l in file(mapfile): + m = re.match(r'(\S+)\s*=\s*"(.*)"$', l) + if m: + self.cache[m.group(1)] = m.group(2) + else: + m = re.match(r'(\S+)\s*=\s*(\S+)', l) + if m: + self.map[m.group(1)] = os.path.join(self.base, m.group(2)) + else: + raise LookupError(_("unknown map entry '%s'") % l) + + def __call__(self, t, **map): + m = self.defaults.copy() + m.update(map) + try: + tmpl = self.cache[t] + except KeyError: + tmpl = self.cache[t] = file(self.map[t]).read() + return self.template(tmpl, self.filters, **m) + + def template(self, tmpl, filters={}, **map): + while tmpl: + m = re.search(r"#([a-zA-Z0-9]+)((%[a-zA-Z0-9]+)*)((\|[a-zA-Z0-9]+)*)#", tmpl) + if m: + yield tmpl[:m.start(0)] + v = map.get(m.group(1), "") + v = callable(v) and v(**map) or v + + format = m.group(2) + fl = m.group(4) + + if format: + q = v.__iter__ + for i in q(): + lm = map.copy() + lm.update(i) + yield self(format[1:], **lm) + + v = "" + + elif fl: + for f in fl.split("|")[1:]: + v = filters[f](v) + + yield v + tmpl = tmpl[m.end(0):] + else: + yield tmpl + return + +def age(x): + def plural(t, c): + if c == 1: + return t + return t + "s" + def fmt(t, c): + return "%d %s" % (c, plural(t, c)) + + now = time.time() + then = x[0] + delta = max(1, int(now - then)) + + scales = [["second", 1], + ["minute", 60], + ["hour", 3600], + ["day", 3600 * 24], + ["week", 3600 * 24 * 7], + ["month", 3600 * 24 * 30], + ["year", 3600 * 24 * 365]] + + scales.reverse() + + for t, s in scales: + n = delta / s + if n >= 2 or s == 1: + return fmt(t, n) + +def nl2br(text): + return text.replace('\n', '
\n') + +def obfuscate(text): + return ''.join(['&#%d;' % ord(c) for c in text]) + +common_filters = { + "escape": lambda x: cgi.escape(x, True), + "urlescape": urllib.quote, + "strip": lambda x: x.strip(), + "age": age, + "date": lambda x: util.datestr(x), + "addbreaks": nl2br, + "obfuscate": obfuscate, + "short": (lambda x: x[:12]), + "firstline": (lambda x: x.splitlines(1)[0]), + "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"), + "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"), + }