mercurial/hgweb/hgwebdir_mod.py
author Matt Mackall <mpm@selenic.com>
Fri, 01 Jun 2007 18:40:14 -0500
changeset 4478 b2b55acbacdd
parent 4461 12e4d9524951
child 4709 53eca35c3aeb
permissions -rw-r--r--
Add support for url#id syntax This allows you to do: hg clone http://server/repo#stable which is equivalent to: hg clone -r stable http://server/repo Future incoming, outgoing, and push commands will default to using this id because it's recorded in the default path. Other commands that accept URLs (push, pull, bundle, incoming, and outgoing) also accept this syntax.
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>
2858
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
3886
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3543
diff changeset
     9
from mercurial import demandimport; demandimport.enable()
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3543
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 _
3886
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3543
diff changeset
    12
from mercurial import ui, hg, util, templater
4461
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
3886
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3543
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: 3879
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):
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    20
            return [(name.strip(os.sep), path) 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
    21
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: 3879
diff changeset
    22
        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
    23
        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
    24
        self.style = None
4461
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
    25
        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
    26
        self.repos_sorted = ('name', False)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    27
        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
    28
            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
    29
            self.repos_sorted = ('', False)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    30
        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
    31
            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
    32
            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
    33
        else:
4051
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    34
            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
    35
                cp = config
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    36
            else:
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    37
                cp = util.configparser()
022056263354 hgwebdir: class hgwebdir should also accept a configparser instance
Michael Gebetsroither <michael.geb@gmx.at>
parents: 3887
diff changeset
    38
                cp.read(config)
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    39
            self.repos = []
3213
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2858
diff changeset
    40
            if cp.has_section('web'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2858
diff changeset
    41
                if cp.has_option('web', 'motd'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2858
diff changeset
    42
                    self.motd = cp.get('web', 'motd')
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2858
diff changeset
    43
                if cp.has_option('web', 'style'):
3215
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3213
diff changeset
    44
                    self.style = cp.get('web', 'style')
4461
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
    45
                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
    46
                    self.stripecount = int(cp.get('web', 'stripes'))
1829
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    47
            if cp.has_section('paths'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    48
                self.repos.extend(cleannames(cp.items('paths')))
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    49
            if cp.has_section('collections'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    50
                for prefix, root in cp.items('collections'):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    51
                    for path in util.walkrepos(root):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    52
                        repo = os.path.normpath(path)
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    53
                        name = repo
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    54
                        if name.startswith(prefix):
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    55
                            name = name[len(prefix):]
b0f6af327fd4 hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1703
diff changeset
    56
                        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
    57
            self.repos.sort()
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    58
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    59
    def run(self):
2538
f4b7d71c1c60 Cleanup hgweb and hgwebdir's run method a bit.
Eric Hopper <hopper@omnifarious.org>
parents: 2537
diff changeset
    60
        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
    61
            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
    62
        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
    63
        from request import wsgiapplication
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    64
        def make_web_app():
2538
f4b7d71c1c60 Cleanup hgweb and hgwebdir's run method a bit.
Eric Hopper <hopper@omnifarious.org>
parents: 2537
diff changeset
    65
            return self
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    66
        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
    67
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
    68
    def run_wsgi(self, req):
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    69
        def header(**map):
3879
9c8488490724 Set charset encoding for hgwebdir, too.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3543
diff changeset
    70
            header_file = cStringIO.StringIO(
9c8488490724 Set charset encoding for hgwebdir, too.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3543
diff changeset
    71
                ''.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
    72
            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
    73
            req.header(msg.items())
419c42223bee Really fix http headers for web UI and issue 254.
Eric Hopper <hopper@omnifarious.org>
parents: 2509
diff changeset
    74
            yield header_file.read()
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    75
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    76
        def footer(**map):
3474
bbfb392b2b1a Fix "templater object got multiple values for keyword argument 'motd'"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3473
diff changeset
    77
            yield tmpl("footer", **map)
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
    78
3483
8f02223662c8 hgweb: make #motd# available for all templates
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3474
diff changeset
    79
        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
    80
            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
    81
                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
    82
            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
    83
                yield config('web', 'motd', '')
3483
8f02223662c8 hgweb: make #motd# available for all templates
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3474
diff changeset
    84
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: 3879
diff changeset
    85
        parentui = self.parentui or ui.ui(report_untrusted=False)
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: 3879
diff changeset
    86
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
    87
        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
    88
            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
    89
3326
415905fad4fe Add base URL to hgwebdir templater (fixes index page when the URL does not have a trailing /)
Brendan Cully <brendan@kublai.com>
parents: 3275
diff changeset
    90
        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: 3275
diff changeset
    91
        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: 3275
diff changeset
    92
            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: 3275
diff changeset
    93
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
    94
        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
    95
        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
    96
            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
    97
3213
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2858
diff changeset
    98
        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
    99
        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
   100
            style = config('web', 'style', '')
3213
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2858
diff changeset
   101
        if req.form.has_key('style'):
d7d53e3d9590 Add style support to hgwebdir
Edouard Gomez <ed.gomez@free.fr>
parents: 2858
diff changeset
   102
            style = req.form['style'][0]
4461
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   103
        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
   104
            self.stripecount = int(config('web', 'stripes', 1))
3275
db9d2a624521 hgweb: Search templates in templatepath/style/map, too, using a common function.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3262
diff changeset
   105
        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: 3262
diff changeset
   106
        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
   107
                                   defaults={"header": header,
3326
415905fad4fe Add base URL to hgwebdir templater (fixes index page when the URL does not have a trailing /)
Brendan Cully <brendan@kublai.com>
parents: 3275
diff changeset
   108
                                             "footer": footer,
3483
8f02223662c8 hgweb: make #motd# available for all templates
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3474
diff changeset
   109
                                             "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
   110
                                             "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
   111
                                             "staticurl": staticurl})
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   112
2171
290534ee163c Add download links to hgwebdir index page for allowed archive types.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2170
diff changeset
   113
        def archivelist(ui, nodeid, url):
3542
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3483
diff changeset
   114
            allowed = ui.configlist("web", "allow_archive", untrusted=True)
3261
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3215
diff changeset
   115
            for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
3542
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3483
diff changeset
   116
                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: 3483
diff changeset
   117
                                                    untrusted=True):
3261
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3215
diff changeset
   118
                    yield {"type" : i[0], "extension": i[1],
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3215
diff changeset
   119
                           "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
   120
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   121
        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: 3326
diff changeset
   122
            def sessionvars(**map):
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   123
                fields = []
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   124
                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: 3326
diff changeset
   125
                    style = req.form['style'][0]
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   126
                    if style != get('web', 'style', ''):
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   127
                        fields.append(('style', style))
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   128
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   129
                separator = url[-1] == '?' and ';' or '?'
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   130
                for name, value in fields:
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   131
                    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: 3326
diff changeset
   132
                    separator = ';'
cf680c9ab1dd Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3326
diff changeset
   133
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   134
            rows = []
4461
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   135
            parity = paritygen(self.stripecount)
1141
033c968d7c66 Use ConfigParser only in hgwebdir.__init__()
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1140
diff changeset
   136
            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: 3879
diff changeset
   137
                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
   138
                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
   139
                    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
   140
                except IOError:
85555540a4e2 Make .hg/hgrc optional for repositories published by hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1165
diff changeset
   141
                    pass
3542
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3483
diff changeset
   142
                def get(section, name, default=None):
c3043ebe40a0 use untrusted settings in hgwebdir
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3483
diff changeset
   143
                    return u.config(section, name, default, untrusted=True)
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   144
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
   145
                url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name])
3261
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3215
diff changeset
   146
                       .replace("//", "/")) + '/'
1022
31dcaf9123ba Minor hgwebdir tweaks
mpm@selenic.com
parents: 987
diff changeset
   147
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   148
                # update time with local timezone
1524
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   149
                try:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   150
                    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
   151
                except OSError:
0d47bb884330 hgweb: fix traceback by skipping invalid repo paths
TK Soh <teekaysoh@yahoo.com>
parents: 1511
diff changeset
   152
                    continue
1348
b8c82bf3da21 hgwebdir: Fix date display
mpm@selenic.com
parents: 1333
diff changeset
   153
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   154
                contact = (get("ui", "username") or # preferred
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   155
                           get("web", "contact") or # deprecated
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   156
                           get("web", "author", "")) # also
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   157
                description = get("web", "description", "")
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   158
                name = get("web", "name", name)
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   159
                row = dict(contact=contact or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   160
                           contact_sort=contact.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   161
                           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
   162
                           name_sort=name,
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1023
diff changeset
   163
                           url=url,
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   164
                           description=description or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   165
                           description_sort=description.upper() or "unknown",
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   166
                           lastchange=d,
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   167
                           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: 3326
diff changeset
   168
                           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
   169
                           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
   170
                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
   171
                    or (sortcolumn, descending) == self.repos_sorted):
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   172
                    # fast path for unsorted output
4461
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   173
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   174
                    yield row
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   175
                else:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   176
                    rows.append((row["%s_sort" % sortcolumn], row))
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   177
            if rows:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   178
                rows.sort()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   179
                if descending:
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   180
                    rows.reverse()
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   181
                for key, row in rows:
4461
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4250
diff changeset
   182
                    row['parity'] = parity.next()
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   183
                    yield row
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   184
4246
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   185
        try:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   186
            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
   187
            if virtual.startswith('static/'):
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   188
                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
   189
                fname = virtual[7:]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   190
                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
   191
                          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
   192
            elif virtual:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   193
                while virtual:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   194
                    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
   195
                    if real:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   196
                        break
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   197
                    up = virtual.rfind('/')
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   198
                    if up < 0:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   199
                        break
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   200
                    virtual = virtual[:up]
3261
1e322b44b366 Teach hgwebdir about new interface
Brendan Cully <brendan@kublai.com>
parents: 3215
diff changeset
   201
                if real:
4246
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   202
                    req.env['REPO_NAME'] = virtual
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   203
                    try:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   204
                        repo = hg.repository(parentui, real)
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   205
                        hgweb(repo).run_wsgi(req)
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   206
                    except IOError, inst:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   207
                        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
   208
                    except hg.RepoError, inst:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   209
                        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
   210
                else:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   211
                    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
   212
            else:
4246
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   213
                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
   214
                    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
   215
                    fname = req.form['static'][0]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   216
                    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
   217
                              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
   218
                else:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   219
                    sortable = ["name", "description", "contact", "lastchange"]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   220
                    sortcolumn, descending = self.repos_sorted
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   221
                    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
   222
                        sortcolumn = req.form['sort'][0]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   223
                        descending = sortcolumn.startswith('-')
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   224
                        if descending:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   225
                            sortcolumn = sortcolumn[1:]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   226
                        if sortcolumn not in sortable:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   227
                            sortcolumn = ""
2173
d1943df604c4 Make hgwebdir columns sortable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2171
diff changeset
   228
4246
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   229
                    sort = [("sort_%s" % column,
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   230
                             "%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
   231
                                       and "-" or "", column))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   232
                            for column in sortable]
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   233
                    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
   234
                                   sortcolumn=sortcolumn, descending=descending,
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   235
                                   **dict(sort)))
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   236
        finally:
a80502f47552 hgwebdir: break templater -> templater circular reference
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4080
diff changeset
   237
            tmpl = None