mercurial/hgweb/hgwebdir_mod.py
author Dirkjan Ochtman <dirkjan@ochtman.nl>
Fri, 07 Sep 2007 17:38:52 +0200
changeset 5289 ed6df6b1c29a
parent 5063 142a07e758c8
child 5290 05889b6b1468
child 5332 b0bfe087ad8a
permissions -rw-r--r--
Prevent WSGI apps from touching sys.stdin by setting ui.interactive to False.
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
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3557
diff changeset
     9
from mercurial import demandimport; demandimport.enable()
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3557
diff changeset
    10
import os, mimetools, cStringIO
2311
b832b6eb65ab Moving hgweb.py into it's own module in preparation for breaking it up.
Eric Hopper <hopper@omnifarious.org>
parents: 2275
diff changeset
    11
from mercurial.i18n import gettext as _
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3557
diff changeset
    12
from mercurial import ui, hg, util, templater
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
    13
from common import get_mtime, staticfile, style_map, paritygen
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3557
diff changeset
    14
from hgweb_mod import hgweb
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    15
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    16
# 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
    17
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
    18
    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
    19
        def cleannames(items):
5063
142a07e758c8 hgwebdir: change os.sep in the name of repos to "/"
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4709
diff changeset
    20
            return [(util.pconvert(name.strip(os.sep)), path)
142a07e758c8 hgwebdir: change os.sep in the name of repos to "/"
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4709
diff changeset
    21
                    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
    22
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
    23
        self.parentui = parentui
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
    24
        self.motd = None
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
    25
        self.style = None
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
    26
        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
    27
        self.repos_sorted = ('name', False)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    28
        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
    29
            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
    30
            self.repos_sorted = ('', False)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    31
        elif isinstance(config, dict):
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.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
    33
            self.repos.sort()
4fffb3d84b7c Allow list of (virtual, real) or dictionary to be passed to hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1142
diff changeset
    34
        else:
4051
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    35
            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
    36
                cp = config
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    37
            else:
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    38
                cp = util.configparser()
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    39
                cp.read(config)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    40
            self.repos = []
3221
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    41
            if cp.has_section('web'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    42
                if cp.has_option('web', 'motd'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    43
                    self.motd = cp.get('web', 'motd')
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
    44
                if cp.has_option('web', 'style'):
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3221
diff changeset
    45
                    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
    46
                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
    47
                    self.stripecount = int(cp.get('web', 'stripes'))
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    48
            if cp.has_section('paths'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    49
                self.repos.extend(cleannames(cp.items('paths')))
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    50
            if cp.has_section('collections'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    51
                for prefix, root in cp.items('collections'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    52
                    for path in util.walkrepos(root):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    53
                        repo = os.path.normpath(path)
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    54
                        name = repo
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    55
                        if name.startswith(prefix):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    56
                            name = name[len(prefix):]
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    57
                        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
    58
            self.repos.sort()
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    59
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    60
    def run(self):
2538
f4b7d71c1c60 Cleanup hgweb and hgwebdir's run method a bit.
Eric Hopper <hopper@omnifarious.org>
parents: 2537
diff changeset
    61
        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
    62
            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
    63
        import mercurial.hgweb.wsgicgi as wsgicgi
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    64
        from request import wsgiapplication
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    65
        def make_web_app():
2538
f4b7d71c1c60 Cleanup hgweb and hgwebdir's run method a bit.
Eric Hopper <hopper@omnifarious.org>
parents: 2537
diff changeset
    66
            return self
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    67
        wsgicgi.launch(wsgiapplication(make_web_app))
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    68
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    69
    def run_wsgi(self, req):
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    70
        def header(**map):
3882
9c8488490724 Set charset encoding for hgwebdir, too.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3557
diff changeset
    71
            header_file = cStringIO.StringIO(
9c8488490724 Set charset encoding for hgwebdir, too.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3557
diff changeset
    72
                ''.join(tmpl("header", encoding=util._encoding, **map)))
2514
419c42223bee Really fix http headers for web UI and issue 254.
Eric Hopper <hopper@omnifarious.org>
parents: 2509
diff changeset
    73
            msg = mimetools.Message(header_file, 0)
419c42223bee Really fix http headers for web UI and issue 254.
Eric Hopper <hopper@omnifarious.org>
parents: 2509
diff changeset
    74
            req.header(msg.items())
419c42223bee Really fix http headers for web UI and issue 254.
Eric Hopper <hopper@omnifarious.org>
parents: 2509
diff changeset
    75
            yield header_file.read()
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    76
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    77
        def footer(**map):
3479
bbfb392b2b1a Fix "templater object got multiple values for keyword argument 'motd'"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3478
diff changeset
    78
            yield tmpl("footer", **map)
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    79
3488
8f02223662c8 hgweb: make #motd# available for all templates
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3479
diff changeset
    80
        def motd(**map):
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
    81
            if self.motd is not None:
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
    82
                yield self.motd
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
    83
            else:
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
    84
                yield config('web', 'motd', '')
3488
8f02223662c8 hgweb: make #motd# available for all templates
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3479
diff changeset
    85
5289
ed6df6b1c29a Prevent WSGI apps from touching sys.stdin by setting ui.interactive to False.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5063
diff changeset
    86
        parentui = self.parentui or ui.ui(report_untrusted=False,
ed6df6b1c29a Prevent WSGI apps from touching sys.stdin by setting ui.interactive to False.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5063
diff changeset
    87
                                          interactive=False)
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
    88
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
    89
        def config(section, name, default=None, untrusted=True):
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
    90
            return parentui.config(section, name, default, untrusted)
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
    91
3328
415905fad4fe Add base URL to hgwebdir templater (fixes index page when the URL does not have a trailing /)
Brendan Cully <brendan@kublai.com>
parents: 3276
diff changeset
    92
        url = req.env['REQUEST_URI'].split('?')[0]
415905fad4fe Add base URL to hgwebdir templater (fixes index page when the URL does not have a trailing /)
Brendan Cully <brendan@kublai.com>
parents: 3276
diff changeset
    93
        if not url.endswith('/'):
415905fad4fe Add base URL to hgwebdir templater (fixes index page when the URL does not have a trailing /)
Brendan Cully <brendan@kublai.com>
parents: 3276
diff changeset
    94
            url += '/'
415905fad4fe Add base URL to hgwebdir templater (fixes index page when the URL does not have a trailing /)
Brendan Cully <brendan@kublai.com>
parents: 3276
diff changeset
    95
4084
51e52db6b40d hgweb: allow static files to be served directly by the HTTP server
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4081
diff changeset
    96
        staticurl = config('web', 'staticurl') or url + 'static/'
51e52db6b40d hgweb: allow static files to be served directly by the HTTP server
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4081
diff changeset
    97
        if not staticurl.endswith('/'):
51e52db6b40d hgweb: allow static files to be served directly by the HTTP server
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4081
diff changeset
    98
            staticurl += '/'
51e52db6b40d hgweb: allow static files to be served directly by the HTTP server
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4081
diff changeset
    99
3221
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
   100
        style = self.style
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
   101
        if style is None:
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
   102
            style = config('web', 'style', '')
3221
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
   103
        if req.form.has_key('style'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2859
diff changeset
   104
            style = req.form['style'][0]
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   105
        if self.stripecount is None:
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   106
            self.stripecount = int(config('web', 'stripes', 1))
3276
db9d2a624521 hgweb: Search templates in templatepath/style/map, too, using a common function.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3263
diff changeset
   107
        mapfile = style_map(templater.templatepath(), style)
db9d2a624521 hgweb: Search templates in templatepath/style/map, too, using a common function.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3263
diff changeset
   108
        tmpl = templater.templater(mapfile, templater.common_filters,
1964
778281d46bb2 fix template bug that made hgweb break.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1920
diff changeset
   109
                                   defaults={"header": header,
3328
415905fad4fe Add base URL to hgwebdir templater (fixes index page when the URL does not have a trailing /)
Brendan Cully <brendan@kublai.com>
parents: 3276
diff changeset
   110
                                             "footer": footer,
3488
8f02223662c8 hgweb: make #motd# available for all templates
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3479
diff changeset
   111
                                             "motd": motd,
4084
51e52db6b40d hgweb: allow static files to be served directly by the HTTP server
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4081
diff changeset
   112
                                             "url": url,
51e52db6b40d hgweb: allow static files to be served directly by the HTTP server
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4081
diff changeset
   113
                                             "staticurl": staticurl})
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   114
2171
290534ee163c Add download links to hgwebdir index page for allowed archive types.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2170
diff changeset
   115
        def archivelist(ui, nodeid, url):
3556
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   116
            allowed = ui.configlist("web", "allow_archive", untrusted=True)
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   117
            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
   118
                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
   119
                                                    untrusted=True):
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   120
                    yield {"type" : i[0], "extension": i[1],
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   121
                           "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
   122
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   123
        def entries(sortcolumn="", descending=False, **map):
3365
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   124
            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
   125
                fields = []
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   126
                if req.form.has_key('style'):
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   127
                    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
   128
                    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
   129
                        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
   130
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   131
                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
   132
                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
   133
                    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
   134
                    separator = ';'
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3328
diff changeset
   135
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   136
            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
   137
            parity = paritygen(self.stripecount)
1141
033c968d7c66 Use ConfigParser only in hgwebdir.__init__()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1140
diff changeset
   138
            for name, path in self.repos:
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
   139
                u = ui.ui(parentui=parentui)
1170
85555540a4e2 Make .hg/hgrc optional for repositories published by hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1165
diff changeset
   140
                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
   141
                    u.readconfig(os.path.join(path, '.hg', 'hgrc'))
1170
85555540a4e2 Make .hg/hgrc optional for repositories published by hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1165
diff changeset
   142
                except IOError:
85555540a4e2 Make .hg/hgrc optional for repositories published by hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1165
diff changeset
   143
                    pass
3556
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   144
                def get(section, name, default=None):
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3488
diff changeset
   145
                    return u.config(section, name, default, untrusted=True)
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   146
4709
53eca35c3aeb Add option "hidden" to hgwebdir.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents: 4462
diff changeset
   147
                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
   148
                    continue
53eca35c3aeb Add option "hidden" to hgwebdir.
Markus F.X.J. Oberhumer <markus@oberhumer.com>
parents: 4462
diff changeset
   149
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
   150
                url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name])
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   151
                       .replace("//", "/")) + '/'
1022
31dcaf9123ba Minor hgwebdir tweaks
mpm@selenic.com
parents: 987
diff changeset
   152
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   153
                # update time with local timezone
1524
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   154
                try:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   155
                    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
   156
                except OSError:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   157
                    continue
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   158
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   159
                contact = (get("ui", "username") or # preferred
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   160
                           get("web", "contact") or # deprecated
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   161
                           get("web", "author", "")) # also
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   162
                description = get("web", "description", "")
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   163
                name = get("web", "name", name)
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   164
                row = dict(contact=contact or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   165
                           contact_sort=contact.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   166
                           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
   167
                           name_sort=name,
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1023
diff changeset
   168
                           url=url,
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   169
                           description=description or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   170
                           description_sort=description.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   171
                           lastchange=d,
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   172
                           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
   173
                           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
   174
                           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
   175
                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
   176
                    or (sortcolumn, descending) == self.repos_sorted):
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   177
                    # 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
   178
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   179
                    yield row
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   180
                else:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   181
                    rows.append((row["%s_sort" % sortcolumn], row))
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   182
            if rows:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   183
                rows.sort()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   184
                if descending:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   185
                    rows.reverse()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   186
                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
   187
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   188
                    yield row
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   189
4244
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   190
        try:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   191
            virtual = req.env.get("PATH_INFO", "").strip('/')
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   192
            if virtual.startswith('static/'):
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   193
                static = os.path.join(templater.templatepath(), 'static')
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   194
                fname = virtual[7:]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   195
                req.write(staticfile(static, fname, req) or
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   196
                          tmpl('error', error='%r not found' % fname))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   197
            elif virtual:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   198
                while virtual:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   199
                    real = dict(self.repos).get(virtual)
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   200
                    if real:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   201
                        break
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   202
                    up = virtual.rfind('/')
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   203
                    if up < 0:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   204
                        break
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   205
                    virtual = virtual[:up]
3262
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3223
diff changeset
   206
                if real:
4244
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   207
                    req.env['REPO_NAME'] = virtual
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   208
                    try:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   209
                        repo = hg.repository(parentui, real)
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   210
                        hgweb(repo).run_wsgi(req)
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   211
                    except IOError, inst:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   212
                        req.write(tmpl("error", error=inst.strerror))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   213
                    except hg.RepoError, inst:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   214
                        req.write(tmpl("error", error=str(inst)))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   215
                else:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   216
                    req.write(tmpl("notfound", repo=virtual))
1123
457c23af92bd Use a template for the error message.
Ollivier Robert <roberto@keltia.freenix.fr>
parents: 1122
diff changeset
   217
            else:
4244
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   218
                if req.form.has_key('static'):
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   219
                    static = os.path.join(templater.templatepath(), "static")
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   220
                    fname = req.form['static'][0]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   221
                    req.write(staticfile(static, fname, req)
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   222
                              or tmpl("error", error="%r not found" % fname))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   223
                else:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   224
                    sortable = ["name", "description", "contact", "lastchange"]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   225
                    sortcolumn, descending = self.repos_sorted
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   226
                    if req.form.has_key('sort'):
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   227
                        sortcolumn = req.form['sort'][0]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   228
                        descending = sortcolumn.startswith('-')
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   229
                        if descending:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   230
                            sortcolumn = sortcolumn[1:]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   231
                        if sortcolumn not in sortable:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   232
                            sortcolumn = ""
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   233
4244
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   234
                    sort = [("sort_%s" % column,
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   235
                             "%s%s" % ((not descending and column == sortcolumn)
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   236
                                       and "-" or "", column))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   237
                            for column in sortable]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   238
                    req.write(tmpl("index", entries=entries,
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   239
                                   sortcolumn=sortcolumn, descending=descending,
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   240
                                   **dict(sort)))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   241
        finally:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   242
            tmpl = None