mercurial/templatefilters.py
author Jesse Glick <jesse.glick@sun.com>
Sat, 17 Oct 2009 14:00:41 -0400
changeset 9748 67e5d5a2f625
parent 9722 4d9dea174b84
child 10263 25e572394f5c
permissions -rw-r--r--
Sometimes pushing to an HTTP repo fails with a useless message. abort: 'https://.../.../' does not appear to be an hg repository! Ought to produce a better diagnostics on the client. With patched 1.3.1, observed to produce an Apache HTML error message (from cgitb) including the vital text: File ".../hgwebdir.cgi", line 70, in ? wsgicgi.launch(application) File "mercurial/hgweb/wsgicgi.py", line 68, in launch File "mercurial/hgweb/hgwebdir_mod.py", line 91, in __call__ File "mercurial/hgweb/hgwebdir_mod.py", line 148, in run_wsgi File "mercurial/hgweb/hgweb_mod.py", line 100, in run_wsgi File "mercurial/hgweb/protocol.py", line 156, in unbundle File "mercurial/localrepo.py", line 2031, in addchangegroup File "mercurial/revlog.py", line 1204, in addgroup LookupError: 00manifest.i@......: unknown parent Might also be helpful if server's hgweb_mod.run_wsgi caught unexpected errors and returned a well-formed error response including the stack trace. The client patch would still be useful in this case, because it would let you diagnose issues with HTTP proxy servers and so on.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# template-filters.py - common template expansion filters
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8158
diff changeset
     5
# This software may be used and distributed according to the terms of the
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8158
diff changeset
     6
# GNU General Public License version 2, incorporated herein by reference.
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
import cgi, re, os, time, urllib, textwrap
8390
beae42f3d93b drop unused imports
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8389
diff changeset
     9
import util, encoding
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
    11
def stringify(thing):
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
    12
    '''turn nested template iterator into string.'''
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
    13
    if hasattr(thing, '__iter__') and not isinstance(thing, str):
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
    14
        return "".join([stringify(t) for t in thing if t is not None])
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
    15
    return str(thing)
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
    16
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
agescales = [("second", 1),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
             ("minute", 60),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
             ("hour", 3600),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
             ("day", 3600 * 24),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
             ("week", 3600 * 24 * 7),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
             ("month", 3600 * 24 * 30),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
             ("year", 3600 * 24 * 365)]
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
agescales.reverse()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
def age(date):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
    '''turn a (timestamp, tzoff) tuple into an age string.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
    def plural(t, c):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
        if c == 1:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
            return t
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
        return t + "s"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
    def fmt(t, c):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
        return "%d %s" % (c, plural(t, c))
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
    now = time.time()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
    then = date[0]
7682
9c8bbae02e9c templater: fix age filter to state the obvious on future timestamps
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6691
diff changeset
    39
    if then > now:
9c8bbae02e9c templater: fix age filter to state the obvious on future timestamps
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6691
diff changeset
    40
        return 'in the future'
9c8bbae02e9c templater: fix age filter to state the obvious on future timestamps
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6691
diff changeset
    41
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
    delta = max(1, int(now - then))
9722
4d9dea174b84 templater: readable dates older than 24 months revert to ISO8601 (issue1006)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9721
diff changeset
    43
    if delta > agescales[0][1] * 2:
4d9dea174b84 templater: readable dates older than 24 months revert to ISO8601 (issue1006)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9721
diff changeset
    44
        return util.shortdate(date)
4d9dea174b84 templater: readable dates older than 24 months revert to ISO8601 (issue1006)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9721
diff changeset
    45
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    for t, s in agescales:
9029
0001e49f1c11 compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents: 8697
diff changeset
    47
        n = delta // s
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
        if n >= 2 or s == 1:
9721
1d75c683ada1 templater: put 'ago' inside the age template filter
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9387
diff changeset
    49
            return '%s ago' % fmt(t, n)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
para_re = None
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
space_re = None
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
def fill(text, width):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
    '''fill many paragraphs.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
    global para_re, space_re
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
    if para_re is None:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
        para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
        space_re = re.compile(r'  +')
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
    def findparas():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
        start = 0
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
        while True:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
            m = para_re.search(text, start)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
            if not m:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
                w = len(text)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
                while w > start and text[w-1].isspace(): w -= 1
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
                yield text[start:w], text[w:]
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
                break
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
            yield text[start:m.start(0)], m.group(1)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
            start = m.end(1)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
    return "".join([space_re.sub(' ', textwrap.fill(para, width)) + rest
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
                    for para, rest in findparas()])
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
def firstline(text):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
    '''return the first line of text'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
    try:
9136
31177742f54a for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9029
diff changeset
    79
        return text.splitlines(True)[0].rstrip('\r\n')
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
    except IndexError:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
        return ''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
def nl2br(text):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
    '''replace raw newlines with xhtml line breaks.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
    return text.replace('\n', '<br/>\n')
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
def obfuscate(text):
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7682
diff changeset
    88
    text = unicode(text, encoding.encoding, 'replace')
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
    return ''.join(['&#%d;' % ord(c) for c in text])
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
def domain(author):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
    '''get domain of author, or empty string if none.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
    f = author.find('@')
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
    if f == -1: return ''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
    author = author[f+1:]
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    96
    f = author.find('>')
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
    if f >= 0: author = author[:f]
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
    return author
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
def person(author):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
    '''get name of author, or else username.'''
8697
3d53820381cb templater: retain author's full name if no email is supplied (issue1685)
Marco Beck <mbeck@miamod.de>
parents: 8591
diff changeset
   102
    if not '@' in author: return author
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
    f = author.find('<')
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
    if f == -1: return util.shortuser(author)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
    return author[:f].rstrip()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   106
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   107
def indent(text, prefix):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   108
    '''indent each non-empty line of text after first with prefix.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   109
    lines = text.splitlines()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   110
    num_lines = len(lines)
