mercurial/hgweb/hgweb_mod.py
changeset 26219 ae33fff17c1e
parent 26218 7d45ec47c0af
child 26220 a43328baa2ac
equal deleted inserted replaced
26218:7d45ec47c0af 26219:ae33fff17c1e
    22     'stream_out': 'pull',
    22     'stream_out': 'pull',
    23     'listkeys': 'pull',
    23     'listkeys': 'pull',
    24     'unbundle': 'push',
    24     'unbundle': 'push',
    25     'pushkey': 'push',
    25     'pushkey': 'push',
    26 }
    26 }
    27 
       
    28 ## Files of interest
       
    29 # Used to check if the repository has changed looking at mtime and size of
       
    30 # theses files. This should probably be relocated a bit higher in core.
       
    31 foi = [('spath', '00changelog.i'),
       
    32        ('spath', 'phaseroots'), # ! phase can change content at the same size
       
    33        ('spath', 'obsstore'),
       
    34        ('path', 'bookmarks'), # ! bookmark can change content at the same size
       
    35       ]
       
    36 
    27 
    37 def makebreadcrumb(url, prefix=''):
    28 def makebreadcrumb(url, prefix=''):
    38     '''Return a 'URL breadcrumb' list
    29     '''Return a 'URL breadcrumb' list
    39 
    30 
    40     A 'URL breadcrumb' is a list of URL-name pairs,
    31     A 'URL breadcrumb' is a list of URL-name pairs,
    64 
    55 
    65     Servers can be multi-threaded. Holding state on the WSGI application
    56     Servers can be multi-threaded. Holding state on the WSGI application
    66     is prone to race conditions. Instances of this class exist to hold
    57     is prone to race conditions. Instances of this class exist to hold
    67     mutable and race-free state for requests.
    58     mutable and race-free state for requests.
    68     """
    59     """
    69     def __init__(self, app):
    60     def __init__(self, app, repo):
    70         self.repo = app.repo
    61         self.repo = repo
    71         self.reponame = app.reponame
    62         self.reponame = app.reponame
    72 
    63 
    73         self.archives = ('zip', 'gz', 'bz2')
    64         self.archives = ('zip', 'gz', 'bz2')
    74 
    65 
    75         self.maxchanges = self.configint('web', 'maxchanges', 10)
    66         self.maxchanges = self.configint('web', 'maxchanges', 10)
   215         r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
   206         r.baseui.setconfig('ui', 'nontty', 'true', 'hgweb')
   216         # displaying bundling progress bar while serving feel wrong and may
   207         # displaying bundling progress bar while serving feel wrong and may
   217         # break some wsgi implementation.
   208         # break some wsgi implementation.
   218         r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
   209         r.ui.setconfig('progress', 'disable', 'true', 'hgweb')
   219         r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
   210         r.baseui.setconfig('progress', 'disable', 'true', 'hgweb')
   220         self.repo = self._webifyrepo(r)
   211         self._repo = hg.cachedlocalrepo(self._webifyrepo(r))
   221         hook.redirect(True)
   212         hook.redirect(True)
   222         self.repostate = None
       
   223         self.mtime = -1
       
   224         self.reponame = name
   213         self.reponame = name
   225 
   214 
   226     def _webifyrepo(self, repo):
   215     def _webifyrepo(self, repo):
   227         repo = getwebview(repo)
   216         repo = getwebview(repo)
   228         self.websubtable = webutil.getwebsubs(repo)
   217         self.websubtable = webutil.getwebsubs(repo)
   229         return repo
   218         return repo
   230 
   219 
   231     def refresh(self):
   220     def _getrepo(self):
   232         repostate = []
   221         r, created = self._repo.fetch()
   233         mtime = 0
   222         if created:
   234         # file of interrests mtime and size
   223             r = self._webifyrepo(r)
   235         for meth, fname in foi:
   224 
   236             prefix = getattr(self.repo, meth)
   225         self.mtime = self._repo.mtime
   237             st = get_stat(prefix, fname)
   226         return r
   238             repostate.append((st.st_mtime, st.st_size))
       
   239             mtime = max(mtime, st.st_mtime)
       
   240         repostate = tuple(repostate)
       
   241         # we need to compare file size in addition to mtime to catch
       
   242         # changes made less than a second ago
       
   243         if repostate != self.repostate:
       
   244             r = hg.repository(self.repo.baseui, self.repo.url())
       
   245             self.repo = self._webifyrepo(r)
       
   246             # update these last to avoid threads seeing empty settings
       
   247             self.repostate = repostate
       
   248             # mtime is needed for ETag
       
   249             self.mtime = mtime
       
   250 
   227 
   251     def run(self):
   228     def run(self):
   252         """Start a server from CGI environment.
   229         """Start a server from CGI environment.
   253 
   230 
   254         Modern servers should be using WSGI and should avoid this
   231         Modern servers should be using WSGI and should avoid this
   272         """Internal method to run the WSGI application.
   249         """Internal method to run the WSGI application.
   273 
   250 
   274         This is typically only called by Mercurial. External consumers
   251         This is typically only called by Mercurial. External consumers
   275         should be using instances of this class as the WSGI application.
   252         should be using instances of this class as the WSGI application.
   276         """
   253         """
   277         self.refresh()
   254         repo = self._getrepo()
   278         rctx = requestcontext(self)
   255         rctx = requestcontext(self, repo)
   279 
   256 
   280         # This state is global across all threads.
   257         # This state is global across all threads.
   281         encoding.encoding = rctx.config('web', 'encoding', encoding.encoding)
   258         encoding.encoding = rctx.config('web', 'encoding', encoding.encoding)
   282         rctx.repo.ui.environ = req.env
   259         rctx.repo.ui.environ = req.env
   283 
   260