mercurial/hgweb/hgwebdir_mod.py
author Martin von Zweigbergk <martinvonz@google.com>
Tue, 18 Dec 2018 09:34:32 -0800
changeset 41032 b2de94e59702
parent 40763 c93d046d4300
child 41344 46781c1b5049
permissions -rw-r--r--
repository: update interface signature of narrowmatch() This should have been part of 4fd0fac48922 (localrepo: allow narrowmatch() to accept matcher to intersect with, 2018-09-28) and 41fcdfe3bfeb (narrow: allow repo.narrowmatch(match) to include exact matches from "match", 2018-10-01). Differential Revision: https://phab.mercurial-scm.org/D5466
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
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8216
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9903
diff changeset
     7
# GNU General Public License version 2 or any later version.
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
     8
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
     9
from __future__ import absolute_import
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    10
35854
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
    11
import gc
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    12
import os
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    13
import time
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    14
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    15
from ..i18n import _
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    16
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    17
from .common import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    18
    ErrorResponse,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    19
    HTTP_SERVER_ERROR,
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
    20
    cspvalues,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    21
    get_contact,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    22
    get_mtime,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    23
    ismember,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    24
    paritygen,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    25
    staticfile,
36913
c1de7efca574 hgweb: port to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36912
diff changeset
    26
    statusmessage,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    27
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    28
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    29
from .. import (
34251
fe5202bef5ce configitems: register the 'web.refreshinterval' config
Boris Feld <boris.feld@octobus.net>
parents: 34250
diff changeset
    30
    configitems,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    31
    encoding,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    32
    error,
40762
2cd5f1fac788 hgweb: load globally-enabled extensions explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 39809
diff changeset
    33
    extensions,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    34
    hg,
29798
80df04266a16 hgweb: profile HTTP requests
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29797
diff changeset
    35
    profiling,
34359
8cbcee0b923d py3: remove use of str() in hgwebdir
Yuya Nishihara <yuya@tcha.org>
parents: 34264
diff changeset
    36
    pycompat,
38967
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
    37
    registrar,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    38
    scmutil,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    39
    templater,
37508
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
    40
    templateutil,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    41
    ui as uimod,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    42
    util,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    43
)
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    44
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    45
from . import (
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    46
    hgweb_mod,
36812
b9b968e21f78 hgweb: rename req to wsgireq
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36636
diff changeset
    47
    request as requestmod,
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    48
    webutil,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    49
    wsgicgi,
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27045
diff changeset
    50
)
36636
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 34703
diff changeset
    51
from ..utils import dateutil
138
c77a679e9cfa Revamped templated hgweb
mpm@selenic.com
parents: 137
diff changeset
    52
8215
227707c90548 hgweb: some cleanups in hgwebdir, remove double defaults
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8209
diff changeset
    53
