Permalink
Browse files

Compatibility with dreadpiratebob and percious's tree.

  • Loading branch information...
ralphbean committed Mar 30, 2012
1 parent 5a7ef40 commit af7a2e6b867bca63b09b5be90f2ca01bfb506f4b
Showing with 104 additions and 0 deletions.
  1. +30 −0 tests/test_middleware.py
  2. +4 −0 tw2/core/__init__.py
  3. +70 −0 tw2/core/compat.py
@@ -77,6 +77,36 @@ def mock_inject(*a, **kw):
finally:
resources.inject_resources = real
def testTGStyleController(self):
""" Test turbogears style dispatch """
from tw2.core.middleware import ControllersApp, TwMiddleware
from tw2.core.compat import TGStyleController
controller_response = Response("CONTROLLER")
class WidgetMock(TGStyleController):
id = 'fake'
class Controller(object):
def foobar(self, request):
return controller_response
mock = WidgetMock()
mw = TwMiddleware(None, controller_prefix="goo")
testapi.request(1, mw)
ca = ControllersApp()
ca.register(mock)
res = ca(Request.blank("/%s/%s/foobar" % (
mw.config.controller_prefix, mock.id
)))
self.assert_(res.status_int == 200, res.status_int)
self.assert_(res.body == controller_response.body, res.body)
res = ca(Request.blank("/%s/404" % mw.config.controller_prefix))
self.assert_(res.status_int == 404, res.status_int)
res = ca(Request.blank("%s/404" % mw.config.controller_prefix))
self.assert_(res.status_int == 404, res.status_int)
def testControllerAppWithId(self):
"""
controllerapp should dispatch to an object having id, and a
@@ -47,6 +47,10 @@
encoder
)
from compat import (
TGStyleController,
)
from i18n import _, tw2_translation_string
# Shortcut from Deprecated TWEncoder that was in js.py
@@ -0,0 +1,70 @@
""" Collections of extra pieces to help smooth over community divergence. """
from widgets import Widget
class TGStyleController(Widget):
""" A widget mixin that provides more advanced controller routing and
dispatching.
The need for this mainly sprung from a divergence of source trees
(unintentionally forking) between the developers of tw2 while it was still
alpha/beta. One team expected users to define controllers as a 'request'
classmethod on the widget and another team expected users to define a
Controller class as a child of the widget. Team A's pattern is now the
default in the main tree. This is a shim to support Team B's approach.
Use it like this:
>>> import tw2.core
>>> class MyWidget(tw2.core.TGStyleController, tw2.core.Widget):
... class Controller(object):
... @jsonify
... def some_method(self, req):
... return dict(foo="bar")
"""
@classmethod
def dispatch(cls, req, controller):
path = req.path_info.strip('/').split('/')[2:]
if len(path) == 0:
method_name = 'index'
else:
method_name = path[0]
# later we want to better handle .ext conditions, but hey
# this aint TG
if method_name.endswith('.json'):
method_name = method_name[:-5]
method = getattr(controller, method_name, None)
if not method:
method = getattr(controller, 'default', None)
return method
@classmethod
def request(cls, req):
"""
Override this method to define your own way of handling a widget
request.
The default does TG-style object dispatch.
"""
authn = cls.attrs.get('_check_authn')
authz = cls.attrs.get('_check_authz')
if authn and not authn(req):
return util.abort(req, 401)
controller = cls.attrs.get('controller', cls.Controller)
if controller is None:
return util.abort(req, 404)
method = cls.dispatch(req, controller)
if method:
if authz and not authz(req, method):
return util.abort(req, 403)
controller = cls.Controller()
return method(controller, req)
return util.abort(req, 404)

0 comments on commit af7a2e6

Please sign in to comment.