6 # This software may be used and distributed according to the terms |
6 # This software may be used and distributed according to the terms |
7 # of the GNU General Public License, incorporated herein by reference. |
7 # of the GNU General Public License, incorporated herein by reference. |
8 |
8 |
9 import os |
9 import os |
10 from mercurial.i18n import _ |
10 from mercurial.i18n import _ |
11 from mercurial import ui, hg, util, templater, templatefilters, error, encoding |
11 from mercurial import ui, hg, util, templater, templatefilters |
|
12 from mercurial import config, error, encoding |
12 from common import ErrorResponse, get_mtime, staticfile, paritygen,\ |
13 from common import ErrorResponse, get_mtime, staticfile, paritygen,\ |
13 get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
14 get_contact, HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
14 from hgweb_mod import hgweb |
15 from hgweb_mod import hgweb |
15 from request import wsgirequest |
16 from request import wsgirequest |
16 |
17 |
17 # This is a stopgap |
18 # This is a stopgap |
18 class hgwebdir(object): |
19 class hgwebdir(object): |
19 def __init__(self, config, parentui=None): |
20 def __init__(self, conf, parentui=None): |
20 def cleannames(items): |
21 def cleannames(items): |
21 return [(util.pconvert(name).strip('/'), path) |
22 return [(util.pconvert(name).strip('/'), path) |
22 for name, path in items] |
23 for name, path in items] |
23 |
24 |
24 if parentui: |
25 if parentui: |
31 self.motd = None |
32 self.motd = None |
32 self.style = 'paper' |
33 self.style = 'paper' |
33 self.stripecount = None |
34 self.stripecount = None |
34 self.repos_sorted = ('name', False) |
35 self.repos_sorted = ('name', False) |
35 self._baseurl = None |
36 self._baseurl = None |
36 if isinstance(config, (list, tuple)): |
37 if isinstance(conf, (list, tuple)): |
37 self.repos = cleannames(config) |
38 self.repos = cleannames(conf) |
38 self.repos_sorted = ('', False) |
39 self.repos_sorted = ('', False) |
39 elif isinstance(config, dict): |
40 elif isinstance(conf, dict): |
40 self.repos = util.sort(cleannames(config.items())) |
41 self.repos = util.sort(cleannames(conf.items())) |
41 else: |
42 else: |
42 if isinstance(config, util.configparser): |
43 if isinstance(conf, config.config): |
43 cp = config |
44 cp = conf |
44 else: |
45 else: |
45 cp = util.configparser() |
46 cp = config.config() |
46 cp.read(config) |
47 cp.read(conf) |
47 self.repos = [] |
48 self.repos = [] |
48 if cp.has_section('web'): |
49 self.motd = cp.get('web', 'motd') |
49 if cp.has_option('web', 'motd'): |
50 self.style = cp.get('web', 'style', 'paper') |
50 self.motd = cp.get('web', 'motd') |
51 self.stripecount = cp.get('web', 'stripes') |
51 if cp.has_option('web', 'style'): |
52 self._baseurl = cp.get('web', 'baseurl') |
52 self.style = cp.get('web', 'style') |
53 if 'paths' in cp: |
53 if cp.has_option('web', 'stripes'): |
|
54 self.stripecount = int(cp.get('web', 'stripes')) |
|
55 if cp.has_option('web', 'baseurl'): |
|
56 self._baseurl = cp.get('web', 'baseurl') |
|
57 if cp.has_section('paths'): |
|
58 paths = cleannames(cp.items('paths')) |
54 paths = cleannames(cp.items('paths')) |
59 for prefix, root in paths: |
55 for prefix, root in paths: |
60 roothead, roottail = os.path.split(root) |
56 roothead, roottail = os.path.split(root) |
61 # "foo = /bar/*" makes every subrepo of /bar/ to be |
57 # "foo = /bar/*" makes every subrepo of /bar/ to be |
62 # mounted as foo/subrepo |
58 # mounted as foo/subrepo |
73 path = os.path.normpath(path) |
69 path = os.path.normpath(path) |
74 name = util.pconvert(path[len(roothead):]).strip('/') |
70 name = util.pconvert(path[len(roothead):]).strip('/') |
75 if prefix: |
71 if prefix: |
76 name = prefix + '/' + name |
72 name = prefix + '/' + name |
77 self.repos.append((name, path)) |
73 self.repos.append((name, path)) |
78 if cp.has_section('collections'): |
74 for prefix, root in cp.items('collections'): |
79 for prefix, root in cp.items('collections'): |
75 for path in util.walkrepos(root, followsym=True): |
80 for path in util.walkrepos(root, followsym=True): |
76 repo = os.path.normpath(path) |
81 repo = os.path.normpath(path) |
77 name = repo |
82 name = repo |
78 if name.startswith(prefix): |
83 if name.startswith(prefix): |
79 name = name[len(prefix):] |
84 name = name[len(prefix):] |
80 self.repos.append((name.lstrip(os.sep), repo)) |
85 self.repos.append((name.lstrip(os.sep), repo)) |
|
86 self.repos.sort() |
81 self.repos.sort() |
87 |
82 |
88 def run(self): |
83 def run(self): |
89 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."): |
84 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."): |
90 raise RuntimeError("This function is only intended to be called while running as a CGI script.") |
85 raise RuntimeError("This function is only intended to be called while running as a CGI script.") |
318 style = self.style |
313 style = self.style |
319 if style is None: |
314 if style is None: |
320 style = config('web', 'style', '') |
315 style = config('web', 'style', '') |
321 if 'style' in req.form: |
316 if 'style' in req.form: |
322 style = req.form['style'][0] |
317 style = req.form['style'][0] |
323 if self.stripecount is None: |
318 self.stripecount = int(self.stripecount or config('web', 'stripes', 1)) |
324 self.stripecount = int(config('web', 'stripes', 1)) |
|
325 mapfile = templater.stylemap(style) |
319 mapfile = templater.stylemap(style) |
326 tmpl = templater.templater(mapfile, templatefilters.filters, |
320 tmpl = templater.templater(mapfile, templatefilters.filters, |
327 defaults={"header": header, |
321 defaults={"header": header, |
328 "footer": footer, |
322 "footer": footer, |
329 "motd": motd, |
323 "motd": motd, |