mercurial/hgweb/webutil.py
author Augie Fackler <augie@google.com>
Mon, 16 Oct 2017 22:44:06 -0400
changeset 34807 3caec3c032c8
parent 34403 407ebe7a9b93
child 34855 35c6a54ec1ff
permissions -rw-r--r--
webutil: use pycompat.bytestr() instead of str() Stops us from choking the templater on Python 3. With this patch applied, much of hgweb works correctly in Python 3. The notable exception is the graph page, which chokes because it gets node IDs as str instead of bytes. Differential Revision: https://phab.mercurial-scm.org/D1135
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     1
# hgweb/webutil.py - utility library for the web interface.
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     2
#
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     3
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     4
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7717
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9402
diff changeset
     7
# GNU General Public License version 2 or any later version.
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     8
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
     9
from __future__ import absolute_import
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    10
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    11
import copy
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    12
import difflib
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    13
import os
26162
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
    14
import re
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    15
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    16
from ..i18n import _
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    17
from ..node import hex, nullid, short
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    18
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    19
from .common import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    20
    ErrorResponse,
31665
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
    21
    HTTP_BAD_REQUEST,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    22
    HTTP_NOT_FOUND,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    23
    paritygen,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    24
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    25
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    26
from .. import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    27
    context,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    28
    error,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    29
    match,
31808
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31727
diff changeset
    30
    mdiff,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    31
    patch,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    32
    pathutil,
34807
3caec3c032c8 webutil: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 34403
diff changeset
    33
    pycompat,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    34
    templatefilters,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    35
    ui as uimod,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    36
    util,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27023
diff changeset
    37
)
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    38
6393
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    39
def up(p):
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    40
    if p[0] != "/":
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    41
        p = "/" + p
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    42
    if p[-1] == "/":
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    43
        p = p[:-1]
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    44
    up = os.path.dirname(p)
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    45
    if up == "/":
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    46
        return "/"
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    47
    return up + "/"
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    48
18391
833eb34e90e4 hgweb: better names for _navseq arguments
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18390
diff changeset
    49
def _navseq(step, firststep=None):
833eb34e90e4 hgweb: better names for _navseq arguments
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18390
diff changeset
    50
    if firststep:
833eb34e90e4 hgweb: better names for _navseq arguments
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18390
diff changeset
    51
        yield firststep
833eb34e90e4 hgweb: better names for _navseq arguments
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18390
diff changeset
    52
        if firststep >= 20 and firststep <= 40:
18392
88a37b19dc0e hgweb: ensure _navseq yield strictly increasing numbers
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18391
diff changeset
    53
            firststep = 50
88a37b19dc0e hgweb: ensure _navseq yield strictly increasing numbers
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18391
diff changeset
    54
            yield firststep
88a37b19dc0e hgweb: ensure _navseq yield strictly increasing numbers
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18391
diff changeset
    55
        assert step > 0
88a37b19dc0e hgweb: ensure _navseq yield strictly increasing numbers
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18391
diff changeset
    56
        assert firststep > 0
88a37b19dc0e hgweb: ensure _navseq yield strictly increasing numbers
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18391
diff changeset
    57
        while step <= firststep:
88a37b19dc0e hgweb: ensure _navseq yield strictly increasing numbers
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18391
diff changeset
    58
            step *= 10
18390
28fa9443f751 hgweb: drop recursivity in _navseq
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18389
diff changeset
    59
    while True:
18391
833eb34e90e4 hgweb: better names for _navseq arguments
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18390
diff changeset
    60
        yield 1 * step
833eb34e90e4 hgweb: better names for _navseq arguments
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18390
diff changeset
    61
        yield 3 * step
833eb34e90e4 hgweb: better names for _navseq arguments
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18390
diff changeset
    62
        step *= 10
18389
82572533bc00 hgweb: move the `seq` function out of the revnavgen scope
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18388
diff changeset
    63
18403
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    64
class revnav(object):
18320
60680d691a0b hgweb: document the revnavgen function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17991
diff changeset
    65
18409
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
    66
    def __init__(self, repo):
18404
1da84a6b136a hgweb: pass nodefunc to the revnav object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18403
diff changeset
    67
        """Navigation generation object
1da84a6b136a hgweb: pass nodefunc to the revnav object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18403
diff changeset
    68
18409
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
    69
        :repo: repo object we generate nav for
18404
1da84a6b136a hgweb: pass nodefunc to the revnav object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18403
diff changeset
    70
        """
18409
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
    71
        # used for hex generation
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
    72
        self._revlog = repo.changelog
18404
1da84a6b136a hgweb: pass nodefunc to the revnav object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18403
diff changeset
    73
18406
20cf53932b6f hgweb: simplify the handling of empty repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18405
diff changeset
    74
    def __nonzero__(self):
20cf53932b6f hgweb: simplify the handling of empty repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18405
diff changeset
    75
        """return True if any revision to navigate over"""
19094
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
    76
        return self._first() is not None
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
    77
31476
413b44003462 py3: add __bool__ to every class defining __nonzero__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31434
diff changeset
    78
    __bool__ = __nonzero__
413b44003462 py3: add __bool__ to every class defining __nonzero__
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31434
diff changeset
    79
19094
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
    80
    def _first(self):
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
    81
        """return the minimum non-filtered changeset or None"""
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
    82
        try:
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28709
diff changeset
    83
            return next(iter(self._revlog))
19094
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
    84
        except StopIteration:
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
    85
            return None
18406
20cf53932b6f hgweb: simplify the handling of empty repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18405
diff changeset
    86
18405
1eaf0d017b2c hgweb: move hex creation into an object method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18404
diff changeset
    87
    def hex(self, rev):
