Commits

Yuya Nishihara committed 7e6402f

wrap object.__class__ instead of class itself

Comments (0)

Files changed (1)

hgext/webuserdir.py

 and http://mercurial.selenic.com/bts/issue1824 for details.
 """
 
-from mercurial import extensions, util
-from mercurial.hgweb.hgwebdir_mod import hgwebdir, findrepos
 import os, pwd, re
+from mercurial import extensions, hgweb, util
+from mercurial.hgweb import hgwebdir_mod
 
 class NoUserDirError(Exception):
     pass
 
+def _wraphgwebdir(obj):
+    origcls = obj.__class__
+    class hgwebudir(obj.__class__):
+        def run_wsgi(self, req):
+            virtual = req.env.get('PATH_INFO', '').strip('/')
+            m = re.match(r'~([^/]+)', virtual)
+            if not m:
+                return super(hgwebudir, self).run_wsgi(req)
 
-def run_wsgi_userdir(orig, self, req):
-    """dispatches /~username/ request to userdir"""
-    virtual = req.env.get('PATH_INFO', '').strip('/')
-    m = re.match(r'~([^/]+)', virtual)
-    if not m:
-        return orig(self, req)
+            user = m.group(1)
+            try:
+                userdir = getuserdir(self.ui, user)
+            except NoUserDirError:
+                return super(hgwebudir, self).run_wsgi(req)  # delegates 404 error
 
-    user = m.group(1)
-    try:
-        userdir = getuserdir(self.ui, user)
-    except NoUserDirError:
-        return orig(self, req)  # delegates 404 error
+            # TODO: cache repos/webdir for certain seconds like hgwebdir
+            repos = hgwebdir_mod.findrepos([('~' + user, os.path.join(userdir, '**'))])
+            return origcls(repos, baseui=self.ui).run_wsgi(req)
 
-    repos = findrepos([('~' + user, os.path.join(userdir, '**'))])
-    # TODO: cache repos for certain seconds like hgwebdir
+    obj.__class__ = hgwebudir
 
-    # we cannot call hgwebdir().run_wsgi(req) because it's wrapped by me.
-    return orig(hgwebdir(repos, baseui=self.ui), req)
+def hgwebwrapper(orig, config, name=None, baseui=None):
+    o = orig(config, name, baseui)
+    if isinstance(o, hgwebdir_mod.hgwebdir):
+        _wraphgwebdir(o)
+    return o
 
+def hgwebdirwrapper(orig, config, baseui=None):
+    o = orig(config, baseui)
+    _wraphgwebdir(o)
+    return o
 
 def getuserdir(ui, user):
     """returns path to directory of user's repositories"""
 
     return path
 
-
-def uisetup(ui):
-    extensions.wrapfunction(hgwebdir, 'run_wsgi', run_wsgi_userdir)
+def extsetup():
+    extensions.wrapfunction(hgweb, 'hgweb', hgwebwrapper)
+    extensions.wrapfunction(hgweb, 'hgwebdir', hgwebdirwrapper)