9387
20ed9909dbd9 templatefilters: indent: do not compute text.endswith('\n') in each iteration
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9136
diff changeset
   111
    endswithnewline = text[-1:] == '\n'
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   112
    def indenter():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   113
        for i in xrange(num_lines):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   114
            l = lines[i]
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   115
            if i and l.strip():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   116
                yield prefix
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
            yield l
9387
20ed9909dbd9 templatefilters: indent: do not compute text.endswith('\n') in each iteration
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9136
diff changeset
   118
            if i < num_lines - 1 or endswithnewline:
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   119
                yield '\n'
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
    return "".join(indenter())
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   122
def permissions(flags):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   123
    if "l" in flags:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   124
        return "lrwxrwxrwx"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   125
    if "x" in flags:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   126
        return "-rwxr-xr-x"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   127
    return "-rw-r--r--"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   128
6174
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   129
def xmlescape(text):
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   130
    text = (text
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   131
            .replace('&', '&amp;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   132
            .replace('<', '&lt;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   133
            .replace('>', '&gt;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   134
            .replace('"', '&quot;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   135
            .replace("'", '&#39;')) # &apos; invalid in HTML
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   136
    return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   137
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   138
_escapes = [
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   139
    ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   140
    ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   141
]
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   142
8014
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   143
def jsonescape(s):
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   144
    for k, v in _escapes:
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   145
        s = s.replace(k, v)
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   146
    return s
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   147
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   148
def json(obj):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   149
    if obj is None or obj is False or obj is True:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   150
        return {None: 'null', False: 'false', True: 'true'}[obj]
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   151
    elif isinstance(obj, int) or isinstance(obj, float):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   152
        return str(obj)
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   153
    elif isinstance(obj, str):
8014
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   154
        return '"%s"' % jsonescape(obj)
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   155
    elif isinstance(obj, unicode):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   156
        return json(obj.encode('utf-8'))
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   157
    elif hasattr(obj, 'keys'):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   158
        out = []
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   159
        for k, v in obj.iteritems():
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   160
            s = '%s: %s' % (json(k), json(v))
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   161
            out.append(s)
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   162
        return '{' + ', '.join(out) + '}'
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   163
    elif hasattr(obj, '__iter__'):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   164
        out = []
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   165
        for i in obj:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   166
            out.append(json(i))
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   167
        return '[' + ', '.join(out) + ']'
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   168
    else:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   169
        raise TypeError('cannot encode type %s' % obj.__class__.__name__)
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   170
8158
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   171
def stripdir(text):
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   172
    '''Treat the text as path and strip a directory level, if possible.'''
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   173
    dir = os.path.dirname(text)
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   174
    if dir == "":
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   175
        return os.path.basename(text)
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   176
    else:
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   177
        return dir
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   178
8234
27dbe534397b templatefilters: add "nonempty" template filter
Rocco Rutte <pdmef@gmx.net>
parents: 8225
diff changeset
   179
def nonempty(str):
8389
4b798b100c32 indentation cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8360
diff changeset
   180
    return str or "(none)"
8234
27dbe534397b templatefilters: add "nonempty" template filter
Rocco Rutte <pdmef@gmx.net>
parents: 8225
diff changeset
   181
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   182
filters = {
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   183
    "addbreaks": nl2br,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   184
    "basename": os.path.basename,
8158
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
   185
    "stripdir": stripdir,
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   186
    "age": age,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   187
    "date": lambda x: util.datestr(x),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   188
    "domain": domain,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   189
    "email": util.email,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   190
    "escape": lambda x: cgi.escape(x, True),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   191
    "fill68": lambda x: fill(x, width=68),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   192
    "fill76": lambda x: fill(x, width=76),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   193
    "firstline": firstline,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   194
    "tabindent": lambda x: indent(x, '\t'),
6229
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
   195
    "hgdate": lambda x: "%d %d" % x,
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
   196
    "isodate": lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2'),
6319
8999d1249171 Add an {isodatesec} template, to show seconds too.
Giorgos Keramidas <keramida@ceid.upatras.gr>
parents: 6229
diff changeset
   197
    "isodatesec": lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2'),
8014
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   198
    "json": json,
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
   199
    "jsonescape": jsonescape,
8591
08c93b07f5ad templatefilters: add filter to convert date to local date (issue1674)
Henrik Stuart <hg@hstuart.dk>
parents: 8390
diff changeset
   200
    "localdate": lambda x: (x[0], util.makedate()[1]),
8234
27dbe534397b templatefilters: add "nonempty" template filter
Rocco Rutte <pdmef@gmx.net>
parents: 8225
diff changeset
   201
    "nonempty": nonempty,
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   202
    "obfuscate": obfuscate,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   203
    "permissions": permissions,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   204
    "person": person,
6229
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
   205
    "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2"),
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
   206
    "rfc3339date": lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2"),
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   207
    "short": lambda x: x[:12],
6134
7b937b26adf7 Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5976
diff changeset
   208
    "shortdate": util.shortdate,
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
   209
    "stringify": stringify,
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   210
    "strip": lambda x: x.strip(),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   211
    "urlescape": lambda x: urllib.quote(x),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   212
    "user": lambda x: util.shortuser(x),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   213
    "stringescape": lambda x: x.encode('string_escape'),
6174
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
   214
    "xmlescape": xmlescape,
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
   215
}