18409
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
    88
        return hex(self._revlog.node(rev))
18405
1eaf0d017b2c hgweb: move hex creation into an object method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18404
diff changeset
    89
18404
1da84a6b136a hgweb: pass nodefunc to the revnav object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18403
diff changeset
    90
    def gen(self, pos, pagelen, limit):
18403
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    91
        """computes label and revision id for navigation link
18320
60680d691a0b hgweb: document the revnavgen function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17991
diff changeset
    92
18403
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    93
        :pos: is the revision relative to which we generate navigation.
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    94
        :pagelen: the size of each navigation page
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    95
        :limit: how far shall we link
6393
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
    96
18403
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    97
        The return is:
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    98
            - a single element tuple
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
    99
            - containing a dictionary with a `before` and `after` key
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   100
            - values are generator functions taking arbitrary number of kwargs
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   101
            - yield items are dictionaries with `label` and `node` keys
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   102
        """
18406
20cf53932b6f hgweb: simplify the handling of empty repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18405
diff changeset
   103
        if not self:
20cf53932b6f hgweb: simplify the handling of empty repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18405
diff changeset
   104
            # empty repo
20cf53932b6f hgweb: simplify the handling of empty repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18405
diff changeset
   105
            return ({'before': (), 'after': ()},)
6393
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
   106
18425
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   107
        targets = []
18403
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   108
        for f in _navseq(1, pagelen):
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   109
            if f > limit:
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   110
                break
18425
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   111
            targets.append(pos + f)
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   112
            targets.append(pos - f)
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   113
        targets.sort()
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   114
19094
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
   115
        first = self._first()
fc1b77db123f hgweb: handle filtered "0" rev in navigation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 19093
diff changeset
   116
        navbefore = [("(%i)" % first, self.hex(first))]
18425
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   117
        navafter = []
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   118
        for rev in targets:
18426
01638b51df44 hgweb: ignore filtered revision in revnav
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18425
diff changeset
   119
            if rev not in self._revlog:
01638b51df44 hgweb: ignore filtered revision in revnav
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18425
diff changeset
   120
                continue
18425
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   121
            if pos < rev < limit:
18503
7f769d3a8ad2 hgweb: fix navigation label (issue3792)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18426
diff changeset
   122
                navafter.append(("+%d" % abs(rev - pos), self.hex(rev)))
18425
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   123
            if 0 < rev < pos:
18503
7f769d3a8ad2 hgweb: fix navigation label (issue3792)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18426
diff changeset
   124
                navbefore.append(("-%d" % abs(rev - pos), self.hex(rev)))
18425
6da1e979340a hgweb: generate revnav in two phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18409
diff changeset
   125
10254
8d5de52431f2 hgweb: changenav: separate pages before and after the current position
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9402
diff changeset
   126
18403
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   127
        navafter.append(("tip", "tip"))
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   128
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   129
        data = lambda i: {"label": i[0], "node": i[1]}
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   130
        return ({'before': lambda **map: (data(i) for i in navbefore),
bfaee31a83d2 hgweb: move revnavgen into an object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18392
diff changeset
   131
                 'after':  lambda **map: (data(i) for i in navafter)},)
6393
894875eae49b hgweb: refactor hgweb code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6392
diff changeset
   132
18408
f332a64fef51 hgweb: introduction a filerevnav subclass
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18407
diff changeset
   133
class filerevnav(revnav):
18409
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   134
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   135
    def __init__(self, repo, path):
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   136
        """Navigation generation object
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   137
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   138
        :repo: repo object we generate nav for
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   139
        :path: path of the file we generate nav for
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   140
        """
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   141
        # used for iteration
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   142
        self._changelog = repo.unfiltered().changelog
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   143
        # used for hex generation
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   144
        self._revlog = repo.file(path)
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   145
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   146
    def hex(self, rev):
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   147
        return hex(self._changelog.node(self._revlog.linkrev(rev)))
e3f5cef11d6a hgweb: pass repo object to revnav construction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18408
diff changeset
   148
27023
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   149
class _siblings(object):
31391
d2878bec55bd hgweb: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31276
diff changeset
   150
    def __init__(self, siblings=None, hiderev=None):
31434
d4645ae6ba15 hgweb: explicitly tests for None in webutil
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31391
diff changeset
   151
        if siblings is None:
d4645ae6ba15 hgweb: explicitly tests for None in webutil
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31391
diff changeset
   152
            siblings = []
d4645ae6ba15 hgweb: explicitly tests for None in webutil
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31391
diff changeset
   153
        self.siblings = [s for s in siblings if s.node() != nullid]
27023
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   154
        if len(self.siblings) == 1 and self.siblings[0].rev() == hiderev:
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   155
            self.siblings = []
18408
f332a64fef51 hgweb: introduction a filerevnav subclass
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18407
diff changeset
   156
27023
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   157
    def __iter__(self):
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   158
        for s in self.siblings:
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   159
            d = {
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   160
                'node': s.hex(),
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   161
                'rev': s.rev(),
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   162
                'user': s.user(),
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   163
                'date': s.date(),
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   164
                'description': s.description(),
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   165
                'branch': s.branch(),
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   166
            }
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   167
            if util.safehasattr(s, 'path'):
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   168
                d['file'] = s.path()
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   169
            yield d
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   170
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   171
    def __len__(self):