def cleannames(items):
227707c90548 hgweb: some cleanups in hgwebdir, remove double defaults
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8209
diff changeset
    54
    return [(util.pconvert(name).strip('/'), 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
    55
8529
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    56
def findrepos(paths):
9723
a235644a0b93 hgweb: use a tuple-list instead of dictionary for append-only store
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9363
diff changeset
    57
    repos = []
8529
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    58
    for prefix, root in cleannames(paths):
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    59
        roothead, roottail = os.path.split(root)
17104
5a9acb0b2086 help: improve hgweb help
Mads Kiilerich <mads@kiilerich.com>
parents: 16754
diff changeset
    60
        # "foo = /bar/*" or "foo = /bar/**" lets every repo /bar/N in or below
5a9acb0b2086 help: improve hgweb help
Mads Kiilerich <mads@kiilerich.com>
parents: 16754
diff changeset
    61
        # /bar/ be served as as foo/N .
5a9acb0b2086 help: improve hgweb help
Mads Kiilerich <mads@kiilerich.com>
parents: 16754
diff changeset
    62
        # '*' will not search inside dirs with .hg (except .hg/patches),
5a9acb0b2086 help: improve hgweb help
Mads Kiilerich <mads@kiilerich.com>
parents: 16754
diff changeset
    63
        # '**' will search inside dirs with .hg (and thus also find subrepos).
8529
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    64
        try:
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    65
            recurse = {'*': False, '**': True}[roottail]
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    66
        except KeyError:
9723
a235644a0b93 hgweb: use a tuple-list instead of dictionary for append-only store
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9363
diff changeset
    67
            repos.append((prefix, root))
8529
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    68
            continue
11677
8f8a7976f4bc hgwebdir: allow pure relative globs in paths
Mads Kiilerich <mads@kiilerich.com>
parents: 11649
diff changeset
    69
        roothead = os.path.normpath(os.path.abspath(roothead))
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13964
diff changeset
    70
        paths = scmutil.walkrepos(roothead, followsym=True, recurse=recurse)
13402
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    71
        repos.extend(urlrepos(prefix, roothead, paths))
9723
a235644a0b93 hgweb: use a tuple-list instead of dictionary for append-only store
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9363
diff changeset
    72
    return repos
8529
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
    73
13402
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    74
def urlrepos(prefix, roothead, paths):
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    75
    """yield url paths and filesystem paths from a list of repo paths
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    76
13538
d24e97fd52a9 test-doctest: handle unix/windows path discrepancies
Patrick Mezard <pmezard@gmail.com>
parents: 13436
diff changeset
    77
    >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34040
diff changeset
    78
    >>> conv(urlrepos(b'hg', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt']))
13403
8ed91088acbb hgweb: make paths wildcards expanding in a repo root match repo correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 13402
diff changeset
    79
    [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34040
diff changeset
    80
    >>> conv(urlrepos(b'', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt']))
13402
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    81
    [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    82
    """
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    83
    for path in paths:
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    84
        path = os.path.normpath(path)
13403
8ed91088acbb hgweb: make paths wildcards expanding in a repo root match repo correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 13402
diff changeset
    85
        yield (prefix + '/' +
8ed91088acbb hgweb: make paths wildcards expanding in a repo root match repo correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 13402
diff changeset
    86
               util.pconvert(path[len(roothead):]).lstrip('/')).strip('/'), path
13402
f947d9a4c45c hgweb: doctest of url creation from wildcard expansion
Mads Kiilerich <mads@kiilerich.com>
parents: 13214
diff changeset
    87
36896
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    88
def readallowed(ui, req):
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    89
    """Check allow_read and deny_read config options of a repo's ui object
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    90
    to determine user permissions.  By default, with neither option set (or
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    91
    both empty), allow all users to read the repo.  There are two ways a
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    92
    user can be denied read access:  (1) deny_read is not empty, and the
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    93
    user is unauthenticated or deny_read contains user (or *), and (2)
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    94
    allow_read is not empty and the user is not in allow_read.  Return True
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    95
    if user is allowed to read the repo, else return False."""
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    96
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    97
    user = req.remoteuser
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    98
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
    99
    deny_read = ui.configlist('web', 'deny_read', untrusted=True)
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   100
    if deny_read and (not user or ismember(ui, user, deny_read)):
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   101
        return False
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   102
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   103
    allow_read = ui.configlist('web', 'allow_read', untrusted=True)
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   104
    # by default, allow reading if no allow_read option has been set
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   105
    if not allow_read or ismember(ui, user, allow_read):
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   106
        return True
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   107
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   108
    return False
f8d6d9b29b39 hgweb: move readallowed to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36895
diff changeset
   109
36910
092ab4ba7ee5 hgweb: don't pass wsgireq to makeindex and other functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   110
def rawindexentries(ui, repos, req, subdir=''):
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   111
    descend = ui.configbool('web', 'descend')
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   112
    collapse = ui.configbool('web', 'collapse')
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   113
    seenrepos = set()
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   114
    seendirs = set()
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   115
    for name, path in repos:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   116
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   117
        if not name.startswith(subdir):
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   118
            continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   119
        name = name[len(subdir):]
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   120
        directory = False
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   121
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   122
        if '/' in name:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   123
            if not descend:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   124
                continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   125
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   126
            nameparts = name.split('/')
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   127
            rootname = nameparts[0]
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   128
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   129
            if not collapse:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   130
                pass
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   131
            elif rootname in seendirs:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   132
                continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   133
            elif rootname in seenrepos:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   134
                pass
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   135
            else:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   136
                directory = True
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   137
                name = rootname
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   138
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   139
                # redefine the path to refer to the directory
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   140
                discarded = '/'.join(nameparts[1:])
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   141
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   142
                # remove name parts plus accompanying slash
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   143
                path = path[:-len(discarded) - 1]
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   144
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   145
                try:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   146
                    r = hg.repository(ui, path)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   147
                    directory = False
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   148
                except (IOError, error.RepoError):
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   149
                    pass
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   150
36908
e473a032f38a hgweb: rewrite path generation for index entries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36907
diff changeset
   151
        parts = [
36910
092ab4ba7ee5 hgweb: don't pass wsgireq to makeindex and other functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   152
            req.apppath.strip('/'),
36908
e473a032f38a hgweb: rewrite path generation for index entries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36907
diff changeset
   153
            subdir.strip('/'),
e473a032f38a hgweb: rewrite path generation for index entries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36907
diff changeset
   154
            name.strip('/'),
e473a032f38a hgweb: rewrite path generation for index entries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36907
diff changeset
   155
        ]
e473a032f38a hgweb: rewrite path generation for index entries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36907
diff changeset
   156
        url = '/' + '/'.join(p for p in parts if p) + '/'
15003
a31b8e03af28 hgweb: extract the path logic from updatereqenv and add doctests
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   157
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   158
        # show either a directory entry or a repository
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   159
        if directory:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   160
            # get the directory's time information
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   161
            try:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   162
                d = (get_mtime(path), dateutil.makedate()[1])
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   163
            except OSError:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   164
                continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   165
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   166
            # add '/' to the name to make it obvious that
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   167
            # the entry is a directory, not a regular repository
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   168
            row = {'contact': "",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   169
                   'contact_sort': "",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   170
                   'name': name + '/',
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   171
                   'name_sort': name,
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   172
                   'url': url,
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   173
                   'description': "",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   174
                   'description_sort': "",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   175
                   'lastchange': d,
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   176
                   'lastchange_sort': d[1] - d[0],
37515
8a5ee6aa8870 hgweb: wrap {archives} with mappinglist
Yuya Nishihara <yuya@tcha.org>
parents: 37513
diff changeset
   177
                   'archives': templateutil.mappinglist([]),
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   178
                   'isdirectory': True,
37510
876d54f800cf hgweb: wrap {labels} by hybridlist()
Yuya Nishihara <yuya@tcha.org>
parents: 37508
diff changeset
   179
                   'labels': templateutil.hybridlist([], name='label'),
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   180
                   }
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   181
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   182
            seendirs.add(name)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   183
            yield row
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   184
            continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   185
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   186
        u = ui.copy()
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   187
        try:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   188
            u.readconfig(os.path.join(path, '.hg', 'hgrc'))
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   189
        except Exception as e:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   190
            u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e))
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   191
            continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   192
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   193
        def get(section, name, default=uimod._unset):
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   194
            return u.config(section, name, default, untrusted=True)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   195
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   196
        if u.configbool("web", "hidden", untrusted=True):
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   197
            continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   198
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   199
        if not readallowed(u, req):
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   200
            continue
