mercurial/hgweb/hgweb_mod.py
changeset 18627 4e949b8e0930
parent 18522 36549fa712da
child 18629 013fcd112f13
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,