0c8ef79b9fd7 webutil: make _siblings into an object with __iter__ and __len__
Anton Shestakov <av6@dwimlabs.net>
parents: 27008
diff changeset
   172
        return len(self.siblings)
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   173
34390
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   174
def difffeatureopts(req, ui, section):
30081
dd0ff715a82c hgweb: make fctx.annotate a separated function so it could be wrapped
Jun Wu <quark@fb.com>
parents: 29216
diff changeset
   175
    diffopts = patch.difffeatureopts(ui, untrusted=True,
34390
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   176
                                     section=section, whitespace=True)
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   177
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   178
    for k in ('ignorews', 'ignorewsamount', 'ignorewseol', 'ignoreblanklines'):
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   179
        v = req.form.get(k, [None])[0]
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   180
        if v is not None:
34403
407ebe7a9b93 hgweb: use parsebool for parsing diff query string options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34390
diff changeset
   181
            v = util.parsebool(v)
407ebe7a9b93 hgweb: use parsebool for parsing diff query string options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34390
diff changeset
   182
            setattr(diffopts, k, v if v is not None else True)
34390
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   183
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   184
    return diffopts
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   185
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   186
def annotate(req, fctx, ui):
f6492f482c60 hgweb: query string arguments to control whitespace for annotate
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34246
diff changeset
   187
    diffopts = difffeatureopts(req, ui, 'annotate')
30081
dd0ff715a82c hgweb: make fctx.annotate a separated function so it could be wrapped
Jun Wu <quark@fb.com>
parents: 29216
diff changeset
   188
    return fctx.annotate(follow=True, linenumber=True, diffopts=diffopts)
dd0ff715a82c hgweb: make fctx.annotate a separated function so it could be wrapped
Jun Wu <quark@fb.com>
parents: 29216
diff changeset
   189
7671
06cf09c822c4 hgweb: simplify parents/children generation code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   190
def parents(ctx, hide=None):
24136
46d6cdfce4bf hgweb: use introrev() for finding parents (issue4506)
Anton Shestakov <engored@ya.ru>
parents: 23745
diff changeset
   191
    if isinstance(ctx, context.basefilectx):
46d6cdfce4bf hgweb: use introrev() for finding parents (issue4506)
Anton Shestakov <engored@ya.ru>
parents: 23745
diff changeset
   192
        introrev = ctx.introrev()
46d6cdfce4bf hgweb: use introrev() for finding parents (issue4506)
Anton Shestakov <engored@ya.ru>
parents: 23745
diff changeset
   193
        if ctx.changectx().rev() != introrev:
24340
567ae5365754 hgweb: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24306
diff changeset
   194
            return _siblings([ctx.repo()[introrev]], hide)
7671
06cf09c822c4 hgweb: simplify parents/children generation code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   195
    return _siblings(ctx.parents(), hide)
06cf09c822c4 hgweb: simplify parents/children generation code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   196
06cf09c822c4 hgweb: simplify parents/children generation code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   197
def children(ctx, hide=None):
06cf09c822c4 hgweb: simplify parents/children generation code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   198
    return _siblings(ctx.children(), hide)
06cf09c822c4 hgweb: simplify parents/children generation code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   199
6434
62e0bb41e682 hgweb: minor improvements for new web style
Matt Mackall <mpm@selenic.com>
parents: 6413
diff changeset
   200
def renamelink(fctx):
6437
101526031d06 hgweb: fix merge breakage
Matt Mackall <mpm@selenic.com>
parents: 6434
diff changeset
   201
    r = fctx.renamed()
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   202
    if r:
20681
52e5aca15f0c webutil: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 20033
diff changeset
   203
        return [{'file': r[0], 'node': hex(r[1])}]
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   204
    return []
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   205
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   206
def nodetagsdict(repo, node):
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   207
    return [{"name": i} for i in repo.nodetags(node)]
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   208
13596
270f57d35525 hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov <alexander@solovyov.net>
parents: 12691
diff changeset
   209
def nodebookmarksdict(repo, node):
270f57d35525 hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov <alexander@solovyov.net>
parents: 12691
diff changeset
   210
    return [{"name": i} for i in repo.nodebookmarks(node)]
270f57d35525 hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov <alexander@solovyov.net>
parents: 12691
diff changeset
   211
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   212
def nodebranchdict(repo, ctx):
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   213
    branches = []
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   214
    branch = ctx.branch()
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   215
    # If this is an empty repo, ctx.node() == nullid,
16719
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   216
    # ctx.branch() == 'default'.
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   217
    try:
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   218
        branchnode = repo.branchtip(branch)
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   219
    except error.RepoLookupError:
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   220
        branchnode = None
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   221
    if branchnode == ctx.node():
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   222
        branches.append({"name": branch})
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   223
    return branches
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   224
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   225
def nodeinbranch(repo, ctx):
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   226
    branches = []
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   227
    branch = ctx.branch()
16719
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   228
    try:
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   229
        branchnode = repo.branchtip(branch)
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   230
    except error.RepoLookupError:
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   231
        branchnode = None
e7bf09acd410 localrepo: add branchtip() method for faster single-branch lookups
Brodie Rao <brodie@sf.io>
parents: 16308
diff changeset
   232
    if branch != 'default' and branchnode != ctx.node():
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   233
        branches.append({"name": branch})
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   234
    return branches
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   235
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   236
def nodebranchnodefault(ctx):
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   237
    branches = []
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   238
    branch = ctx.branch()
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   239
    if branch != 'default':
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   240
        branches.append({"name": branch})
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   241
    return branches
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   242
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   243
def showtag(repo, tmpl, t1, node=nullid, **args):
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   244
    for t in repo.nodetags(node):
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   245
        yield tmpl(t1, tag=t, **args)
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   246
13596
270f57d35525 hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov <alexander@solovyov.net>
parents: 12691
diff changeset
   247