15003
a31b8e03af28 hgweb: extract the path logic from updatereqenv and add doctests
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   201
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   202
        # update time with local timezone
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   203
        try:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   204
            r = hg.repository(ui, path)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   205
        except IOError:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   206
            u.warn(_('error accessing repository at %s\n') % path)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   207
            continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   208
        except error.RepoError:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   209
            u.warn(_('error accessing repository at %s\n') % path)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   210
            continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   211
        try:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   212
            d = (get_mtime(r.spath), dateutil.makedate()[1])
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   213
        except OSError:
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   214
            continue
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   215
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   216
        contact = get_contact(get)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   217
        description = get("web", "description")
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   218
        seenrepos.add(name)
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   219
        name = get("web", "name", name)
37510
876d54f800cf hgweb: wrap {labels} by hybridlist()
Yuya Nishihara <yuya@tcha.org>
parents: 37508
diff changeset
   220
        labels = u.configlist('web', 'labels', untrusted=True)
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   221
        row = {'contact': contact or "unknown",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   222
               'contact_sort': contact.upper() or "unknown",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   223
               'name': name,
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   224
               'name_sort': name,
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   225
               'url': url,
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   226
               'description': description or "unknown",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   227
               'description_sort': description.upper() or "unknown",
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   228
               'lastchange': d,
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   229
               'lastchange_sort': d[1] - d[0],
37513
40a7c1dd2df9 hgweb: move archivelist() of hgwebdir to webutil
Yuya Nishihara <yuya@tcha.org>
parents: 37511
diff changeset
   230
               'archives': webutil.archivelist(u, "tip", url),
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   231
               'isdirectory': None,
37510
876d54f800cf hgweb: wrap {labels} by hybridlist()
Yuya Nishihara <yuya@tcha.org>
parents: 37508
diff changeset
   232
               'labels': templateutil.hybridlist(labels, name='label'),
36898
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   233
               }
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   234
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   235
        yield row
f370f1b4f12c hgweb: move rawentries() to a standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36897
diff changeset
   236
37508
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
   237
def _indexentriesgen(context, ui, repos, req, stripecount, sortcolumn,
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
   238
                     descending, subdir):
36910
092ab4ba7ee5 hgweb: don't pass wsgireq to makeindex and other functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   239
    rows = rawindexentries(ui, repos, req, subdir=subdir)
36899
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   240
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   241
    sortdefault = None, False
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   242
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   243
    if sortcolumn and sortdefault != (sortcolumn, descending):
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   244
        sortkey = '%s_sort' % sortcolumn
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   245
        rows = sorted(rows, key=lambda x: x[sortkey],
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   246
                      reverse=descending)
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   247
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   248
    for row, parity in zip(rows, paritygen(stripecount)):
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   249
        row['parity'] = parity
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   250
        yield row
15003
a31b8e03af28 hgweb: extract the path logic from updatereqenv and add doctests
Matt Mackall <mpm@selenic.com>
parents: 15002
diff changeset
   251
37508
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
   252
def indexentries(ui, repos, req, stripecount, sortcolumn='',
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
   253
                 descending=False, subdir=''):
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
   254
    args = (ui, repos, req, stripecount, sortcolumn, descending, subdir)
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
   255
    return templateutil.mappinggenerator(_indexentriesgen, args=args)
30a7b32897f1 hgwebdir: wrap {entries} with mappinggenerator
Yuya Nishihara <yuya@tcha.org>
parents: 37022
diff changeset
   256
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1554
diff changeset
   257
class hgwebdir(object):
26132
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26072
diff changeset
   258
    """HTTP server for multiple repositories.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26072
diff changeset
   259
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26072
diff changeset
   260
    Given a configuration, different repositories will be served depending
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26072
diff changeset
   261
    on the request path.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26072
diff changeset
   262
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26072
diff changeset
   263
    Instances are typically used as WSGI applications.
9df8c729e2e7 hgweb: add some documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26072
diff changeset
   264
    """
