mercurial/templater.py
author Vadim Gelfer <vadim.gelfer@gmail.com>
Sun, 26 Feb 2006 20:53:37 -0800
changeset 1899 888d298ddb91
parent 1897 58b6784cf9f1
child 1900 f2815605186e
permissions -rw-r--r--
many small changes to templater. get string code to parse escapes. uses eval now, should parse strings itself soon. let caller check if fragment is defined using "in". make templatepath take optional file name.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     1
from demandload import demandload
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     2
demandload(globals(), "cgi os re time urllib util")
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     3
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     4
class templater(object):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     5
    def __init__(self, mapfile, filters={}, defaults={}):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     6
        self.cache = {}
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     7
        self.map = {}
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     8
        self.base = os.path.dirname(mapfile)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     9
        self.filters = filters
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    10
        self.defaults = defaults
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    11
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    12
        for l in file(mapfile):
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    13
            m = re.match(r'(\S+)\s*=\s*(".*"|\'.*\')$', l)
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    14
            if m:
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    15
                self.cache[m.group(1)] = eval(m.group(2))
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    16
            else:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    17
                m = re.match(r'(\S+)\s*=\s*(\S+)', l)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    18
                if m:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    19
                    self.map[m.group(1)] = os.path.join(self.base, m.group(2))
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    20
                else:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    21
                    raise LookupError(_("unknown map entry '%s'") % l)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    22
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    23
    def __contains__(self, key):
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    24
        return key in self.cache
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    25
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    26
    def __call__(self, t, **map):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    27
        m = self.defaults.copy()
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    28
        m.update(map)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    29
        try:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    30
            tmpl = self.cache[t]
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    31
        except KeyError:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    32
            tmpl = self.cache[t] = file(self.map[t]).read()
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    33
        return self.template(tmpl, self.filters, **m)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    34
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    35
    def template(self, tmpl, filters={}, **map):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    36
        while tmpl:
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    37
            m = re.search(r"#([a-zA-Z_][a-zA-Z0-9_]*)"
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    38
                          r"((%[a-zA-Z_][a-zA-Z0-9_]*)*)"
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    39
                          r"((\|[a-zA-Z_][a-zA-Z0-9_]*)*)#", tmpl)
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    40
            if m:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    41
                yield tmpl[:m.start(0)]
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    42
                v = map.get(m.group(1), "")
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    43
                v = callable(v) and v(**map) or v
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    44
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    45
                format = m.group(2)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    46
                fl = m.group(4)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    47
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    48
                if format:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    49
                    q = v.__iter__
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    50
                    for i in q():
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    51
                        lm = map.copy()
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    52
                        lm.update(i)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    53
                        yield self(format[1:], **lm)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    54
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    55
                    v = ""
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    56
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    57
                elif fl:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    58
                    for f in fl.split("|")[1:]:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    59
                        v = filters[f](v)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    60
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    61
                yield v
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    62
                tmpl = tmpl[m.end(0):]
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    63
            else:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    64
                yield tmpl
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    65
                return
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    66
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    67
def age(x):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    68
    def plural(t, c):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    69
        if c == 1:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    70
            return t
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    71
        return t + "s"
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    72
    def fmt(t, c):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    73
        return "%d %s" % (c, plural(t, c))
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    74
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    75
    now = time.time()
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    76
    then = x[0]
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    77
    delta = max(1, int(now - then))
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    78
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    79
    scales = [["second", 1],
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    80
              ["minute", 60],
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    81
              ["hour", 3600],
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    82
              ["day", 3600 * 24],
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    83
              ["week", 3600 * 24 * 7],
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    84
              ["month", 3600 * 24 * 30],
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    85
              ["year", 3600 * 24 * 365]]
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    86
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    87
    scales.reverse()
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    88
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    89
    for t, s in scales:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    90
        n = delta / s
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    91
        if n >= 2 or s == 1:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    92
            return fmt(t, n)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    93
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    94
def nl2br(text):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    95
    return text.replace('\n', '<br/>\n')
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    96
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    97
def obfuscate(text):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    98
    return ''.join(['&#%d;' % ord(c) for c in text])
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    99
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   100
common_filters = {
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   101
    "escape": lambda x: cgi.escape(x, True),
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   102
    "urlescape": urllib.quote,
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   103
    "strip": lambda x: x.strip(),
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   104
    "age": age,
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   105
    "date": lambda x: util.datestr(x),
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   106
    "addbreaks": nl2br,
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   107
    "obfuscate": obfuscate,
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   108
    "short": (lambda x: x[:12]),
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   109
    "firstline": (lambda x: x.splitlines(1)[0]),
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   110
    "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"),
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   111
    "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"),
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   112
    }
1897
58b6784cf9f1 move hgweb.templatepath into templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1896
diff changeset
   113
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   114
def templatepath(name=None):
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   115
    for f in 'templates', '../templates':
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   116
        fl = f.split('/')
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   117
        if name: fl.append(name)
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   118
        p = os.path.join(os.path.dirname(__file__), *fl)
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   119
        if (name and os.path.exists(p)) or os.path.isdir(p):
1897
58b6784cf9f1 move hgweb.templatepath into templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1896
diff changeset
   120
            return os.path.normpath(p)