def showbookmark(repo, tmpl, t1, node=nullid, **args):
270f57d35525 hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov <alexander@solovyov.net>
parents: 12691
diff changeset
   248
    for t in repo.nodebookmarks(node):
270f57d35525 hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov <alexander@solovyov.net>
parents: 12691
diff changeset
   249
        yield tmpl(t1, bookmark=t, **args)
270f57d35525 hgweb: add display of bookmarks for changelog and changeset
Alexander Solovyov <alexander@solovyov.net>
parents: 12691
diff changeset
   250
26129
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   251
def branchentries(repo, stripecount, limit=0):
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   252
    tips = []
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   253
    heads = repo.heads()
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   254
    parity = paritygen(stripecount)
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   255
    sortkey = lambda item: (not item[1], item[0].rev())
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   256
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   257
    def entries(**map):
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   258
        count = 0
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   259
        if not tips:
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   260
            for tag, hs, tip, closed in repo.branchmap().iterbranches():
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   261
                tips.append((repo[tip], closed))
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   262
        for ctx, closed in sorted(tips, key=sortkey, reverse=True):
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   263
            if limit > 0 and count >= limit:
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   264
                return
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   265
            count += 1
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   266
            if closed:
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   267
                status = 'closed'
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   268
            elif ctx.node() not in heads:
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   269
                status = 'inactive'
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   270
            else:
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   271
                status = 'open'
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   272
            yield {
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28709
diff changeset
   273
                'parity': next(parity),
26129
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   274
                'branch': ctx.branch(),
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   275
                'status': status,
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   276
                'node': ctx.hex(),
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   277
                'date': ctx.date()
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   278
            }
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   279
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   280
    return entries
a103ecb8a04a hgweb: move branchentries code from webcommands to webutil
Anton Shestakov <av6@dwimlabs.net>
parents: 25999
diff changeset
   281
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   282
def cleanpath(repo, path):
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   283
    path = path.lstrip('/')
20033
f962870712da pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents: 19094
diff changeset
   284
    return pathutil.canonpath(repo.root, '', path)
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   285
25999
1c75249e159b style: adjust whitespaces in webutil.py
Anton Shestakov <av6@dwimlabs.net>
parents: 25778
diff changeset
   286
def changeidctx(repo, changeid):
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   287
    try:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6437
diff changeset
   288
        ctx = repo[changeid]
7637
1d54e2f6c0b7 error: move repo errors
Matt Mackall <mpm@selenic.com>
parents: 7361
diff changeset
   289
    except error.RepoError:
30375
11b8b740d54a manifest: remove last uses of repo.manifest
Durham Goode <durham@fb.com>
parents: 30081
diff changeset
   290
        man = repo.manifestlog._revlog
7361
9fe97eea5510 linkrev: take a revision number rather than a hash
Matt Mackall <mpm@selenic.com>
parents: 7345
diff changeset
   291
        ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))]
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   292
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   293
    return ctx
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   294
25999
1c75249e159b style: adjust whitespaces in webutil.py
Anton Shestakov <av6@dwimlabs.net>
parents: 25778
diff changeset
   295
def changectx(repo, req):
17991
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   296
    changeid = "tip"
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   297
    if 'node' in req.form:
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   298
        changeid = req.form['node'][0]
25999
1c75249e159b style: adjust whitespaces in webutil.py
Anton Shestakov <av6@dwimlabs.net>
parents: 25778
diff changeset
   299
        ipos = changeid.find(':')
17991
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   300
        if ipos != -1:
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   301
            changeid = changeid[(ipos + 1):]
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   302
    elif 'manifest' in req.form:
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   303
        changeid = req.form['manifest'][0]
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   304
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   305
    return changeidctx(repo, changeid)
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   306
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   307
def basechangectx(repo, req):
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   308
    if 'node' in req.form:
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   309
        changeid = req.form['node'][0]
25999
1c75249e159b style: adjust whitespaces in webutil.py
Anton Shestakov <av6@dwimlabs.net>
parents: 25778
diff changeset
   310
        ipos = changeid.find(':')
17991
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   311
        if ipos != -1:
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   312
            changeid = changeid[:ipos]
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   313
            return changeidctx(repo, changeid)
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   314
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   315
    return None
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   316
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   317
def filectx(repo, req):
17289
f2d6b4f8e78c hgweb: avoid traceback when file or node parameters are missing
Ross Lagerwall <rosslagerwall@gmail.com>
parents: 17202
diff changeset
   318
    if 'file' not in req.form:
f2d6b4f8e78c hgweb: avoid traceback when file or node parameters are missing
Ross Lagerwall <rosslagerwall@gmail.com>
parents: 17202
diff changeset
   319
        raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   320
    path = cleanpath(repo, req.form['file'][0])
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   321
    if 'node' in req.form:
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   322
        changeid = req.form['node'][0]
17289
f2d6b4f8e78c hgweb: avoid traceback when file or node parameters are missing
Ross Lagerwall <rosslagerwall@gmail.com>
parents: 17202
diff changeset
   323
    elif 'filenode' in req.form:
f2d6b4f8e78c hgweb: avoid traceback when file or node parameters are missing
Ross Lagerwall <rosslagerwall@gmail.com>
parents: 17202
diff changeset
   324
        changeid = req.form['filenode'][0]
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   325
    else:
17289
f2d6b4f8e78c hgweb: avoid traceback when file or node parameters are missing
Ross Lagerwall <rosslagerwall@gmail.com>
parents: 17202
diff changeset
   326
        raise ErrorResponse(HTTP_NOT_FOUND, 'node or filenode not given')
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   327
    try:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6437
diff changeset
   328
        fctx = repo[changeid][path]
