mercurial/hgweb/hgwebdir_mod.py
author Matt Mackall <mpm@selenic.com>
Mon, 16 Feb 2009 17:37:23 -0600
changeset 7782 140429276b63
parent 7740 176d3d681702
child 7948 de377b1a9a84
child 8536 6796d41be421
permissions -rw-r--r--
mq: handle empty patches more gracefully (issue1501)
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 _
7637
1d54e2f6c0b7 error: move repo errors
Matt Mackall <mpm@selenic.com>
parents: 7575
diff changeset
    11
from mercurial import ui, hg, util, templater, templatefilters, error
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents: 5970
diff changeset
    12
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
    13
                   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
    14
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
    15
from request import wsgirequest
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    16
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    17
# 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
    18
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
    19
    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
    20
        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
    21
            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
    22
                    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
    23
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
    24
        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
    25
                                          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
    26
        self.motd = None
7337
feb0b76b6717 hgweb: Change default style to paper
Matt Mackall <mpm@selenic.com>
parents: 7336
diff changeset
    27
        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
    28
        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
    29
        self.repos_sorted = ('name', False)
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
    30
        self._baseurl = None
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    31
        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
    32
            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
    33
            self.repos_sorted = ('', False)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    34
        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
    35
            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
    36
        else:
4051
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    37
            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
    38
                cp = config
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    39
            else:
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    40
                cp = util.configparser()
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    41
                cp.read(config)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    42
            self.repos = []