8191
35604226d712 hgweb: kill parentui references
Matt Mackall <mpm@selenic.com>
parents: 8190
diff changeset
   265
    def __init__(self, conf, baseui=None):
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   266
        self.conf = conf
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   267
        self.baseui = baseui
26072
06320fb11699 hgweb: make refresh interval configurable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   268
        self.ui = None
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   269
        self.lastrefresh = 0
9903
5d748045c2ae Do not overwrite motd attribute of hgwebdir instances on refresh.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 9842
diff changeset
   270
        self.motd = None
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   271
        self.refresh()
40762
2cd5f1fac788 hgweb: load globally-enabled extensions explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 39809
diff changeset
   272
        if not baseui:
2cd5f1fac788 hgweb: load globally-enabled extensions explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 39809
diff changeset
   273
            # set up environment for new ui
2cd5f1fac788 hgweb: load globally-enabled extensions explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 39809
diff changeset
   274
            extensions.loadall(self.ui)
40763
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40762
diff changeset
   275
            extensions.populateui(self.ui)
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
   276
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   277
    def refresh(self):
26072
06320fb11699 hgweb: make refresh interval configurable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   278
        if self.ui:
34251
fe5202bef5ce configitems: register the 'web.refreshinterval' config
Boris Feld <boris.feld@octobus.net>
parents: 34250
diff changeset
   279
            refreshinterval = self.ui.configint('web', 'refreshinterval')
fe5202bef5ce configitems: register the 'web.refreshinterval' config
Boris Feld <boris.feld@octobus.net>
parents: 34250
diff changeset
   280
        else:
fe5202bef5ce configitems: register the 'web.refreshinterval' config
Boris Feld <boris.feld@octobus.net>
parents: 34250
diff changeset
   281
            item = configitems.coreitems['web']['refreshinterval']
fe5202bef5ce configitems: register the 'web.refreshinterval' config
Boris Feld <boris.feld@octobus.net>
parents: 34250
diff changeset
   282
            refreshinterval = item.default
26072
06320fb11699 hgweb: make refresh interval configurable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   283
06320fb11699 hgweb: make refresh interval configurable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   284
        # refreshinterval <= 0 means to always refresh.
06320fb11699 hgweb: make refresh interval configurable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   285
        if (refreshinterval > 0 and
06320fb11699 hgweb: make refresh interval configurable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
   286
            self.lastrefresh + refreshinterval > time.time()):
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   287
            return
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   288
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   289
        if self.baseui:
11239
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   290
            u = self.baseui.copy()
1143
4fffb3d84b7c Allow list of (virtual, real) or dictionary to be passed to hgwebdir.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1142
diff changeset
   291
        else:
30564
d83ca854fa21 ui: factor out ui.load() to create a ui without loading configs (API)
Yuya Nishihara <yuya@tcha.org>
parents: 29798
diff changeset
   292
            u = uimod.ui.load()
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20677
diff changeset
   293
            u.setconfig('ui', 'report_untrusted', 'off', 'hgwebdir')
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20677
diff changeset
   294
            u.setconfig('ui', 'nontty', 'true', 'hgwebdir')
25488
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25427
diff changeset
   295
            # displaying bundling progress bar while serving feels wrong and may
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25427
diff changeset
   296
            # break some wsgi implementations.
89ce95f907bd hgewb: disable progress when serving (issue4582)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25427
diff changeset
   297
            u.setconfig('progress', 'disable', 'true', 'hgweb')
8136
6b5522cb2ad2 ui: refactor option setting
Matt Mackall <mpm@selenic.com>
parents: 7966
diff changeset
   298
8529
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
   299
        if not isinstance(self.conf, (dict, list, tuple)):
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
   300
            map = {'paths': 'hgweb-paths'}
13214
5bcb6c9d16db hgweb: abort if config file isn't found
Matt Mackall <mpm@selenic.com>
parents: 13066
diff changeset
   301
            if not os.path.exists(self.conf):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   302
                raise error.Abort(_('config file %s not found!') % self.conf)
11239
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   303
            u.readconfig(self.conf, remap=map, trust=True)
13667
8cbb59124e67 hgweb: support multiple directories for the same path
timeless <timeless@gmail.com>
parents: 13538
diff changeset
   304
            paths = []
8cbb59124e67 hgweb: support multiple directories for the same path
timeless <timeless@gmail.com>
parents: 13538
diff changeset
   305
            for name, ignored in u.configitems('hgweb-paths'):
8cbb59124e67 hgweb: support multiple directories for the same path
timeless <timeless@gmail.com>
parents: 13538
diff changeset
   306
                for path in u.configlist('hgweb-paths', name):
8cbb59124e67 hgweb: support multiple directories for the same path
timeless <timeless@gmail.com>
parents: 13538
diff changeset
   307
                    paths.append((name, path))
8529
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
   308
        elif isinstance(self.conf, (list, tuple)):
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
   309
            paths = self.conf
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
   310
        elif isinstance(self.conf, dict):