7637
1d54e2f6c0b7 error: move repo errors
Matt Mackall <mpm@selenic.com>
parents: 7361
diff changeset
   329
    except error.RepoError:
6392
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   330
        fctx = repo.filectx(path, fileid=changeid)
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   331
2540521dc7c1 hgweb: separate out utility functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   332
    return fctx
7310
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   333
31665
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   334
def linerange(req):
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   335
    linerange = req.form.get('linerange')
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   336
    if linerange is None:
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   337
        return None
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   338
    if len(linerange) > 1:
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   339
        raise ErrorResponse(HTTP_BAD_REQUEST,
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   340
                            'redundant linerange parameter')
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   341
    try:
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   342
        fromline, toline = map(int, linerange[0].split(':', 1))
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   343
    except ValueError:
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   344
        raise ErrorResponse(HTTP_BAD_REQUEST,
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   345
                            'invalid linerange parameter')
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   346
    try:
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   347
        return util.processlinerange(fromline, toline)
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   348
    except error.ParseError as exc:
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   349
        raise ErrorResponse(HTTP_BAD_REQUEST, str(exc))
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   350
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   351
def formatlinerange(fromline, toline):
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   352
    return '%d:%d' % (fromline + 1, toline)
5e6d44511317 hgweb: handle a "linerange" request parameter in filelog command
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31660
diff changeset
   353
27294
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   354
def commonentry(repo, ctx):
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   355
    node = ctx.node()
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   356
    return {
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   357
        'rev': ctx.rev(),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   358
        'node': hex(node),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   359
        'author': ctx.user(),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   360
        'desc': ctx.description(),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   361
        'date': ctx.date(),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   362
        'extra': ctx.extra(),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   363
        'phase': ctx.phasestr(),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   364
        'branch': nodebranchnodefault(ctx),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   365
        'inbranch': nodeinbranch(repo, ctx),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   366
        'branches': nodebranchdict(repo, ctx),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   367
        'tags': nodetagsdict(repo, node),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   368
        'bookmarks': nodebookmarksdict(repo, node),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   369
        'parent': lambda **x: parents(ctx),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   370
        'child': lambda **x: children(ctx),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   371
    }
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   372
23745
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   373
def changelistentry(web, ctx, tmpl):
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   374
    '''Obtain a dictionary to be used for entries in a changelist.
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   375
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   376
    This function is called when producing items for the "entries" list passed
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   377
    to the "shortlog" and "changelog" templates.
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   378
    '''
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   379
    repo = web.repo
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   380
    rev = ctx.rev()
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   381
    n = ctx.node()
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   382
    showtags = showtag(repo, tmpl, 'changelogtag', n)
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   383
    files = listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   384
27294
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   385
    entry = commonentry(repo, ctx)
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   386
    entry.update(
28709
94494031f659 hgweb: add parents to json-log (issue5074)
Anton Shestakov <av6@dwimlabs.net>
parents: 27294
diff changeset
   387
        allparents=lambda **x: parents(ctx),
27294
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   388
        parent=lambda **x: parents(ctx, rev - 1),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   389
        child=lambda **x: children(ctx, rev + 1),
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   390
        changelogtag=showtags,
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   391
        files=files,
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   392
    )
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   393
    return entry
23745
513d47905114 hgweb: extract changelist entry generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21122
diff changeset
   394
25602
85fb416f2fa7 hgweb: provide symrev (symbolic revision) property to the templates
Anton Shestakov <av6@dwimlabs.net>
parents: 25278
diff changeset
   395
def symrevorshortnode(req, ctx):
85fb416f2fa7 hgweb: provide symrev (symbolic revision) property to the templates
Anton Shestakov <av6@dwimlabs.net>
parents: 25278
diff changeset
   396
    if 'node' in req.form:
27008
7f19f331ef59 hgweb: do not import templatefilters.revescape and websub as symbol
Yuya Nishihara <yuya@tcha.org>
parents: 27007
diff changeset
   397
        return templatefilters.revescape(req.form['node'][0])
25602
85fb416f2fa7 hgweb: provide symrev (symbolic revision) property to the templates
Anton Shestakov <av6@dwimlabs.net>
parents: 25278
diff changeset
   398
    else:
85fb416f2fa7 hgweb: provide symrev (symbolic revision) property to the templates
Anton Shestakov <av6@dwimlabs.net>
parents: 25278
diff changeset
   399
        return short(ctx.node())
85fb416f2fa7 hgweb: provide symrev (symbolic revision) property to the templates
Anton Shestakov <av6@dwimlabs.net>
parents: 25278
diff changeset
   400
24177
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   401
def changesetentry(web, req, tmpl, ctx):
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   402
    '''Obtain a dictionary to be used to render the "changeset" template.'''
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   403
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   404
    showtags = showtag(web.repo, tmpl, 'changesettag', ctx.node())
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   405
    showbookmarks = showbookmark(web.repo, tmpl, 'changesetbookmark',
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   406
                                 ctx.node())
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   407
    showbranch = nodebranchnodefault(ctx)
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   408
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   409
    files = []
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   410
    parity = paritygen(web.stripecount)
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   411
    for blockno, f in enumerate(ctx.files()):
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   412
        template = f in ctx and 'filenodelink' or 'filenolink'
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   413
        files.append(tmpl(template,
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   414
                          node=ctx.hex(), file=f, blockno=blockno + 1,
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28709
diff changeset
   415
                          parity=next(parity)))
24177
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   416
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   417
    basectx = basechangectx(web.repo, req)
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   418
    if basectx is None:
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   419
        basectx = ctx.p1()
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   420
34246
db63872e10cc configitems: register the 'web.style' config
Boris Feld <boris.feld@octobus.net>
parents: 31808
diff changeset
   421
    style = web.config('web', 'style')
