mercurial/hgweb/hgwebdir_mod.py
author Brendan Cully <brendan@kublai.com>
Fri, 21 Nov 2008 15:51:40 -0800
changeset 7396 526c40a74bd0
parent 7337 feb0b76b6717
child 7450 79d1bb737c16
permissions -rw-r--r--
templater: return data in increasing chunk sizes Currently hgweb is not streaming its output -- it accumulates the entire response before sending it. This patch restores streaming behaviour. To avoid having to synchronously write many tiny fragments, this patch also adds buffering to the template generator. Local testing of a fetch of a 100,000 line file with wget produces a slight slowdown overall (up from 6.5 seconds to 7.2 seconds), but instead of waiting 6 seconds for headers to arrive, output begins immediately.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2391
d351a3be3371 Fixing up comment headers for split up code.
Eric Hopper <hopper@omnifarious.org>
parents: 2360
diff changeset
     1
# hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     2
#
238
3b92f8fe47ae hgweb.py: kill #! line, clean up copyright notice
mpm@selenic.com
parents: 222
diff changeset
     3
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2538
diff changeset
     4
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     5
#
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     6
# This software may be used and distributed according to the terms
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     7
# of the GNU General Public License, incorporated herein by reference.
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     8
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
     9
import os
7225
59b4ae211584 i18n: import _ instead of gettext
Martin Geisler <mg@daimi.au.dk>
parents: 7107
diff changeset
    10
from mercurial.i18n import _
6217
fe8dbbe9520d Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
Joel Rosdahl <joel@rosdahl.net>
parents: 6210
diff changeset
    11
from mercurial.repo import RepoError
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents: 5970
diff changeset
    12
from mercurial import ui, hg, util, templater, templatefilters
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents: 5970
diff changeset
    13
from common import ErrorResponse, get_mtime, staticfile, style_map, paritygen,\
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
    14
                   get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3557
diff changeset
    15
from hgweb_mod import hgweb
5566
d74fc8dec2b4 Less indirection in the WSGI web interface. This simplifies some code, and makes it more compliant with WSGI.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5561
diff changeset
    16
from request import wsgirequest
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    17
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    18
# This is a stopgap
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
    19
class hgwebdir(object):
4079
40c9710e8182 Pass a ui from create_server to hgwebdir and a repo from hgwebdir to hgweb
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3882
diff changeset
    20
    def __init__(self, config, parentui=None):
1181
4f5001f5b4c3 Make sure the repository names don't have slashes at the at or else in some
Vincent Wagelaar <vincent@ricardis.tudelft.nl>
parents: 1180
diff changeset
    21
        def cleannames(items):
6908
b77c25c2d6c0 Do not sort hgwebdir repositories if python list or tuple is given.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6797
diff changeset
    22
            return [(util.pconvert(name).strip('/'), path)
b77c25c2d6c0 Do not sort hgwebdir repositories if python list or tuple is given.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6797
diff changeset
    23
                    for name, path in items]
1181
4f5001f5b4c3 Make sure the repository names don't have slashes at the at or else in some
Vincent Wagelaar <vincent@ricardis.tudelft.nl>
parents: 1180
diff changeset
    24
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
    25
        self.parentui = parentui or ui.ui(report_untrusted=False,
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
    26
                                          interactive = False)
4080
ef14fdb675da hgwebdir: try to get web.style and web.motd from the ui.config system
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4079
diff changeset
    27
        self.motd = None
7337
feb0b76b6717 hgweb: Change default style to paper
Matt Mackall <mpm@selenic.com>
parents: 7336
diff changeset
    28
        self.style = 'paper'
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
    29
        self.stripecount = None
2174
3044a3fdae76 If default sorting is name, offer name-descending with one click.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2173
diff changeset
    30
        self.repos_sorted = ('name', False)
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
    31
        self._baseurl = None
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    32
        if isinstance(config, (list, tuple)):
