##// END OF EJS Templates
Keep session variables when linking from hgwebdir's index to repositories.
Thomas Arendsen Hein -
r3365:cf680c9a default
parent child Browse files
Show More
@@ -1,192 +1,205
1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
5 #
5 #
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.demandload import demandload
10 from mercurial.demandload import demandload
11 demandload(globals(), "ConfigParser mimetools cStringIO")
11 demandload(globals(), "ConfigParser mimetools cStringIO")
12 demandload(globals(), "mercurial:ui,hg,util,templater")
12 demandload(globals(), "mercurial:ui,hg,util,templater")
13 demandload(globals(), "mercurial.hgweb.hgweb_mod:hgweb")
13 demandload(globals(), "mercurial.hgweb.hgweb_mod:hgweb")
14 demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile,style_map")
14 demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile,style_map")
15 from mercurial.i18n import gettext as _
15 from mercurial.i18n import gettext as _
16
16
17 # This is a stopgap
17 # This is a stopgap
18 class hgwebdir(object):
18 class hgwebdir(object):
19 def __init__(self, config):
19 def __init__(self, config):
20 def cleannames(items):
20 def cleannames(items):
21 return [(name.strip(os.sep), path) for name, path in items]
21 return [(name.strip(os.sep), path) for name, path in items]
22
22
23 self.motd = ""
23 self.motd = ""
24 self.style = ""
24 self.style = ""
25 self.repos_sorted = ('name', False)
25 self.repos_sorted = ('name', False)
26 if isinstance(config, (list, tuple)):
26 if isinstance(config, (list, tuple)):
27 self.repos = cleannames(config)
27 self.repos = cleannames(config)
28 self.repos_sorted = ('', False)
28 self.repos_sorted = ('', False)
29 elif isinstance(config, dict):
29 elif isinstance(config, dict):
30 self.repos = cleannames(config.items())
30 self.repos = cleannames(config.items())
31 self.repos.sort()
31 self.repos.sort()
32 else:
32 else:
33 cp = ConfigParser.SafeConfigParser()
33 cp = ConfigParser.SafeConfigParser()
34 cp.read(config)
34 cp.read(config)
35 self.repos = []
35 self.repos = []
36 if cp.has_section('web'):
36 if cp.has_section('web'):
37 if cp.has_option('web', 'motd'):
37 if cp.has_option('web', 'motd'):
38 self.motd = cp.get('web', 'motd')
38 self.motd = cp.get('web', 'motd')
39 if cp.has_option('web', 'style'):
39 if cp.has_option('web', 'style'):
40 self.style = cp.get('web', 'style')
40 self.style = cp.get('web', 'style')
41 if cp.has_section('paths'):
41 if cp.has_section('paths'):
42 self.repos.extend(cleannames(cp.items('paths')))
42 self.repos.extend(cleannames(cp.items('paths')))
43 if cp.has_section('collections'):
43 if cp.has_section('collections'):
44 for prefix, root in cp.items('collections'):
44 for prefix, root in cp.items('collections'):
45 for path in util.walkrepos(root):
45 for path in util.walkrepos(root):
46 repo = os.path.normpath(path)
46 repo = os.path.normpath(path)
47 name = repo
47 name = repo
48 if name.startswith(prefix):
48 if name.startswith(prefix):
49 name = name[len(prefix):]
49 name = name[len(prefix):]
50 self.repos.append((name.lstrip(os.sep), repo))
50 self.repos.append((name.lstrip(os.sep), repo))
51 self.repos.sort()
51 self.repos.sort()
52
52
53 def run(self):
53 def run(self):
54 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
54 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
55 raise RuntimeError("This function is only intended to be called while running as a CGI script.")
55 raise RuntimeError("This function is only intended to be called while running as a CGI script.")
56 import mercurial.hgweb.wsgicgi as wsgicgi
56 import mercurial.hgweb.wsgicgi as wsgicgi
57 from request import wsgiapplication
57 from request import wsgiapplication
58 def make_web_app():
58 def make_web_app():
59 return self
59 return self
60 wsgicgi.launch(wsgiapplication(make_web_app))
60 wsgicgi.launch(wsgiapplication(make_web_app))
61
61
62 def run_wsgi(self, req):
62 def run_wsgi(self, req):
63 def header(**map):
63 def header(**map):
64 header_file = cStringIO.StringIO(''.join(tmpl("header", **map)))
64 header_file = cStringIO.StringIO(''.join(tmpl("header", **map)))
65 msg = mimetools.Message(header_file, 0)
65 msg = mimetools.Message(header_file, 0)
66 req.header(msg.items())
66 req.header(msg.items())
67 yield header_file.read()
67 yield header_file.read()
68
68
69 def footer(**map):
69 def footer(**map):
70 yield tmpl("footer", motd=self.motd, **map)
70 yield tmpl("footer", motd=self.motd, **map)
71
71
72 url = req.env['REQUEST_URI'].split('?')[0]
72 url = req.env['REQUEST_URI'].split('?')[0]
73 if not url.endswith('/'):
73 if not url.endswith('/'):
74 url += '/'
74 url += '/'
75
75
76 style = self.style
76 style = self.style
77 if req.form.has_key('style'):
77 if req.form.has_key('style'):
78 style = req.form['style'][0]
78 style = req.form['style'][0]
79 mapfile = style_map(templater.templatepath(), style)
79 mapfile = style_map(templater.templatepath(), style)
80 tmpl = templater.templater(mapfile, templater.common_filters,
80 tmpl = templater.templater(mapfile, templater.common_filters,
81 defaults={"header": header,
81 defaults={"header": header,
82 "footer": footer,
82 "footer": footer,
83 "url": url})
83 "url": url})
84
84
85 def archivelist(ui, nodeid, url):
85 def archivelist(ui, nodeid, url):
86 allowed = ui.configlist("web", "allow_archive")
86 allowed = ui.configlist("web", "allow_archive")
87 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
87 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
88 if i[0] in allowed or ui.configbool("web", "allow" + i[0]):
88 if i[0] in allowed or ui.configbool("web", "allow" + i[0]):
89 yield {"type" : i[0], "extension": i[1],
89 yield {"type" : i[0], "extension": i[1],
90 "node": nodeid, "url": url}
90 "node": nodeid, "url": url}
91
91
92 def entries(sortcolumn="", descending=False, **map):
92 def entries(sortcolumn="", descending=False, **map):
93 def sessionvars(**map):
94 fields = []
95 if req.form.has_key('style'):
96 style = req.form['style'][0]
97 if style != get('web', 'style', ''):
98 fields.append(('style', style))
99
100 separator = url[-1] == '?' and ';' or '?'
101 for name, value in fields:
102 yield dict(name=name, value=value, separator=separator)
103 separator = ';'
104
93 rows = []
105 rows = []
94 parity = 0
106 parity = 0
95 for name, path in self.repos:
107 for name, path in self.repos:
96 u = ui.ui()
108 u = ui.ui()
97 try:
109 try:
98 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
110 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
99 except IOError:
111 except IOError:
100 pass
112 pass
101 get = u.config
113 get = u.config
102
114
103 url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name])
115 url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name])
104 .replace("//", "/")) + '/'
116 .replace("//", "/")) + '/'
105
117
106 # update time with local timezone
118 # update time with local timezone
107 try:
119 try:
108 d = (get_mtime(path), util.makedate()[1])
120 d = (get_mtime(path), util.makedate()[1])
109 except OSError:
121 except OSError:
110 continue
122 continue
111
123
112 contact = (get("ui", "username") or # preferred
124 contact = (get("ui", "username") or # preferred
113 get("web", "contact") or # deprecated
125 get("web", "contact") or # deprecated
114 get("web", "author", "")) # also
126 get("web", "author", "")) # also
115 description = get("web", "description", "")
127 description = get("web", "description", "")
116 name = get("web", "name", name)
128 name = get("web", "name", name)
117 row = dict(contact=contact or "unknown",
129 row = dict(contact=contact or "unknown",
118 contact_sort=contact.upper() or "unknown",
130 contact_sort=contact.upper() or "unknown",
119 name=name,
131 name=name,
120 name_sort=name,
132 name_sort=name,
121 url=url,
133 url=url,
122 description=description or "unknown",
134 description=description or "unknown",
123 description_sort=description.upper() or "unknown",
135 description_sort=description.upper() or "unknown",
124 lastchange=d,
136 lastchange=d,
125 lastchange_sort=d[1]-d[0],
137 lastchange_sort=d[1]-d[0],
138 sessionvars=sessionvars,
126 archives=archivelist(u, "tip", url))
139 archives=archivelist(u, "tip", url))
127 if (not sortcolumn
140 if (not sortcolumn
128 or (sortcolumn, descending) == self.repos_sorted):
141 or (sortcolumn, descending) == self.repos_sorted):
129 # fast path for unsorted output
142 # fast path for unsorted output
130 row['parity'] = parity
143 row['parity'] = parity
131 parity = 1 - parity
144 parity = 1 - parity
132 yield row
145 yield row
133 else:
146 else:
134 rows.append((row["%s_sort" % sortcolumn], row))
147 rows.append((row["%s_sort" % sortcolumn], row))
135 if rows:
148 if rows:
136 rows.sort()
149 rows.sort()
137 if descending:
150 if descending:
138 rows.reverse()
151 rows.reverse()
139 for key, row in rows:
152 for key, row in rows:
140 row['parity'] = parity
153 row['parity'] = parity
141 parity = 1 - parity
154 parity = 1 - parity
142 yield row
155 yield row
143
156
144 virtual = req.env.get("PATH_INFO", "").strip('/')
157 virtual = req.env.get("PATH_INFO", "").strip('/')
145 if virtual.startswith('static/'):
158 if virtual.startswith('static/'):
146 static = os.path.join(templater.templatepath(), 'static')
159 static = os.path.join(templater.templatepath(), 'static')
147 fname = virtual[7:]
160 fname = virtual[7:]
148 req.write(staticfile(static, fname, req) or
161 req.write(staticfile(static, fname, req) or
149 tmpl('error', error='%r not found' % fname))
162 tmpl('error', error='%r not found' % fname))
150 elif virtual:
163 elif virtual:
151 while virtual:
164 while virtual:
152 real = dict(self.repos).get(virtual)
165 real = dict(self.repos).get(virtual)
153 if real:
166 if real:
154 break
167 break
155 up = virtual.rfind('/')
168 up = virtual.rfind('/')
156 if up < 0:
169 if up < 0:
157 break
170 break
158 virtual = virtual[:up]
171 virtual = virtual[:up]
159 if real:
172 if real:
160 req.env['REPO_NAME'] = virtual
173 req.env['REPO_NAME'] = virtual
161 try:
174 try:
162 hgweb(real).run_wsgi(req)
175 hgweb(real).run_wsgi(req)
163 except IOError, inst:
176 except IOError, inst:
164 req.write(tmpl("error", error=inst.strerror))
177 req.write(tmpl("error", error=inst.strerror))
165 except hg.RepoError, inst:
178 except hg.RepoError, inst:
166 req.write(tmpl("error", error=str(inst)))
179 req.write(tmpl("error", error=str(inst)))
167 else:
180 else:
168 req.write(tmpl("notfound", repo=virtual))
181 req.write(tmpl("notfound", repo=virtual))
169 else:
182 else:
170 if req.form.has_key('static'):
183 if req.form.has_key('static'):
171 static = os.path.join(templater.templatepath(), "static")
184 static = os.path.join(templater.templatepath(), "static")
172 fname = req.form['static'][0]
185 fname = req.form['static'][0]
173 req.write(staticfile(static, fname, req)
186 req.write(staticfile(static, fname, req)
174 or tmpl("error", error="%r not found" % fname))
187 or tmpl("error", error="%r not found" % fname))
175 else:
188 else:
176 sortable = ["name", "description", "contact", "lastchange"]
189 sortable = ["name", "description", "contact", "lastchange"]
177 sortcolumn, descending = self.repos_sorted
190 sortcolumn, descending = self.repos_sorted
178 if req.form.has_key('sort'):
191 if req.form.has_key('sort'):
179 sortcolumn = req.form['sort'][0]
192 sortcolumn = req.form['sort'][0]
180 descending = sortcolumn.startswith('-')
193 descending = sortcolumn.startswith('-')
181 if descending:
194 if descending:
182 sortcolumn = sortcolumn[1:]
195 sortcolumn = sortcolumn[1:]
183 if sortcolumn not in sortable:
196 if sortcolumn not in sortable:
184 sortcolumn = ""
197 sortcolumn = ""
185
198
186 sort = [("sort_%s" % column,
199 sort = [("sort_%s" % column,
187 "%s%s" % ((not descending and column == sortcolumn)
200 "%s%s" % ((not descending and column == sortcolumn)
188 and "-" or "", column))
201 and "-" or "", column))
189 for column in sortable]
202 for column in sortable]
190 req.write(tmpl("index", entries=entries,
203 req.write(tmpl("index", entries=entries,
191 sortcolumn=sortcolumn, descending=descending,
204 sortcolumn=sortcolumn, descending=descending,
192 **dict(sort)))
205 **dict(sort)))
@@ -1,55 +1,55
1 default = 'summary'
1 default = 'summary'
2 header = header.tmpl
2 header = header.tmpl
3 footer = footer.tmpl
3 footer = footer.tmpl
4 search = search.tmpl
4 search = search.tmpl
5 changelog = changelog.tmpl
5 changelog = changelog.tmpl
6 summary = summary.tmpl
6 summary = summary.tmpl
7 error = error.tmpl
7 error = error.tmpl
8 naventry = '<a href="#url#log/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
8 naventry = '<a href="#url#log/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
9 navshortentry = '<a href="#url#shortlog/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
9 navshortentry = '<a href="#url#shortlog/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
10 filedifflink = '<a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
10 filedifflink = '<a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
11 filenodelink = '<tr class="parity#parity#"><td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">#file|escape#</a></td><td></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> | <a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a></td></tr>'
11 filenodelink = '<tr class="parity#parity#"><td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">#file|escape#</a></td><td></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> | <a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a></td></tr>'
12 fileellipses = '...'
12 fileellipses = '...'
13 changelogentry = changelogentry.tmpl
13 changelogentry = changelogentry.tmpl
14 searchentry = changelogentry.tmpl
14 searchentry = changelogentry.tmpl
15 changeset = changeset.tmpl
15 changeset = changeset.tmpl
16 manifest = manifest.tmpl
16 manifest = manifest.tmpl
17 manifestdirentry = '<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td style="font-family:monospace"></td><td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a></td><td class="link"><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">manifest</a></td></tr>'
17 manifestdirentry = '<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td style="font-family:monospace"></td><td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a></td><td class="link"><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">manifest</a></td></tr>'
18 manifestfileentry = '<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td style="font-family:monospace" align=right>#size#</td><td class="list"><a class="list" href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a></td></tr>'
18 manifestfileentry = '<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td style="font-family:monospace" align=right>#size#</td><td class="list"><a class="list" href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a></td></tr>'
19 filerevision = filerevision.tmpl
19 filerevision = filerevision.tmpl
20 fileannotate = fileannotate.tmpl
20 fileannotate = fileannotate.tmpl
21 filediff = filediff.tmpl
21 filediff = filediff.tmpl
22 filelog = filelog.tmpl
22 filelog = filelog.tmpl
23 fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><span class="linenr"> #linenumber#</span> #line|escape#</pre></div>'
23 fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><span class="linenr"> #linenumber#</span> #line|escape#</pre></div>'
24 annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
24 annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
25 difflineplus = '<div style="color:#008800;">#line|escape#</div>'
25 difflineplus = '<div style="color:#008800;">#line|escape#</div>'
26 difflineminus = '<div style="color:#cc0000;">#line|escape#</div>'
26 difflineminus = '<div style="color:#cc0000;">#line|escape#</div>'
27 difflineat = '<div style="color:#990099;">#line|escape#</div>'
27 difflineat = '<div style="color:#990099;">#line|escape#</div>'
28 diffline = '<div>#line|escape#</div>'
28 diffline = '<div>#line|escape#</div>'
29 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
29 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
30 changesetparent = '<tr><td>parent</td><td style="font-family:monospace"><a class="list" href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
30 changesetparent = '<tr><td>parent</td><td style="font-family:monospace"><a class="list" href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
31 filerevparent = '<tr><td class="metatag">parent:</td><td><a href="{url}file/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
31 filerevparent = '<tr><td class="metatag">parent:</td><td><a href="{url}file/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
32 filerename = '<tr><td class="metatag">parent:</td><td><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#@#node|short#</a></td></tr>'
32 filerename = '<tr><td class="metatag">parent:</td><td><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#@#node|short#</a></td></tr>'
33 filelogrename = '| <a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">base</a>'
33 filelogrename = '| <a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">base</a>'
34 fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="{url}annotate/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
34 fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="{url}annotate/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
35 changelogchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
35 changelogchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
36 changesetchild = '<tr><td>child</td><td style="font-family:monospace"><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
36 changesetchild = '<tr><td>child</td><td style="font-family:monospace"><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
37 filerevchild = '<tr><td class="metatag">child:</td><td><a href="{url}file/{node|short}#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
37 filerevchild = '<tr><td class="metatag">child:</td><td><a href="{url}file/{node|short}#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
38 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="{url}annotate/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
38 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="{url}annotate/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
39 tags = tags.tmpl
39 tags = tags.tmpl
40 tagentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>#tag|escape#</b></a></td><td class="link"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}log/#node|short#{sessionvars%urlparameter}">changelog</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">manifest</a></td></tr>'
40 tagentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>#tag|escape#</b></a></td><td class="link"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}log/#node|short#{sessionvars%urlparameter}">changelog</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">manifest</a></td></tr>'
41 diffblock = '<pre>#lines#</pre>'
41 diffblock = '<pre>#lines#</pre>'
42 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
42 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
43 changesettag = '<tr><td>tag</td><td>#tag|escape#</td></tr>'
43 changesettag = '<tr><td>tag</td><td>#tag|escape#</td></tr>'
44 filediffparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
44 filediffparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
45 filelogparent = '<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="{url}file/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
45 filelogparent = '<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="{url}file/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
46 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
46 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
47 filelogchild = '<tr><td align="right">child #rev#:&nbsp;</td><td><a href="{url}file{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
47 filelogchild = '<tr><td align="right">child #rev#:&nbsp;</td><td><a href="{url}file{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
48 shortlog = shortlog.tmpl
48 shortlog = shortlog.tmpl
49 shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author#</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">manifest</a></td></tr>'
49 shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author#</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">manifest</a></td></tr>'
50 filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <!-- FIXME: <a href="{url}diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a> | --> <a href="{url}annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> #rename%filelogrename#</td></tr>'
50 filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <!-- FIXME: <a href="{url}diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a> | --> <a href="{url}annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> #rename%filelogrename#</td></tr>'
51 archiveentry = ' | <a href="{url}archive/{node|short}{extension}">#type|escape#</a> '
51 archiveentry = ' | <a href="{url}archive/{node|short}{extension}">#type|escape#</a> '
52 indexentry = '<tr class="parity#parity#"><td><a class="list" href="#url#"><b>#name|escape#</b></a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a class="rss_logo" href="#url#rss-log">RSS</a> #archives%archiveentry#</td></tr>'
52 indexentry = '<tr class="parity#parity#"><td><a class="list" href="#url#{sessionvars%urlparameter}"><b>#name|escape#</b></a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a class="rss_logo" href="#url#rss-log">RSS</a> #archives%archiveentry#</td></tr>'
53 index = index.tmpl
53 index = index.tmpl
54 urlparameter = '#separator##name#=#value|urlescape#'
54 urlparameter = '#separator##name#=#value|urlescape#'
55 hiddenformentry = '<input type="hidden" name="#name#" value="#value|escape#" />'
55 hiddenformentry = '<input type="hidden" name="#name#" value="#value|escape#" />'
@@ -1,55 +1,55
1 default = 'changelog'
1 default = 'changelog'
2 header = header.tmpl
2 header = header.tmpl
3 footer = footer.tmpl
3 footer = footer.tmpl
4 search = search.tmpl
4 search = search.tmpl
5 changelog = changelog.tmpl
5 changelog = changelog.tmpl
6 shortlog = shortlog.tmpl
6 shortlog = shortlog.tmpl
7 shortlogentry = shortlogentry.tmpl
7 shortlogentry = shortlogentry.tmpl
8 naventry = '<a href="#url#log/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
8 naventry = '<a href="#url#log/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
9 navshortentry = '<a href="#url#shortlog/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
9 navshortentry = '<a href="#url#shortlog/#rev#{sessionvars%urlparameter}">#label|escape#</a> '
10 filedifflink = '<a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
10 filedifflink = '<a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
11 filenodelink = '<a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
11 filenodelink = '<a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
12 fileellipses = '...'
12 fileellipses = '...'
13 changelogentry = changelogentry.tmpl
13 changelogentry = changelogentry.tmpl
14 searchentry = changelogentry.tmpl
14 searchentry = changelogentry.tmpl
15 changeset = changeset.tmpl
15 changeset = changeset.tmpl
16 manifest = manifest.tmpl
16 manifest = manifest.tmpl
17 manifestdirentry = '<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a>'
17 manifestdirentry = '<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a>'
18 manifestfileentry = '<tr class="parity#parity#"><td><tt>#permissions|permissions#</tt>&nbsp;<td align=right><tt>#size#</tt>&nbsp;<td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a>'
18 manifestfileentry = '<tr class="parity#parity#"><td><tt>#permissions|permissions#</tt>&nbsp;<td align=right><tt>#size#</tt>&nbsp;<td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a>'
19 filerevision = filerevision.tmpl
19 filerevision = filerevision.tmpl
20 fileannotate = fileannotate.tmpl
20 fileannotate = fileannotate.tmpl
21 filediff = filediff.tmpl
21 filediff = filediff.tmpl
22 filelog = filelog.tmpl
22 filelog = filelog.tmpl
23 fileline = '<div class="parity#parity#"><span class="lineno">#linenumber#</span>#line|escape#</div>'
23 fileline = '<div class="parity#parity#"><span class="lineno">#linenumber#</span>#line|escape#</div>'
24 filelogentry = filelogentry.tmpl
24 filelogentry = filelogentry.tmpl
25 annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
25 annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
26 difflineplus = '<span class="plusline">#line|escape#</span>'
26 difflineplus = '<span class="plusline">#line|escape#</span>'
27 difflineminus = '<span class="minusline">#line|escape#</span>'
27 difflineminus = '<span class="minusline">#line|escape#</span>'
28 difflineat = '<span class="atline">#line|escape#</span>'
28 difflineat = '<span class="atline">#line|escape#</span>'
29 diffline = '#line|escape#'
29 diffline = '#line|escape#'
30 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
30 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
31 changesetparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
31 changesetparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
32 filerevparent = '<tr><td class="metatag">parent:</td><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
32 filerevparent = '<tr><td class="metatag">parent:</td><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
33 filerename = '<tr><td class="metatag">parent:</td><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#@#node|short#</a></td></tr>'
33 filerename = '<tr><td class="metatag">parent:</td><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#@#node|short#</a></td></tr>'
34 filelogrename = '<tr><th>base:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#@#node|short#</a></td></tr>'
34 filelogrename = '<tr><th>base:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#@#node|short#</a></td></tr>'
35 fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
35 fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
36 changesetchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
36 changesetchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
37 changelogchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
37 changelogchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
38 filerevchild = '<tr><td class="metatag">child:</td><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
38 filerevchild = '<tr><td class="metatag">child:</td><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
39 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
39 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
40 tags = tags.tmpl
40 tags = tags.tmpl
41 tagentry = '<li class="tagEntry parity#parity#"><tt class="node">#node#</tt> <a href="#url#rev/#node|short#{sessionvars%urlparameter}">#tag|escape#</a></li>'
41 tagentry = '<li class="tagEntry parity#parity#"><tt class="node">#node#</tt> <a href="#url#rev/#node|short#{sessionvars%urlparameter}">#tag|escape#</a></li>'
42 diffblock = '<pre class="parity#parity#">#lines#</pre>'
42 diffblock = '<pre class="parity#parity#">#lines#</pre>'
43 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
43 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
44 changesettag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
44 changesettag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
45 filediffparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
45 filediffparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
46 filelogparent = '<tr><th>parent #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
46 filelogparent = '<tr><th>parent #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
47 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
47 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
48 filelogchild = '<tr><th>child #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
48 filelogchild = '<tr><th>child #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
49 indexentry = '<tr class="parity#parity#"><td><a href="#url#">#name|escape#</a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a href="#url#rss-log">RSS</a> #archives%archiveentry#</td></tr>'
49 indexentry = '<tr class="parity#parity#"><td><a href="#url#{sessionvars%urlparameter}">#name|escape#</a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a href="#url#rss-log">RSS</a> #archives%archiveentry#</td></tr>'
50 index = index.tmpl
50 index = index.tmpl
51 archiveentry = '<a href="#url#archive/#node|short##extension|urlescape#">#type|escape#</a> '
51 archiveentry = '<a href="#url#archive/#node|short##extension|urlescape#">#type|escape#</a> '
52 notfound = notfound.tmpl
52 notfound = notfound.tmpl
53 error = error.tmpl
53 error = error.tmpl
54 urlparameter = '#separator##name#=#value|urlescape#'
54 urlparameter = '#separator##name#=#value|urlescape#'
55 hiddenformentry = '<input type="hidden" name="#name#" value="#value|escape#" />'
55 hiddenformentry = '<input type="hidden" name="#name#" value="#value|escape#" />'
General Comments 0
You need to be logged in to leave comments. Login now