24177
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   422
    if 'style' in req.form:
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   423
        style = req.form['style'][0]
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   424
31660
c2dbd818e884 hgweb: handle "parity" internally in webutil.diffs()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31476
diff changeset
   425
    diff = diffs(web, tmpl, ctx, basectx, None, style)
24177
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   426
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   427
    parity = paritygen(web.stripecount)
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   428
    diffstatsgen = diffstatgen(ctx, basectx)
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   429
    diffstats = diffstat(tmpl, ctx, diffstatsgen, parity)
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   430
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   431
    return dict(
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   432
        diff=diff,
25602
85fb416f2fa7 hgweb: provide symrev (symbolic revision) property to the templates
Anton Shestakov <av6@dwimlabs.net>
parents: 25278
diff changeset
   433
        symrev=symrevorshortnode(req, ctx),
24177
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   434
        basenode=basectx.hex(),
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   435
        changesettag=showtags,
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   436
        changesetbookmark=showbookmarks,
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   437
        changesetbranch=showbranch,
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   438
        files=files,
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   439
        diffsummary=lambda **x: diffsummary(diffstatsgen),
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   440
        diffstat=diffstats,
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   441
        archives=web.archivelist(ctx.hex()),
27294
5aa2afb4f81a hgweb: move entry-preparing code from webcommands to webutils.commonentry()
Anton Shestakov <av6@dwimlabs.net>
parents: 27046
diff changeset
   442
        **commonentry(web.repo, ctx))
24177
f53b7174facf hgweb: extract changeset template mapping generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24136
diff changeset
   443
7311
de9c87fe1620 hgweb: move another utility function into the webutil module
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7310
diff changeset
   444
def listfilediffs(tmpl, files, node, max):
de9c87fe1620 hgweb: move another utility function into the webutil module
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7310
diff changeset
   445
    for f in files[:max]:
de9c87fe1620 hgweb: move another utility function into the webutil module
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7310
diff changeset
   446
        yield tmpl('filedifflink', node=hex(node), file=f)
de9c87fe1620 hgweb: move another utility function into the webutil module
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7310
diff changeset
   447
    if len(files) > max:
de9c87fe1620 hgweb: move another utility function into the webutil module
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7310
diff changeset
   448
        yield tmpl('fileellipses')
de9c87fe1620 hgweb: move another utility function into the webutil module
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7310
diff changeset
   449
31727
6be6e4becaaf hgweb: prefix line id by ctx shortnode in filelog when patches are shown
Denis Laxalde <denis@laxalde.org>
parents: 31704
diff changeset
   450
def diffs(web, tmpl, ctx, basectx, files, style, linerange=None,
6be6e4becaaf hgweb: prefix line id by ctx shortnode in filelog when patches are shown
Denis Laxalde <denis@laxalde.org>
parents: 31704
diff changeset
   451
          lineidprefix=''):
7310
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   452
31276
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   453
    def prettyprintlines(lines, blockno):
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   454
        for lineno, l in enumerate(lines, 1):
31275
e2f141045634 hgweb: start enumerate at 1 in webutil.diffs's inner function prettyprintlines
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31082
diff changeset
   455
            difflineno = "%d.%d" % (blockno, lineno)
7310
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   456
            if l.startswith('+'):
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   457
                ltype = "difflineplus"
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   458
            elif l.startswith('-'):
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   459
                ltype = "difflineminus"
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   460
            elif l.startswith('@'):
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   461
                ltype = "difflineat"
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   462
            else:
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   463
                ltype = "diffline"
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   464
            yield tmpl(ltype,
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   465
                       line=l,
31275
e2f141045634 hgweb: start enumerate at 1 in webutil.diffs's inner function prettyprintlines
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31082
diff changeset
   466
                       lineno=lineno,
31727
6be6e4becaaf hgweb: prefix line id by ctx shortnode in filelog when patches are shown
Denis Laxalde <denis@laxalde.org>
parents: 31704
diff changeset
   467
                       lineid=lineidprefix + "l%s" % difflineno,
24712
bbf1ae6b6a44 hgweb: expose raw line numbers to templates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24564
diff changeset
   468
                       linenumber="% 8s" % difflineno)
7310
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   469
31660
c2dbd818e884 hgweb: handle "parity" internally in webutil.diffs()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31476
diff changeset
   470
    repo = web.repo
7310
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   471
    if files:
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   472
        m = match.exact(repo.root, repo.getcwd(), files)
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   473
    else:
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   474
        m = match.always(repo.root, repo.getcwd())
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   475
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   476
    diffopts = patch.diffopts(repo.ui, untrusted=True)
31082
abb92b3d370e hgweb: explictly pass basectx in webutil.diffs
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 30375
diff changeset
   477
    node1 = basectx.node()
7310
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   478
    node2 = ctx.node()
31660
c2dbd818e884 hgweb: handle "parity" internally in webutil.diffs()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31476
diff changeset
   479
    parity = paritygen(web.stripecount)
7310
bd522d09d5e3 hgweb: move the diffs() generator into webutil
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7294
diff changeset
   480
31276
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   481
    diffhunks = patch.diffhunks(repo, node1, node2, m, opts=diffopts)
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   482
    for blockno, (header, hunks) in enumerate(diffhunks, 1):
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   483
        if style != 'raw':
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   484
            header = header[1:]
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   485
        lines = [h + '\n' for h in header]
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   486
        for hunkrange, hunklines in hunks:
