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,