1181
4f5001f5b4c3 Make sure the repository names don't have slashes at the at or else in some
Vincent Wagelaar <vincent@ricardis.tudelft.nl>
parents: 1180
diff changeset
    33
            self.repos = cleannames(config)
2174
3044a3fdae76 If default sorting is name, offer name-descending with one click.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2173
diff changeset
    34
            self.repos_sorted = ('', False)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    35
        elif isinstance(config, dict):
6908
b77c25c2d6c0 Do not sort hgwebdir repositories if python list or tuple is given.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6797
diff changeset
    36
            self.repos = util.sort(cleannames(config.items()))
1143
4fffb3d84b7c Allow list of (virtual, real) or dictionary to be passed to hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1142
diff changeset
    37
        else:
4051
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    38
            if isinstance(config, util.configparser):
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    39
                cp = config
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    40
            else:
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    41
                cp = util.configparser()
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    42
                cp.read(config)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    43
            self.repos = []
3221
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    44
            if cp.has_section('web'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    45
                if cp.has_option('web', 'motd'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    46
                    self.motd = cp.get('web', 'motd')
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    47
                if cp.has_option('web', 'style'):
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3221
diff changeset
    48
                    self.style = cp.get('web', 'style')
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
    49
                if cp.has_option('web', 'stripes'):
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
    50
                    self.stripecount = int(cp.get('web', 'stripes'))
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
    51
                if cp.has_option('web', 'baseurl'):
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
    52
                    self._baseurl = cp.get('web', 'baseurl')
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    53
            if cp.has_section('paths'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    54
                self.repos.extend(cleannames(cp.items('paths')))
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    55
            if cp.has_section('collections'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    56
                for prefix, root in cp.items('collections'):
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6284
diff changeset
    57
                    for path in util.walkrepos(root, followsym=True):
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    58
                        repo = os.path.normpath(path)
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    59
                        name = repo
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    60
                        if name.startswith(prefix):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    61
                            name = name[len(prefix):]
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    62
                        self.repos.append((name.lstrip(os.sep), repo))
1143
4fffb3d84b7c Allow list of (virtual, real) or dictionary to be passed to hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1142
diff changeset
    63
            self.repos.sort()
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    64
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    65
    def run(self):
2538
f4b7d71c1c60 Cleanup hgweb and hgwebdir's run method a bit.
Eric Hopper <hopper@omnifarious.org>
parents: 2537
diff changeset
    66
        if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    67
            raise RuntimeError("This function is only intended to be called while running as a CGI script.")
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    68
        import mercurial.hgweb.wsgicgi as wsgicgi
5566
d74fc8dec2b4 Less indirection in the WSGI web interface. This simplifies some code, and makes it more compliant with WSGI.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5561
diff changeset
    69
        wsgicgi.launch(self)
d74fc8dec2b4 Less indirection in the WSGI web interface. This simplifies some code, and makes it more compliant with WSGI.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5561
diff changeset
    70
d74fc8dec2b4 Less indirection in the WSGI web interface. This simplifies some code, and makes it more compliant with WSGI.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5561
diff changeset
    71
    def __call__(self, env, respond):
d74fc8dec2b4 Less indirection in the WSGI web interface. This simplifies some code, and makes it more compliant with WSGI.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5561
diff changeset
    72
        req = wsgirequest(env, respond)
6797
8909070fd05e merge another backout
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6796
diff changeset
    73
        return self.run_wsgi(req)
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    74
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    75
    def read_allowed(self, ui, req):
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    76
        """Check allow_read and deny_read config options of a repo's ui object
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    77
        to determine user permissions.  By default, with neither option set (or
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    78
        both empty), allow all users to read the repo.  There are two ways a
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    79
        user can be denied read access:  (1) deny_read is not empty, and the
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    80
        user is unauthenticated or deny_read contains user (or *), and (2)
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    81
        allow_read is not empty and the user is not in allow_read.  Return True
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    82
        if user is allowed to read the repo, else return False."""
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    83
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    84
        user = req.env.get('REMOTE_USER')
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    85
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    86
        deny_read = ui.configlist('web', 'deny_read', default=None, untrusted=True)
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    87
        if deny_read and (not user or deny_read == ['*'] or user in deny_read):
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    88
            return False
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    89
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    90
        allow_read = ui.configlist('web', 'allow_read', default=None, untrusted=True)
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    91
        # by default, allow reading if no allow_read option has been set
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    92
        if (not allow_read) or (allow_read == ['*']) or (user in allow_read):
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    93
            return True
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    94
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    95
        return False
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    96
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    97
    def run_wsgi(self, req):
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    98
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
    99
        try:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   100
            try:
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   101
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   102
                virtual = req.env.get("PATH_INFO", "").strip('/')
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   103
                tmpl = self.templater(req)
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   104
                ctype = tmpl('mimetype', encoding=util._encoding)
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   105
                ctype = templater.stringify(ctype)
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5603
diff changeset
   106
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   107
                # a static file
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   108
                if virtual.startswith('static/') or 'static' in req.form:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   109
                    if virtual.startswith('static/'):
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   110
                        fname = virtual[7:]
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   111
                    else:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   112
                        fname = req.form['static'][0]
7107
125c8fedcbe0 Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents: 6945
diff changeset
   113
                    static = templater.templatepath('static')
6945
2cfdabe235fb hgweb: return content iterator instead of using write() callable
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6913
diff changeset
   114
                    return staticfile(static, fname, req)
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   115
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   116
                # top-level index
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   117
                elif not virtual:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   118
                    req.respond(HTTP_OK, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   119
                    return self.makeindex(req, tmpl)
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   120
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   121
                # nested indexes and hgwebs
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6046
diff changeset
   122
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   123
                repos = dict(self.repos)
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   124
                while virtual:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   125
                    real = repos.get(virtual)
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   126
                    if real:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   127
                        req.env['REPO_NAME'] = virtual
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   128
                        try:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   129
                            repo = hg.repository(self.parentui, real)
6797
8909070fd05e merge another backout
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6796
diff changeset
   130
                            return hgweb(repo).run_wsgi(req)
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   131
                        except IOError, inst:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   132
                            msg = inst.strerror
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   133
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
6217
fe8dbbe9520d Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
Joel Rosdahl <joel@rosdahl.net>
parents: 6210
diff changeset
   134
                        except RepoError, inst:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   135
                            raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   136
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   137
                    # browse subdirectories
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   138
                    subdir = virtual + '/'
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   139
                    if [r for r in repos if r.startswith(subdir)]:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   140
                        req.respond(HTTP_OK, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   141
                        return self.makeindex(req, tmpl, subdir)
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   142
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   143
                    up = virtual.rfind('/')
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   144
                    if up < 0:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   145
                        break
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   146
                    virtual = virtual[:up]
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   147
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   148
                # prefixes not found
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   149
                req.respond(HTTP_NOT_FOUND, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   150
                return tmpl("notfound", repo=virtual)
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5603
diff changeset
   151
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   152
            except ErrorResponse, err:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   153
                req.respond(err.code, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   154
                return tmpl('error', error=err.message or '')
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   155
        finally:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   156
            tmpl = None
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   157
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   158
    def makeindex(self, req, tmpl, subdir=""):
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   159
2171
290534ee163c Add download links to hgwebdir index page for allowed archive types.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2170
diff changeset
   160
        def archivelist(ui, nodeid, url):
3556
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   161
            allowed = ui.configlist("web", "allow_archive", untrusted=True)
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   162
            for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
3556
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   163
                if i[0] in allowed or ui.configbool("web", "allow" + i[0],
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   164
                                                    untrusted=True):
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   165
                    yield {"type" : i[0], "extension": i[1],
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   166
                           "node": nodeid, "url": url}
2171
290534ee163c Add download links to hgwebdir index page for allowed archive types.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2170
diff changeset
   167
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   168
        def entries(sortcolumn="", descending=False, subdir="", **map):
3365
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   169
            def sessionvars(**map):
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   170
                fields = []
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5779
diff changeset
   171
                if 'style' in req.form:
3365
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   172
                    style = req.form['style'][0]
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   173
                    if style != get('web', 'style', ''):
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   174
                        fields.append(('style', style))
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   175
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   176
                separator = url[-1] == '?' and ';' or '?'
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   177
                for name, value in fields:
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   178
                    yield dict(name=name, value=value, separator=separator)
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   179
                    separator = ';'
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   180
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   181
            rows = []
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   182
            parity = paritygen(self.stripecount)
1141
033c968d7c66 Use ConfigParser only in hgwebdir.__init__()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1140
diff changeset
   183
            for name, path in self.repos:
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   184
                if not name.startswith(subdir):
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   185
                    continue
4843
496ac05c6a31 hgwebdir: show only trailing part of path when browsing subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4841
diff changeset
   186
                name = name[len(subdir):]
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   187
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   188
                u = ui.ui(parentui=self.parentui)
1170
85555540a4e2 Make .hg/hgrc optional for repositories published by hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1165
diff changeset
   189
                try:
1473
7d66ce9895fa make readconfig take a filename instead of a file pointer as argument
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1445
diff changeset
   190
                    u.readconfig(os.path.join(path, '.hg', 'hgrc'))
5332
b0bfe087ad8a hgwebdir: ignore hgrc parse errors while building the index page
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5289
diff changeset
   191
                except Exception, e:
6913
580d5e6bfc1f move % out of translatable strings
Martin Geisler <mg@daimi.au.dk>
parents: 6908
diff changeset
   192
                    u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e))
5332
b0bfe087ad8a hgwebdir: ignore hgrc parse errors while building the index page
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5289
diff changeset
   193
                    continue
3556
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   194
                def get(section, name, default=None):
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   195
                    return u.config(section, name, default, untrusted=True)
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   196
4709
53eca35c3aeb Add option "hidden" to hgwebdir.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents: 4462
diff changeset
   197
                if u.configbool("web", "hidden", untrusted=True):
53eca35c3aeb Add option "hidden" to hgwebdir.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents: 4462
diff changeset
   198
                    continue
53eca35c3aeb Add option "hidden" to hgwebdir.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents: 4462
diff changeset
   199
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   200
                if not self.read_allowed(u, req):
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   201
                    continue
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   202
6459
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   203
                parts = [name]
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   204
                if 'PATH_INFO' in req.env:
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   205
                    parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
5579
e15f7db0f0ee Use SCRIPT_NAME and PATH_INFO instead of REQUEST_URI. This is required by WSGI (fixes issue846).
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5566
diff changeset
   206
                if req.env['SCRIPT_NAME']:
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5603
diff changeset
   207
                    parts.insert(0, req.env['SCRIPT_NAME'])
5579
e15f7db0f0ee Use SCRIPT_NAME and PATH_INFO instead of REQUEST_URI. This is required by WSGI (fixes issue846).
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5566
diff changeset
   208
                url = ('/'.join(parts).replace("//", "/")) + '/'
1022
31dcaf9123ba Minor hgwebdir tweaks
mpm@selenic.com
parents: 987
diff changeset
   209
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   210
                # update time with local timezone
1524
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   211
                try:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   212
                    d = (get_mtime(path), util.makedate()[1])
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   213
                except OSError:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   214
                    continue
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   215
5779
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
   216
                contact = get_contact(get)
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   217
                description = get("web", "description", "")
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   218
                name = get("web", "name", name)
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   219
                row = dict(contact=contact or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   220
                           contact_sort=contact.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   221
                           name=name,
2174
3044a3fdae76 If default sorting is name, offer name-descending with one click.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2173
diff changeset
   222
                           name_sort=name,
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1023
diff changeset
   223
                           url=url,
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   224
                           description=description or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   225
                           description_sort=description.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   226
                           lastchange=d,
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   227
                           lastchange_sort=d[1]-d[0],
3365
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   228
                           sessionvars=sessionvars,
2171
290534ee163c Add download links to hgwebdir index page for allowed archive types.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2170
diff changeset
   229
                           archives=archivelist(u, "tip", url))
2174
3044a3fdae76 If default sorting is name, offer name-descending with one click.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2173
diff changeset
   230
                if (not sortcolumn
3044a3fdae76 If default sorting is name, offer name-descending with one click.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2173
diff changeset
   231
                    or (sortcolumn, descending) == self.repos_sorted):
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   232
                    # fast path for unsorted output
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   233
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   234
                    yield row
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   235
                else:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   236
                    rows.append((row["%s_sort" % sortcolumn], row))
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   237
            if rows:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   238
                rows.sort()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   239
                if descending:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   240
                    rows.reverse()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   241
                for key, row in rows:
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   242
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   243
                    yield row
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   244
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   245
        sortable = ["name", "description", "contact", "lastchange"]
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   246
        sortcolumn, descending = self.repos_sorted
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5779
diff changeset
   247
        if 'sort' in req.form:
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   248
            sortcolumn = req.form['sort'][0]
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   249
            descending = sortcolumn.startswith('-')
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   250
            if descending:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   251
                sortcolumn = sortcolumn[1:]
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   252
            if sortcolumn not in sortable:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   253
                sortcolumn = ""
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   254
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   255
        sort = [("sort_%s" % column,
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   256
                 "%s%s" % ((not descending and column == sortcolumn)
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   257
                            and "-" or "", column))
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   258
                for column in sortable]
5928
3340aa5a64f7 hgweb: move HTTP content types out of header templates
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5915
diff changeset
   259
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   260
        if self._baseurl is not None:
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   261
            req.env['SCRIPT_NAME'] = self._baseurl
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   262
5965
abe373e16fe6 hgweb: forgot to centralize the req.write() calls in hgwebdir
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5928
diff changeset
   263
        return tmpl("index", entries=entries, subdir=subdir,
abe373e16fe6 hgweb: forgot to centralize the req.write() calls in hgwebdir
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5928
diff changeset
   264
                    sortcolumn=sortcolumn, descending=descending,
abe373e16fe6 hgweb: forgot to centralize the req.write() calls in hgwebdir
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5928
diff changeset
   265
                    **dict(sort))
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   266
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   267
    def templater(self, req):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   268
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   269
        def header(**map):
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   270
            yield tmpl('header', encoding=util._encoding, **map)
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   271
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   272
        def footer(**map):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   273
            yield tmpl("footer", **map)
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   274
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   275
        def motd(**map):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   276
            if self.motd is not None:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   277
                yield self.motd
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   278
            else:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   279
                yield config('web', 'motd', '')
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   280
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   281
        def config(section, name, default=None, untrusted=True):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   282
            return self.parentui.config(section, name, default, untrusted)
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   283
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   284
        if self._baseurl is not None:
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   285
            req.env['SCRIPT_NAME'] = self._baseurl
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   286
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   287
        url = req.env.get('SCRIPT_NAME', '')
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   288
        if not url.endswith('/'):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   289
            url += '/'
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   290
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   291
        staticurl = config('web', 'staticurl') or url + 'static/'
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   292
        if not staticurl.endswith('/'):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   293
            staticurl += '/'
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   294
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   295
        style = self.style
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   296
        if style is None:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   297
            style = config('web', 'style', '')
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5779
diff changeset
   298
        if 'style' in req.form:
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   299
            style = req.form['style'][0]
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   300
        if self.stripecount is None:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   301
            self.stripecount = int(config('web', 'stripes', 1))
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   302
        mapfile = style_map(templater.templatepath(), style)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents: 5970
diff changeset
   303
        tmpl = templater.templater(mapfile, templatefilters.filters,
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   304
                                   defaults={"header": header,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   305
                                             "footer": footer,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   306
                                             "motd": motd,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   307
                                             "url": url,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   308
                                             "staticurl": staticurl})
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   309
        return tmpl