31666
aaebc80c9f1d hgweb: add a 'linerange' parameter to webutil.diffs()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31665
diff changeset
   487
            if linerange is not None and hunkrange is not None:
aaebc80c9f1d hgweb: add a 'linerange' parameter to webutil.diffs()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31665
diff changeset
   488
                s1, l1, s2, l2 = hunkrange
31808
ca3b4a2b7e54 mdiff: add a hunkinrange helper function
Denis Laxalde <denis@laxalde.org>
parents: 31727
diff changeset
   489
                if not mdiff.hunkinrange((s2, l2), linerange):
31666
aaebc80c9f1d hgweb: add a 'linerange' parameter to webutil.diffs()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31665
diff changeset
   490
                    continue
31276
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   491
            lines.extend(hunklines)
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   492
        if lines:
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28709
diff changeset
   493
            yield tmpl('diffblock', parity=next(parity), blockno=blockno,
31276
cd29673cebdb hgweb: use patch.diffhunks in webutil.diffs to simplify the algorithm
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 31275
diff changeset
   494
                       lines=prettyprintlines(lines, blockno))
7345
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   495
17302
5c64ce6168da hgweb: fixes traceback for invalid files by removing top-level template
wujek srujek <wujek.srujek@googlemail.com>
parents: 17289
diff changeset
   496
def compare(tmpl, context, leftlines, rightlines):
17202
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   497
    '''Generator function that provides side-by-side comparison data.'''
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   498
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   499
    def compline(type, leftlineno, leftline, rightlineno, rightline):
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   500
        lineid = leftlineno and ("l%s" % leftlineno) or ''
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   501
        lineid += rightlineno and ("r%s" % rightlineno) or ''
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   502
        return tmpl('comparisonline',
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   503
                    type=type,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   504
                    lineid=lineid,
24712
bbf1ae6b6a44 hgweb: expose raw line numbers to templates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24564
diff changeset
   505
                    leftlineno=leftlineno,
17202
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   506
                    leftlinenumber="% 6s" % (leftlineno or ''),
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   507
                    leftline=leftline or '',
24712
bbf1ae6b6a44 hgweb: expose raw line numbers to templates
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24564
diff changeset
   508
                    rightlineno=rightlineno,
17202
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   509
                    rightlinenumber="% 6s" % (rightlineno or ''),
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   510
                    rightline=rightline or '')
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   511
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   512
    def getblock(opcodes):
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   513
        for type, llo, lhi, rlo, rhi in opcodes:
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   514
            len1 = lhi - llo
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   515
            len2 = rhi - rlo
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   516
            count = min(len1, len2)
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   517
            for i in xrange(count):
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   518
                yield compline(type=type,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   519
                               leftlineno=llo + i + 1,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   520
                               leftline=leftlines[llo + i],
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   521
                               rightlineno=rlo + i + 1,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   522
                               rightline=rightlines[rlo + i])
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   523
            if len1 > len2:
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   524
                for i in xrange(llo + count, lhi):
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   525
                    yield compline(type=type,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   526
                                   leftlineno=i + 1,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   527
                                   leftline=leftlines[i],
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   528
                                   rightlineno=None,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   529
                                   rightline=None)
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   530
            elif len2 > len1:
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   531
                for i in xrange(rlo + count, rhi):
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   532
                    yield compline(type=type,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   533
                                   leftlineno=None,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   534
                                   leftline=None,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   535
                                   rightlineno=i + 1,
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   536
                                   rightline=rightlines[i])
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   537
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   538
    s = difflib.SequenceMatcher(None, leftlines, rightlines)
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   539
    if context < 0:
17302
5c64ce6168da hgweb: fixes traceback for invalid files by removing top-level template
wujek srujek <wujek.srujek@googlemail.com>
parents: 17289
diff changeset
   540
        yield tmpl('comparisonblock', lines=getblock(s.get_opcodes()))
17202
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   541
    else:
17302
5c64ce6168da hgweb: fixes traceback for invalid files by removing top-level template
wujek srujek <wujek.srujek@googlemail.com>
parents: 17289
diff changeset
   542
        for oc in s.get_grouped_opcodes(n=context):
5c64ce6168da hgweb: fixes traceback for invalid files by removing top-level template
wujek srujek <wujek.srujek@googlemail.com>
parents: 17289
diff changeset
   543
            yield tmpl('comparisonblock', lines=getblock(oc))
17202
1ae119269ddc hgweb: side-by-side comparison functionality
wujek srujek
parents: 16719
diff changeset
   544
17991
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   545
def diffstatgen(ctx, basectx):
14570
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   546
    '''Generator function that provides the diffstat data.'''
14490
1d3e2349304a web: provide diffstat to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14055
diff changeset
   547
17991
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17302
diff changeset
   548
    stats = patch.diffstatdata(util.iterlines(ctx.diff(basectx)))
14490
1d3e2349304a web: provide diffstat to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14055
diff changeset
   549
    maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
14570
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   550
    while True:
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   551
        yield stats, maxname, maxtotal, addtotal, removetotal, binary
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   552
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   553
def diffsummary(statgen):
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   554
    '''Return a short summary of the diff.'''
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   555
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28709
diff changeset
   556
    stats, maxname, maxtotal, addtotal, removetotal, binary = next(statgen)
14570
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   557
    return _(' %d files changed, %d insertions(+), %d deletions(-)\n') % (
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   558
             len(stats), addtotal, removetotal)
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   559
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   560
def diffstat(tmpl, ctx, statgen, parity):
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   561
    '''Return a diffstat template for each file in the diff.'''
9f908ef5a595 web: provide diff summary to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14562
diff changeset
   562
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28709
diff changeset
   563
    stats, maxname, maxtotal, addtotal, removetotal, binary = next(statgen)