a767998f0a78 hgweb: make hgwebdir handle dict/list paths the same as config paths
Jeremy Whitlock <jcscoobyrs@gmail.com>
parents: 8389
diff changeset
   311
            paths = self.conf.items()
40763
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40762
diff changeset
   312
        extensions.populateui(u)
8345
dcebff8a25dd hgwebdir: read --webdir-conf as actual configuration to ui (issue1586)
Alexander Solovyov <piranha@piranha.org.ua>
parents: 8225
diff changeset
   313
11239
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   314
        repos = findrepos(paths)
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   315
        for prefix, root in u.configitems('collections'):
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   316
            prefix = util.pconvert(prefix)
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13964
diff changeset
   317
            for path in scmutil.walkrepos(root, followsym=True):
11239
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   318
                repo = os.path.normpath(path)
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   319
                name = util.pconvert(repo)
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   320
                if name.startswith(prefix):
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   321
                    name = name[len(prefix):]
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   322
                repos.append((name.lstrip('/'), repo))
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   323
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   324
        self.repos = repos
99bc18d1ab0f hgweb: fix race in refreshing repo list (issue2188)
Matt Mackall <mpm@selenic.com>
parents: 10675
diff changeset
   325
        self.ui = u
34246
344fd1fe237b configitems: register the 'web.encoding' config
Boris Feld <boris.feld@octobus.net>
parents: 34245
diff changeset
   326
        encoding.encoding = self.ui.config('web', 'encoding')
34253
db63872e10cc configitems: register the 'web.style' config
Boris Feld <boris.feld@octobus.net>
parents: 34252
diff changeset
   327
        self.style = self.ui.config('web', 'style')
34255
b59620c52eec hgwebdir: read 'web.template' untrusted
Boris Feld <boris.feld@octobus.net>
parents: 34254
diff changeset
   328
        self.templatepath = self.ui.config('web', 'templates', untrusted=False)
34252
945c9816ec1d configitems: register the 'web.stripes' config
Boris Feld <boris.feld@octobus.net>
parents: 34251
diff changeset
   329
        self.stripecount = self.ui.config('web', 'stripes')
8621
13613221caf1 hgweb: extract config values after reading webdir-config
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8537
diff changeset
   330
        if self.stripecount:
13613221caf1 hgweb: extract config values after reading webdir-config
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8537
diff changeset
   331
            self.stripecount = int(self.stripecount)
34250
d24816dfdcff configitems: register the 'web.prefix' config
Boris Feld <boris.feld@octobus.net>
parents: 34246
diff changeset
   332
        prefix = self.ui.config('web', 'prefix')
18515
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18258
diff changeset
   333
        if prefix.startswith('/'):
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18258
diff changeset
   334
            prefix = prefix[1:]
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18258
diff changeset
   335
        if prefix.endswith('/'):
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18258
diff changeset
   336
            prefix = prefix[:-1]
bf8bbbf4aa45 hgwebdir: use web.prefix when creating url breadcrumbs (issue3790)
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18258
diff changeset
   337
        self.prefix = prefix
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   338
        self.lastrefresh = time.time()
941
4cf418c2a013 Add a multi-repository server
mpm@selenic.com
parents: 939
diff changeset
   339
2535
b8ccf6386db7 Arrange for old copies of CGI scripts to still work.
Eric Hopper <hopper@omnifarious.org>
parents: 2514
diff changeset
   340
    def run(self):
30641
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30564
diff changeset
   341
        if not encoding.environ.get('GATEWAY_INTERFACE',
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30564
diff changeset
   342
                                    '').startswith("CGI/1."):
8663
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8621
diff changeset
   343
            raise RuntimeError("This function is only intended to be "
45f626a39def wrap string literals in error messages
Martin Geisler <mg@lazybytes.net>
parents: 8621
diff changeset
   344
                               "called while running as a CGI script.")
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
   345
        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
   346
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
   347
    def __call__(self, env, respond):
36906
219b23359f4c hgweb: support constructing URLs from an alternate base URL
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36903
diff changeset
   348
        baseurl = self.ui.config('web', 'baseurl')
36917
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36914
diff changeset
   349
        req = requestmod.parserequestfromenv(env, altbaseurl=baseurl)
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36914
diff changeset
   350
        res = requestmod.wsgiresponse(req, respond)
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   351
36917
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36914
diff changeset
   352
        return self.run_wsgi(req, res)
7336
2dc868712dcc hgweb: support for deny_read/allow_read options
Mark Edgington <edgimar@gmail.com>
parents: 7225
diff changeset
   353
36917
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36914
diff changeset
   354
    def run_wsgi(self, req, res):
32808
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
   355
        profile = self.ui.configbool('profiling', 'enabled')
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32004
diff changeset
   356
        with profiling.profile(self.ui, enabled=profile):
35854
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   357
            try:
36984
c479692690ef merge with stable
Augie Fackler <augie@google.com>
parents: 36926 35854
diff changeset
   358
                for r in self._runwsgi(req, res):
