comparison mercurial/hgweb/hgweb_mod.py @ 26162:268b39770c28

hgweb: extract web substitutions table generation to own function It doesn't use any state in hgweb except for the repo instance. Move it to a standalone function.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 22 Aug 2015 15:40:33 -0700
parents 16d54bbdbf89
children 84511b1d9724
comparison
equal deleted inserted replaced
26161:16d54bbdbf89 26162:268b39770c28
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> 4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 # 5 #
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, re 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 11 from mercurial.templatefilters import websub
12 from mercurial.i18n import _ 12 from mercurial.i18n import _
13 from common import get_stat, ErrorResponse, permhooks, caching 13 from common import get_stat, ErrorResponse, permhooks, caching
14 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST 14 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
57 if not pathel or not urlel: 57 if not pathel or not urlel:
58 break 58 break
59 breadcrumb.append({'url': urlel, 'name': pathel}) 59 breadcrumb.append({'url': urlel, 'name': pathel})
60 urlel = os.path.dirname(urlel) 60 urlel = os.path.dirname(urlel)
61 return reversed(breadcrumb) 61 return reversed(breadcrumb)
62
63 62
64 class requestcontext(object): 63 class requestcontext(object):
65 """Holds state/context for an individual request. 64 """Holds state/context for an individual request.
66 65
67 Servers can be multi-threaded. Holding state on the WSGI application 66 Servers can be multi-threaded. Holding state on the WSGI application
161 self.reponame = name 160 self.reponame = name
162 # we use untrusted=False to prevent a repo owner from using 161 # we use untrusted=False to prevent a repo owner from using
163 # web.templates in .hg/hgrc to get access to any file readable 162 # web.templates in .hg/hgrc to get access to any file readable
164 # by the user running the CGI script 163 # by the user running the CGI script
165 self.templatepath = self.config('web', 'templates', untrusted=False) 164 self.templatepath = self.config('web', 'templates', untrusted=False)
166 self.websubtable = self.loadwebsub() 165 self.websubtable = webutil.getwebsubs(r)
167 166
168 # The CGI scripts are often run by a user different from the repo owner. 167 # The CGI scripts are often run by a user different from the repo owner.
169 # Trust the settings from the .hg/hgrc files by default. 168 # Trust the settings from the .hg/hgrc files by default.
170 def config(self, section, name, default=None, untrusted=True): 169 def config(self, section, name, default=None, untrusted=True):
171 return self.repo.ui.config(section, name, default, 170 return self.repo.ui.config(section, name, default,
367 if inst.code == HTTP_NOT_MODIFIED: 366 if inst.code == HTTP_NOT_MODIFIED:
368 # Not allowed to return a body on a 304 367 # Not allowed to return a body on a 304
369 return [''] 368 return ['']
370 return tmpl('error', error=inst.message) 369 return tmpl('error', error=inst.message)
371 370
372 def loadwebsub(self):
373 websubtable = []
374 websubdefs = self.repo.ui.configitems('websub')
375 # we must maintain interhg backwards compatibility
376 websubdefs += self.repo.ui.configitems('interhg')
377 for key, pattern in websubdefs:
378 # grab the delimiter from the character after the "s"
379 unesc = pattern[1]
380 delim = re.escape(unesc)
381
382 # identify portions of the pattern, taking care to avoid escaped
383 # delimiters. the replace format and flags are optional, but
384 # delimiters are required.
385 match = re.match(
386 r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
387 % (delim, delim, delim), pattern)
388 if not match:
389 self.repo.ui.warn(_("websub: invalid pattern for %s: %s\n")
390 % (key, pattern))
391 continue
392
393 # we need to unescape the delimiter for regexp and format
394 delim_re = re.compile(r'(?<!\\)\\%s' % delim)
395 regexp = delim_re.sub(unesc, match.group(1))
396 format = delim_re.sub(unesc, match.group(2))
397
398 # the pattern allows for 6 regexp flags, so set them if necessary
399 flagin = match.group(3)
400 flags = 0
401 if flagin:
402 for flag in flagin.upper():
403 flags |= re.__dict__[flag]
404
405 try:
406 regexp = re.compile(regexp, flags)
407 websubtable.append((regexp, format))
408 except re.error:
409 self.repo.ui.warn(_("websub: invalid regexp for %s: %s\n")
410 % (key, regexp))
411 return websubtable
412
413 def templater(self, req): 371 def templater(self, req):
414 372
415 # determine scheme, port and server name 373 # determine scheme, port and server name
416 # this is needed to create absolute urls 374 # this is needed to create absolute urls
417 375