14561
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   564
    files = ctx.files()
14490
1d3e2349304a web: provide diffstat to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14055
diff changeset
   565
14561
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   566
    def pct(i):
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   567
        if maxtotal == 0:
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   568
            return 0
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   569
        return (float(i) / maxtotal) * 100
14490
1d3e2349304a web: provide diffstat to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14055
diff changeset
   570
14562
fccd3b966da7 web: provide the file number to the diffstat templates
Steven Brown <StevenGBrown@gmail.com>
parents: 14561
diff changeset
   571
    fileno = 0
14561
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   572
    for filename, adds, removes, isbinary in stats:
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   573
        template = filename in files and 'diffstatlink' or 'diffstatnolink'
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   574
        total = adds + removes
14562
fccd3b966da7 web: provide the file number to the diffstat templates
Steven Brown <StevenGBrown@gmail.com>
parents: 14561
diff changeset
   575
        fileno += 1
fccd3b966da7 web: provide the file number to the diffstat templates
Steven Brown <StevenGBrown@gmail.com>
parents: 14561
diff changeset
   576
        yield tmpl(template, node=ctx.hex(), file=filename, fileno=fileno,
14561
925d9f2b188b web: include all files in the diffstat
Steven Brown <StevenGBrown@gmail.com>
parents: 14490
diff changeset
   577
                   total=total, addpct=pct(adds), removepct=pct(removes),
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 28709
diff changeset
   578
                   parity=next(parity))
14490
1d3e2349304a web: provide diffstat to the changeset page
Steven Brown <StevenGBrown@gmail.com>
parents: 14055
diff changeset
   579
7345
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   580
class sessionvars(object):
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   581
    def __init__(self, vars, start='?'):
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   582
        self.start = start
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   583
        self.vars = vars
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   584
    def __getitem__(self, key):
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   585
        return self.vars[key]
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   586
    def __setitem__(self, key, value):
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   587
        self.vars[key] = value
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   588
    def __copy__(self):
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   589
        return sessionvars(copy.copy(self.vars), self.start)
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   590
    def __iter__(self):
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   591
        separator = self.start
18367
ae7215f4f7b9 hgweb: generate query strings with parameters sorted by key
Mads Kiilerich <mads@kiilerich.com>
parents: 18320
diff changeset
   592
        for key, value in sorted(self.vars.iteritems()):
34807
3caec3c032c8 webutil: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 34403
diff changeset
   593
            yield {'name': key,
3caec3c032c8 webutil: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 34403
diff changeset
   594
                   'value': pycompat.bytestr(value),
3caec3c032c8 webutil: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 34403
diff changeset
   595
                   'separator': separator,
3caec3c032c8 webutil: use pycompat.bytestr() instead of str()
Augie Fackler <augie@google.com>
parents: 34403
diff changeset
   596
            }
7345
55651328dfcc hgweb: fix up the less/more links on the graph page
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7311
diff changeset
   597
            separator = '&'
12691
1b1a9038a71a hgweb: fix hgweb_mod as well as hgwebdir_mod
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   598
27007
c8cbef073645 hgweb: alias ui module as uimod
Yuya Nishihara <yuya@tcha.org>
parents: 26894
diff changeset
   599
class wsgiui(uimod.ui):
12691
1b1a9038a71a hgweb: fix hgweb_mod as well as hgwebdir_mod
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   600
    # default termwidth breaks under mod_wsgi
1b1a9038a71a hgweb: fix hgweb_mod as well as hgwebdir_mod
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   601
    def termwidth(self):
1b1a9038a71a hgweb: fix hgweb_mod as well as hgwebdir_mod
Augie Fackler <durin42@gmail.com>
parents: 10282
diff changeset
   602
        return 80
26162
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   603
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   604
def getwebsubs(repo):
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   605
    websubtable = []
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   606
    websubdefs = repo.ui.configitems('websub')
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   607
    # we must maintain interhg backwards compatibility
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   608
    websubdefs += repo.ui.configitems('interhg')
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   609
    for key, pattern in websubdefs:
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   610
        # grab the delimiter from the character after the "s"
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   611
        unesc = pattern[1]
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   612
        delim = re.escape(unesc)
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   613
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   614
        # identify portions of the pattern, taking care to avoid escaped
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   615
        # delimiters. the replace format and flags are optional, but
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   616
        # delimiters are required.
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   617
        match = re.match(
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   618
            r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   619
            % (delim, delim, delim), pattern)
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   620
        if not match:
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   621
            repo.ui.warn(_("websub: invalid pattern for %s: %s\n")
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   622
                              % (key, pattern))
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   623
            continue
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   624
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   625
        # we need to unescape the delimiter for regexp and format
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   626
        delim_re = re.compile(r'(?<!\\)\\%s' % delim)
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   627
        regexp = delim_re.sub(unesc, match.group(1))
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   628
        format = delim_re.sub(unesc, match.group(2))
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   629
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   630
        # the pattern allows for 6 regexp flags, so set them if necessary
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   631
        flagin = match.group(3)
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   632
        flags = 0
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   633
        if flagin:
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   634
            for flag in flagin.upper():
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   635
                flags |= re.__dict__[flag]
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   636
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   637
        try:
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   638
            regexp = re.compile(regexp, flags)
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   639
            websubtable.append((regexp, format))
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   640
        except re.error:
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   641
            repo.ui.warn(_("websub: invalid regexp for %s: %s\n")
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   642
                         % (key, regexp))
268b39770c28 hgweb: extract web substitutions table generation to own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26129
diff changeset
   643
    return websubtable