3221
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    43
            if cp.has_section('web'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    44
                if cp.has_option('web', 'motd'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    45
                    self.motd = cp.get('web', 'motd')
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    46
                if cp.has_option('web', 'style'):
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3221
diff changeset
    47
                    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
    48
                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
    49
                    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
    50
                if cp.has_option('web', 'baseurl'):
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
    51
                    self._baseurl = cp.get('web', 'baseurl')
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    52
            if cp.has_section('paths'):
7450
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    53
                paths = cleannames(cp.items('paths'))
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    54
                for prefix, root in paths:
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    55
                    roothead, roottail = os.path.split(root)
7523
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    56
                    # "foo = /bar/*" makes every subrepo of /bar/ to be
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    57
                    # mounted as foo/subrepo
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    58
                    # and "foo = /bar/**" does even recurse inside the
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    59
                    # subdirectories, remember to use it without working dir.
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    60
                    try:
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    61
                        recurse = {'*': False, '**': True}[roottail]
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    62
                    except KeyError:
7450
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    63
                        self.repos.append((prefix, root))
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    64
                        continue
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    65
                    roothead = os.path.normpath(roothead)
7523
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    66
                    for path in util.walkrepos(roothead, followsym=True,
e60aaae83323 hgweb: recurse down collections only if ** in [paths]
Benoit Allard <benoit@aeteurope.nl>
parents: 7450
diff changeset
    67
                                               recurse=recurse):
7450
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    68
                        path = os.path.normpath(path)
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    69
                        name = util.pconvert(path[len(roothead):]).strip('/')
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    70
                        if prefix:
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    71
                            name = prefix + '/' + name
79d1bb737c16 hgweb: extend [paths] syntax to match repositories recursively (issue852)
Patrick Mezard <pmezard@gmail.com>
parents: 7396
diff changeset
    72
                        self.repos.append((name, path))
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    73
            if cp.has_section('collections'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    74
                for prefix, root in cp.items('collections'):
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6284
diff changeset
    75
                    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
    76
                        repo = os.path.normpath(path)
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    77
                        name = repo
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    78
                        if name.startswith(prefix):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    79
                            name = name[len(prefix):]
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    80
                        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
    81
            self.repos.sort()
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    82
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    83
    def run(self):
2538
f4b7d71c1c60 Cleanup hgweb and hgwebdir's run method a bit.
Eric Hopper <hopper@omnifarious.org>
parents: 2537
diff changeset
    84
        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
    85
            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
    86
        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
    87
        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
    88
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
    89
    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
    90
        req = wsgirequest(env, respond)
6797
8909070fd05e merge another backout
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6796
diff changeset
    91
        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
    92
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    93
    def read_allowed(self, ui, req):
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
    94
        """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
    95
        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
    96
        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
    97
        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
    98
        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
    99
        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
   100
        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
   101
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   102
        user = req.env.get('REMOTE_USER')
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   103
7575
3ccaefc84f45 hgweb: fix long line lengths introduced in 2dc868712dcc
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7560
diff changeset
   104
        deny_read = ui.configlist('web', 'deny_read', untrusted=True)
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   105
        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
   106
            return False
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   107
7575
3ccaefc84f45 hgweb: fix long line lengths introduced in 2dc868712dcc
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7560
diff changeset
   108
        allow_read = ui.configlist('web', 'allow_read', untrusted=True)
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   109
        # 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
   110
        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
   111
            return True
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   112
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   113
        return False
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   114
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
   115
    def run_wsgi(self, req):
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   116
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   117
        try:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   118
            try:
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   119
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   120
                virtual = req.env.get("PATH_INFO", "").strip('/')
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   121
                tmpl = self.templater(req)
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   122
                ctype = tmpl('mimetype', encoding=util._encoding)
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   123
                ctype = templater.stringify(ctype)
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5603
diff changeset
   124
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   125
                # a static file
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   126
                if virtual.startswith('static/') or 'static' in req.form:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   127
                    if virtual.startswith('static/'):
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   128
                        fname = virtual[7:]
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   129
                    else:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   130
                        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
   131
                    static = templater.templatepath('static')
7560
305efd897a63 hgwebdir_mod: fix a performance issue with static files
Patrick Mezard <pmezard@gmail.com>
parents: 7523
diff changeset
   132
                    return (staticfile(static, fname, req),)
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   133
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   134
                # top-level index
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   135
                elif not virtual:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   136
                    req.respond(HTTP_OK, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   137
                    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
   138
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   139
                # nested indexes and hgwebs
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6046
diff changeset
   140
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   141
                repos = dict(self.repos)
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   142
                while virtual:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   143
                    real = repos.get(virtual)
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   144
                    if real:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   145
                        req.env['REPO_NAME'] = virtual
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   146
                        try:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   147
                            repo = hg.repository(self.parentui, real)
6797
8909070fd05e merge another backout
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6796
diff changeset
   148
                            return hgweb(repo).run_wsgi(req)
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   149
                        except IOError, inst:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   150
                            msg = inst.strerror
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   151
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
7637
1d54e2f6c0b7 error: move repo errors
Matt Mackall <mpm@selenic.com>
parents: 7575
diff changeset
   152
                        except error.RepoError, inst:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   153
                            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
   154
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   155
                    # browse subdirectories
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   156
                    subdir = virtual + '/'
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   157
                    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
   158
                        req.respond(HTTP_OK, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   159
                        return self.makeindex(req, tmpl, subdir)
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   160
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   161
                    up = virtual.rfind('/')
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   162
                    if up < 0:
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   163
                        break
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   164
                    virtual = virtual[:up]
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   165
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   166
                # prefixes not found
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
   167
                req.respond(HTTP_NOT_FOUND, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   168
                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
   169
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   170
            except ErrorResponse, err:
7740
176d3d681702 hgweb: pass ErrorResponses directly into req.respond()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7637
diff changeset
   171
                req.respond(err, ctype)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7337
diff changeset
   172
                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
   173
        finally:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   174
            tmpl = None
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   175
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   176
    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
   177
2171
290534ee163c Add download links to hgwebdir index page for allowed archive types.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2170
diff changeset
   178
        def archivelist(ui, nodeid, url):
3556
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   179
            allowed = ui.configlist("web", "allow_archive", untrusted=True)
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   180
            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
   181
                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
   182
                                                    untrusted=True):
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   183
                    yield {"type" : i[0], "extension": i[1],
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   184
                           "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
   185
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   186
        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
   187
            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
   188
                fields = []
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5779
diff changeset
   189
                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
   190
                    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
   191
                    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
   192
                        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
   193
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   194
                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
   195
                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
   196
                    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
   197
                    separator = ';'
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   198
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   199
            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
   200
            parity = paritygen(self.stripecount)
1141
033c968d7c66 Use ConfigParser only in hgwebdir.__init__()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1140
diff changeset
   201
            for name, path in self.repos:
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   202
                if not name.startswith(subdir):
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   203
                    continue
4843
496ac05c6a31 hgwebdir: show only trailing part of path when browsing subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4841
diff changeset
   204
                name = name[len(subdir):]
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   205
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   206
                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
   207
                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
   208
                    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
   209
                except Exception, e:
6913
580d5e6bfc1f move % out of translatable strings
Martin Geisler <mg@daimi.au.dk>
parents: 6908
diff changeset
   210
                    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
   211
                    continue
3556
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   212
                def get(section, name, default=None):
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   213
                    return u.config(section, name, default, untrusted=True)
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   214
4709
53eca35c3aeb Add option "hidden" to hgwebdir.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents: 4462
diff changeset
   215
                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
   216
                    continue
53eca35c3aeb Add option "hidden" to hgwebdir.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents: 4462
diff changeset
   217
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   218
                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
   219
                    continue
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   220
6459
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   221
                parts = [name]
8189e03adb44 hgweb: make hgwebdir work in the absence of PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   222
                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
   223
                    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
   224
                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
   225
                    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
   226
                url = ('/'.join(parts).replace("//", "/")) + '/'
1022
31dcaf9123ba Minor hgwebdir tweaks
mpm@selenic.com
parents: 987
diff changeset
   227
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   228
                # update time with local timezone
1524
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   229
                try:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   230
                    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
   231
                except OSError:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   232
                    continue
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   233
5779
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
   234
                contact = get_contact(get)
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   235
                description = get("web", "description", "")
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   236
                name = get("web", "name", name)
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   237
                row = dict(contact=contact or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   238
                           contact_sort=contact.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   239
                           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
   240
                           name_sort=name,
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1023
diff changeset
   241
                           url=url,
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   242
                           description=description or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   243
                           description_sort=description.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   244
                           lastchange=d,
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   245
                           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
   246
                           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
   247
                           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
   248
                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
   249
                    or (sortcolumn, descending) == self.repos_sorted):
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   250
                    # 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
   251
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   252
                    yield row
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   253
                else:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   254
                    rows.append((row["%s_sort" % sortcolumn], row))
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   255
            if rows:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   256
                rows.sort()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   257
                if descending:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   258
                    rows.reverse()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   259
                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
   260
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   261
                    yield row
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   262
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   263
        sortable = ["name", "description", "contact", "lastchange"]
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   264
        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
   265
        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
   266
            sortcolumn = req.form['sort'][0]
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   267
            descending = sortcolumn.startswith('-')
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   268
            if descending:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   269
                sortcolumn = sortcolumn[1:]
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   270
            if sortcolumn not in sortable:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   271
                sortcolumn = ""
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   272
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   273
        sort = [("sort_%s" % column,
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   274
                 "%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
   275
                            and "-" or "", column))
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   276
                for column in sortable]
5928
3340aa5a64f7 hgweb: move HTTP content types out of header templates
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5915
diff changeset
   277
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   278
        if self._baseurl is not None:
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   279
            req.env['SCRIPT_NAME'] = self._baseurl
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   280
5965
abe373e16fe6 hgweb: forgot to centralize the req.write() calls in hgwebdir
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5928
diff changeset
   281
        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
   282
                    sortcolumn=sortcolumn, descending=descending,
abe373e16fe6 hgweb: forgot to centralize the req.write() calls in hgwebdir
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5928
diff changeset
   283
                    **dict(sort))
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   284
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   285
    def templater(self, req):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   286
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   287
        def header(**map):
6391
a1007f7b9b7b Backed out changeset d2bb66a8a435 (temporary template compatibility)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6379
diff changeset
   288
            yield tmpl('header', encoding=util._encoding, **map)
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   289
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   290
        def footer(**map):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   291
            yield tmpl("footer", **map)
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   292
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   293
        def motd(**map):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   294
            if self.motd is not None:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   295
                yield self.motd
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   296
            else:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   297
                yield config('web', 'motd', '')
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   298
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   299
        def config(section, name, default=None, untrusted=True):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   300
            return self.parentui.config(section, name, default, untrusted)
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   301
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   302
        if self._baseurl is not None:
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   303
            req.env['SCRIPT_NAME'] = self._baseurl
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   304
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   305
        url = req.env.get('SCRIPT_NAME', '')
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   306
        if not url.endswith('/'):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   307
            url += '/'
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   308
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   309
        staticurl = config('web', 'staticurl') or url + 'static/'
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   310
        if not staticurl.endswith('/'):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   311
            staticurl += '/'
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   312
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   313
        style = self.style
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   314
        if style is None:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   315
            style = config('web', 'style', '')
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5779
diff changeset
   316
        if 'style' in req.form:
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   317
            style = req.form['style'][0]
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   318
        if self.stripecount is None:
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   319
            self.stripecount = int(config('web', 'stripes', 1))
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   320
        mapfile = style_map(templater.templatepath(), style)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents: 5970
diff changeset
   321
        tmpl = templater.templater(mapfile, templatefilters.filters,
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   322
                                   defaults={"header": header,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   323
                                             "footer": footer,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   324
                                             "motd": motd,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   325
                                             "url": url,
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   326
                                             "staticurl": staticurl})
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   327
        return tmpl