Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/hgweb/hgweb_mod.py @ 18627:4e949b8e0930
hgweb: add websub template filter
The purpose of this new filter is to make it possible to partially replace the
functionality of the interhg extension. The idea is to be able to define regular
expression based substitutions on a new "websub" config section. hgweb will then
be able to apply these substitutions wherever the "websub" filter is used on a
template.
This first revision just adds the code necessary to load the websub expressions
and adds the websub filter, but it does not add any calls to the websub filter
itself on any of the templates. That will be done on the following revisions.
author | Angel Ezquerra <angel.ezquerra@gmail.com> |
---|---|
date | Fri, 08 Feb 2013 18:05:32 +0100 |
parents | 36549fa712da |
children | 013fcd112f13 |
comparison
equal
deleted
inserted
replaced
18626:b114e41c4df3 | 18627:4e949b8e0930 |
---|---|
6 # This software may be used and distributed according to the terms of the | 6 # This software may be used and distributed according to the terms of the |
7 # GNU General Public License version 2 or any later version. | 7 # GNU General Public License version 2 or any later version. |
8 | 8 |
9 import os | 9 import os |
10 from mercurial import ui, hg, hook, error, encoding, templater, util, repoview | 10 from mercurial import ui, hg, hook, error, encoding, templater, util, repoview |
11 from mercurial.templatefilters import websub | |
12 from mercurial.i18n import _ | |
11 from common import get_stat, ErrorResponse, permhooks, caching | 13 from common import get_stat, ErrorResponse, permhooks, caching |
12 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST | 14 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST |
13 from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR | 15 from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
14 from request import wsgirequest | 16 from request import wsgirequest |
15 import webcommands, protocol, webutil | 17 import webcommands, protocol, webutil, re |
16 | 18 |
17 perms = { | 19 perms = { |
18 'changegroup': 'pull', | 20 'changegroup': 'pull', |
19 'changegroupsubset': 'pull', | 21 'changegroupsubset': 'pull', |
20 'getbundle': 'pull', | 22 'getbundle': 'pull', |
71 self.archives = 'zip', 'gz', 'bz2' | 73 self.archives = 'zip', 'gz', 'bz2' |
72 self.stripecount = 1 | 74 self.stripecount = 1 |
73 # a repo owner may set web.templates in .hg/hgrc to get any file | 75 # a repo owner may set web.templates in .hg/hgrc to get any file |
74 # readable by the user running the CGI script | 76 # readable by the user running the CGI script |
75 self.templatepath = self.config('web', 'templates') | 77 self.templatepath = self.config('web', 'templates') |
78 self.websubtable = self.loadwebsub() | |
76 | 79 |
77 # The CGI scripts are often run by a user different from the repo owner. | 80 # The CGI scripts are often run by a user different from the repo owner. |
78 # Trust the settings from the .hg/hgrc files by default. | 81 # Trust the settings from the .hg/hgrc files by default. |
79 def config(self, section, name, default=None, untrusted=True): | 82 def config(self, section, name, default=None, untrusted=True): |
80 return self.repo.ui.config(section, name, default, | 83 return self.repo.ui.config(section, name, default, |
256 if inst.code == HTTP_NOT_MODIFIED: | 259 if inst.code == HTTP_NOT_MODIFIED: |
257 # Not allowed to return a body on a 304 | 260 # Not allowed to return a body on a 304 |
258 return [''] | 261 return [''] |
259 return tmpl('error', error=inst.message) | 262 return tmpl('error', error=inst.message) |
260 | 263 |
264 def loadwebsub(self): | |
265 websubtable = [] | |
266 websubdefs = self.repo.ui.configitems('websub') | |
267 for key, pattern in websubdefs: | |
268 # grab the delimiter from the character after the "s" | |
269 unesc = pattern[1] | |
270 delim = re.escape(unesc) | |
271 | |
272 # identify portions of the pattern, taking care to avoid escaped | |
273 # delimiters. the replace format and flags are optional, but | |
274 # delimiters are required. | |
275 match = re.match( | |
276 r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$' | |
277 % (delim, delim, delim), pattern) | |
278 if not match: | |
279 self.repo.ui.warn(_("websub: invalid pattern for %s: %s\n") | |
280 % (key, pattern)) | |
281 continue | |
282 | |
283 # we need to unescape the delimiter for regexp and format | |
284 delim_re = re.compile(r'(?<!\\)\\%s' % delim) | |
285 regexp = delim_re.sub(unesc, match.group(1)) | |
286 format = delim_re.sub(unesc, match.group(2)) | |
287 | |
288 # the pattern allows for 6 regexp flags, so set them if necessary | |
289 flagin = match.group(3) | |
290 flags = 0 | |
291 if flagin: | |
292 for flag in flagin.upper(): | |
293 flags |= re.__dict__[flag] | |
294 | |
295 try: | |
296 regexp = re.compile(regexp, flags) | |
297 websubtable.append((regexp, format)) | |
298 except re.error: | |
299 self.repo.ui.warn(_("websub: invalid regexp for %s: %s\n") | |
300 % (key, regexp)) | |
301 return websubtable | |
302 | |
261 def templater(self, req): | 303 def templater(self, req): |
262 | 304 |
263 # determine scheme, port and server name | 305 # determine scheme, port and server name |
264 # this is needed to create absolute urls | 306 # this is needed to create absolute urls |
265 | 307 |
309 if not self.reponame: | 351 if not self.reponame: |
310 self.reponame = (self.config("web", "name") | 352 self.reponame = (self.config("web", "name") |
311 or req.env.get('REPO_NAME') | 353 or req.env.get('REPO_NAME') |
312 or req.url.strip('/') or self.repo.root) | 354 or req.url.strip('/') or self.repo.root) |
313 | 355 |
356 def websubfilter(text): | |
357 return websub(text, self.websubtable) | |
358 | |
314 # create the templater | 359 # create the templater |
315 | 360 |
316 tmpl = templater.templater(mapfile, | 361 tmpl = templater.templater(mapfile, |
362 filters={"websub": websubfilter}, | |
317 defaults={"url": req.url, | 363 defaults={"url": req.url, |
318 "logourl": logourl, | 364 "logourl": logourl, |
319 "logoimg": logoimg, | 365 "logoimg": logoimg, |
320 "staticurl": staticurl, | 366 "staticurl": staticurl, |
321 "urlbase": urlbase, | 367 "urlbase": urlbase, |