35854
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   359
                    yield r
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   360
            finally:
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   361
                # There are known cycles in localrepository that prevent
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   362
                # those objects (and tons of held references) from being
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   363
                # collected through normal refcounting. We mitigate those
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   364
                # leaks by performing an explicit GC on every request.
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   365
                # TODO remove this once leaks are fixed.
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   366
                # TODO only run this on requests that create localrepository
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   367
                # instances instead of every request.
ff2370a70fe8 hgweb: garbage collect on every request
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34703
diff changeset
   368
                gc.collect()
29797
fc2442492606 hgweb: abstract call to hgwebdir wsgi function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29471
diff changeset
   369
36917
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36914
diff changeset
   370
    def _runwsgi(self, req, res):
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   371
        try:
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   372
            self.refresh()
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   373
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   374
            csp, nonce = cspvalues(self.ui)
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   375
            if csp:
36879
98baf8dea553 hgweb: port static file handling to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36871
diff changeset
   376
                res.headers['Content-Security-Policy'] = csp
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   377
36909
803e0fc0cc9a hgweb: replace PATH_INFO with dispatchpath
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36908
diff changeset
   378
            virtual = req.dispatchpath.strip('/')
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   379
            tmpl = self.templater(req, nonce)
36992
de117f579431 templater: factor out helper that renders named template as string
Yuya Nishihara <yuya@tcha.org>
parents: 36984
diff changeset
   380
            ctype = tmpl.render('mimetype', {'encoding': encoding.encoding})
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5603
diff changeset
   381
36879
98baf8dea553 hgweb: port static file handling to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36871
diff changeset
   382
            # Global defaults. These can be overridden by any handler.
98baf8dea553 hgweb: port static file handling to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36871
diff changeset
   383
            res.status = '200 Script output follows'
98baf8dea553 hgweb: port static file handling to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36871
diff changeset
   384
            res.headers['Content-Type'] = ctype
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5603
diff changeset
   385
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   386
            # a static file
36871
3d60a22e27f5 hgweb: perform all parameter lookup via qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   387
            if virtual.startswith('static/') or 'static' in req.qsparams:
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   388
                if virtual.startswith('static/'):
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   389
                    fname = virtual[7:]
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   390
                else:
36871
3d60a22e27f5 hgweb: perform all parameter lookup via qsparams
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36869
diff changeset
   391
                    fname = req.qsparams['static']
39809
536f22d6c2c5 hgweb: register web.static to the config table
Yuya Nishihara <yuya@tcha.org>
parents: 38967
diff changeset
   392
                static = self.ui.config("web", "static", untrusted=False)
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   393
                if not static:
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   394
                    tp = self.templatepath or templater.templatepaths()
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   395
                    if isinstance(tp, str):
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   396
                        tp = [tp]
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   397
                    static = [os.path.join(p, 'static') for p in tp]
36879
98baf8dea553 hgweb: port static file handling to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36871
diff changeset
   398
98baf8dea553 hgweb: port static file handling to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36871
diff changeset
   399
                staticfile(static, fname, res)
98baf8dea553 hgweb: port static file handling to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36871
diff changeset
   400
                return res.sendresponse()
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   401
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   402
            # top-level index
31489
da7d19324b1e hgwebdir: add support for explicit index files
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
   403
da7d19324b1e hgwebdir: add support for explicit index files
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
   404
            repos = dict(self.repos)
da7d19324b1e hgwebdir: add support for explicit index files
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
   405
32004
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   406
            if (not virtual or virtual == 'index') and virtual not in repos:
36911
93717f082af9 hgweb: use modern response type for index generation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36910
diff changeset
   407
                return self.makeindex(req, res, tmpl)
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   408
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   409
            # nested indexes and hgwebs
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6046
diff changeset
   410
31489
da7d19324b1e hgwebdir: add support for explicit index files
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
   411
            if virtual.endswith('/index') and virtual not in repos:
da7d19324b1e hgwebdir: add support for explicit index files
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
   412
                subdir = virtual[:-len('index')]
da7d19324b1e hgwebdir: add support for explicit index files
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
   413
                if any(r.startswith(subdir) for r in repos):
36911
93717f082af9 hgweb: use modern response type for index generation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36910
diff changeset
   414
                    return self.makeindex(req, res, tmpl, subdir)
31489
da7d19324b1e hgwebdir: add support for explicit index files
Matt Harbison <matt_harbison@yahoo.com>
parents: 30766
diff changeset
   415
32004
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   416
            def _virtualdirs():
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   417
                # Check the full virtual path, each parent, and the root ('')
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   418
                if virtual != '':
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   419
                    yield virtual
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   420
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   421
                    for p in util.finddirs(virtual):
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   422
                        yield p
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   423
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   424
                yield ''
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   425
bd3cb917761a hgwebdir: allow a repository to be hosted at "/"
Matt Harbison <matt_harbison@yahoo.com>
parents: 31489
diff changeset
   426
            for virtualrepo in _virtualdirs():
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   427
                real = repos.get(virtualrepo)
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   428
                if real:
36903
d7fd203e36cc hgweb: refactor repository name URL parsing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36901
diff changeset
   429
                    # Re-parse the WSGI environment to take into account our
d7fd203e36cc hgweb: refactor repository name URL parsing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36901
diff changeset
   430
                    # repository path component.
37712
a728e3695325 hgwebdir: un-bytes the env dict before re-parsing env
Augie Fackler <augie@google.com>
parents: 37515
diff changeset
   431
                    uenv = req.rawenv
a728e3695325 hgwebdir: un-bytes the env dict before re-parsing env
Augie Fackler <augie@google.com>
parents: 37515
diff changeset
   432
                    if pycompat.ispy3:
a728e3695325 hgwebdir: un-bytes the env dict before re-parsing env
Augie Fackler <augie@google.com>
parents: 37515
diff changeset
   433
                        uenv = {k.decode('latin1'): v for k, v in
a728e3695325 hgwebdir: un-bytes the env dict before re-parsing env
Augie Fackler <augie@google.com>
parents: 37515
diff changeset
   434
                                uenv.iteritems()}
36917
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36914
diff changeset
   435
                    req = requestmod.parserequestfromenv(
37712
a728e3695325 hgwebdir: un-bytes the env dict before re-parsing env
Augie Fackler <augie@google.com>
parents: 37515
diff changeset
   436
                        uenv, reponame=virtualrepo,
37818
877185de62cf hgweb: reuse body file object when hgwebdir calls hgweb (issue5851)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37712
diff changeset
   437
                        altbaseurl=self.ui.config('web', 'baseurl'),
877185de62cf hgweb: reuse body file object when hgwebdir calls hgweb (issue5851)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37712
diff changeset
   438
                        # Reuse wrapped body file object otherwise state
877185de62cf hgweb: reuse body file object when hgwebdir calls hgweb (issue5851)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37712
diff changeset
   439
                        # tracking can get confused.
877185de62cf hgweb: reuse body file object when hgwebdir calls hgweb (issue5851)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37712
diff changeset
   440
                        bodyfh=req.bodyfh)
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   441
                    try:
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   442
                        # ensure caller gets private copy of ui
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   443
                        repo = hg.repository(self.ui.copy(), real)
36917
f0a851542a05 hgweb: remove wsgirequest (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36914
diff changeset
   444
                        return hgweb_mod.hgweb(repo).run_wsgi(req, res)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25488
diff changeset
   445
                    except IOError as inst:
34040
d5b2beca16c0 python3: wrap all uses of <exception>.strerror with strtolocal
Augie Fackler <raf@durin42.com>
parents: 33328
diff changeset
   446
                        msg = encoding.strtolocal(inst.strerror)
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   447
                        raise ErrorResponse(HTTP_SERVER_ERROR, msg)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25488
diff changeset
   448
                    except error.RepoError as inst:
34359
8cbcee0b923d py3: remove use of str() in hgwebdir
Yuya Nishihara <yuya@tcha.org>
parents: 34264
diff changeset
   449
                        raise ErrorResponse(HTTP_SERVER_ERROR, bytes(inst))
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   450
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   451
            # browse subdirectories
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   452
            subdir = virtual + '/'
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   453
            if [r for r in repos if r.startswith(subdir)]:
36911
93717f082af9 hgweb: use modern response type for index generation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36910
diff changeset
   454
                return self.makeindex(req, res, tmpl, subdir)
5603
74f65f44a9aa hgwebdir: refactor inner loop
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5602
diff changeset
   455
25083
ef36536abea3 hgweb: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 22634
diff changeset
   456
            # prefixes not found
36913
c1de7efca574 hgweb: port to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36912
diff changeset
   457
            res.status = '404 Not Found'
37022
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   458
            res.setbodygen(tmpl.generate('notfound', {'repo': virtual}))
36913
c1de7efca574 hgweb: port to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36912
diff changeset
   459
            return res.sendresponse()
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5603
diff changeset
   460
36913
c1de7efca574 hgweb: port to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36912
diff changeset
   461
        except ErrorResponse as e:
c1de7efca574 hgweb: port to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36912
diff changeset
   462
            res.status = statusmessage(e.code, pycompat.bytestr(e))
37022
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   463
            res.setbodygen(tmpl.generate('error', {'error': e.message or ''}))
36913
c1de7efca574 hgweb: port to new response API
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36912
diff changeset
   464
            return res.sendresponse()
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   465
        finally:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   466
            tmpl = None
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   467
36911
93717f082af9 hgweb: use modern response type for index generation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36910
diff changeset
   468
    def makeindex(self, req, res, tmpl, subdir=""):
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   469
        self.refresh()
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   470
        sortable = ["name", "description", "contact", "lastchange"]
36899
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   471
        sortcolumn, descending = None, False
36895
fc4e31297ffb hgweb: remove some use of wsgireq in hgwebdir
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36894
diff changeset
   472
        if 'sort' in req.qsparams:
fc4e31297ffb hgweb: remove some use of wsgireq in hgwebdir
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36894
diff changeset
   473
            sortcolumn = req.qsparams['sort']
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   474
            descending = sortcolumn.startswith('-')
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   475
            if descending:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   476
                sortcolumn = sortcolumn[1:]
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   477
            if sortcolumn not in sortable:
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   478
                sortcolumn = ""
4841
9b0ebb5e0f94 hgweb: let hgwebdir browse subdirectories
Brendan Cully <brendan@kublai.com>
parents: 4709
diff changeset
   479
5601
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   480
        sort = [("sort_%s" % column,
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   481
                 "%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
   482
                            and "-" or "", column))
8279cb841467 hgwebdir: split out makeindex function, facilitate test failure diagnosis
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5585
diff changeset
   483
                for column in sortable]
5928
3340aa5a64f7 hgweb: move HTTP content types out of header templates
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5915
diff changeset
   484
8371
1bd0fdf4c1ec hgwebdir: refresh configuration periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 8360
diff changeset
   485
        self.refresh()
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   486
36910
092ab4ba7ee5 hgweb: don't pass wsgireq to makeindex and other functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36909
diff changeset
   487
        entries = indexentries(self.ui, self.repos, req,
36899
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   488
                               self.stripecount, sortcolumn=sortcolumn,
455918512ed2 hgweb: extract entries() to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36898
diff changeset
   489
                               descending=descending, subdir=subdir)
6221
2eb18c780287 Support web.baseurl in hgwebdir, overriding SCRIPT_NAME
Brendan Cully <brendan@kublai.com>
parents: 6217
diff changeset
   490
37022
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   491
        mapping = {
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   492
            'entries': entries,
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   493
            'subdir': subdir,
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   494
            'pathdef': hgweb_mod.makebreadcrumb('/' + subdir, self.prefix),
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   495
            'sortcolumn': sortcolumn,
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   496
            'descending': descending,
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   497
        }
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   498
        mapping.update(sort)
c97b936d8bb5 templater: use named function to expand template against mapping dict (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36992
diff changeset
   499
        res.setbodygen(tmpl.generate('index', mapping))
36911
93717f082af9 hgweb: use modern response type for index generation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36910
diff changeset
   500
        return res.sendresponse()
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   501
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   502
    def templater(self, req, nonce):
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   503
34233
cf08aaaea7f0 web: use '_unset' default value for proxy config method
Boris Feld <boris.feld@octobus.net>
parents: 34146
diff changeset
   504
        def config(section, name, default=uimod._unset, untrusted=True):
8191
35604226d712 hgweb: kill parentui references
Matt Mackall <mpm@selenic.com>
parents: 8190
diff changeset
   505
            return self.ui.config(section, name, default, untrusted)
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   506
8216
25266fe996b0 hgweb: use new sessionvars code in hgwebdir, too
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8215
diff changeset
   507
        vars = {}
34515
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34486
diff changeset
   508
        styles, (style, mapfile) = hgweb_mod.getstyle(req, config,
8afc25e7effc hgweb: extract function for loading style from request context
Augie Fackler <augie@google.com>
parents: 34486
diff changeset
   509
                                                      self.templatepath)
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9724
diff changeset
   510
        if style == styles[0]:
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9724
diff changeset
   511
            vars['style'] = style
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
   512
36813
ec46415ed826 hgweb: always use "?" when writing session vars
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36812
diff changeset
   513
        sessionvars = webutil.sessionvars(vars, r'?')
34612
c2cb6be4212f configitems: register the 'web.logourl' config
Boris Feld <boris.feld@octobus.net>
parents: 34611
diff changeset
   514
        logourl = config('web', 'logourl')
34611
c879fc7bd71f configitems: register the 'web.logoimg' config
Boris Feld <boris.feld@octobus.net>
parents: 34587
diff changeset
   515
        logoimg = config('web', 'logoimg')
36901
a5c478843c82 hgweb: construct static URL like hgweb does
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36900
diff changeset
   516
        staticurl = (config('web', 'staticurl')
38745
258d90f69076 hgweb: strip trailing '/' in apppath before appending '/static/' (issue5943)
Cédric Krier <ced@b2ck.com>
parents: 37818
diff changeset
   517
                     or req.apppath.rstrip('/') + '/static/')
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   518
        if not staticurl.endswith('/'):
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   519
            staticurl += '/'
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   520
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   521
        defaults = {
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   522
            "encoding": encoding.encoding,
36912
6a0e4efbc61e hgweb: pass modern request type into templater()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36911
diff changeset
   523
            "url": req.apppath + '/',
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   524
            "logourl": logourl,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   525
            "logoimg": logoimg,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   526
            "staticurl": staticurl,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   527
            "sessionvars": sessionvars,
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   528
            "style": style,
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30749
diff changeset
   529
            "nonce": nonce,
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   530
        }
38967
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   531
        templatekeyword = registrar.templatekeyword(defaults)
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   532
        @templatekeyword('motd', requires=())
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   533
        def motd(context, mapping):
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   534
            if self.motd is not None:
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   535
                yield self.motd
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   536
            else:
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   537
                yield config('web', 'motd')
4167437a45dd hgweb: use registrar to add "motd" template keyword
Yuya Nishihara <yuya@tcha.org>
parents: 38745
diff changeset
   538
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 27046
diff changeset
   539
        tmpl = templater.templater.frommapfile(mapfile, defaults=defaults)
5602
d676d0f35bd8 hgwebdir: split out templater creation
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5601
diff changeset
   540
        return tmpl