import routes from routes.middleware import RoutesMiddleware import webob import webob.exc class WsgiToWebobMiddleware(object): def __init__(self, webob_app): self.webob_app = webob_app def __call__(self, environ, start_response): request = webob.Request(environ) response = self.webob_app(request) return response(environ, start_response) class WsgiToRoutesWebobMiddleware(object): def __init__(self, webob_app): self.webob_app = webob_app def __call__(self, environ, start_response): request = webob.Request(environ) url, match_dict = environ["wsgiorg.routing_args"] response = self.webob_app(request, **match_dict) return response(environ, start_response) class RoutesDispatcher(object): def __init__(self, controller_map, mapper, http_error_controller_map=None): self.controller_map = controller_map self.mapper = mapper if http_error_controller_map is None: http_error_controller_map = {} self.http_error_controller_map = http_error_controller_map def PageNotFound(self, environ, start_response): error_controller = self.http_error_controller_map.get(404) if error_controller: return error_controller(environ, start_response) else: return webob.exc.HTTPNotFound()(environ, start_response) def WsgiApp(self, environ, start_response): url, match_dict = environ["wsgiorg.routing_args"] try: controller = self.controller_map[match_dict.pop("controller")] except KeyError: return self.PageNotFound(environ, start_response) try: return controller(environ, start_response) except StopIteration: raise class DispatchRule(object): def __init__(self, name, url, controller, **kwargs): self.name = name self.url = url self.controller = controller self.kwargs = kwargs class DispatchRuleFactory(object): def __init__(self, middleware): self.middleware = middleware def __call__(self, name, url, controller, **kwargs): controller = self.middleware(controller) return DispatchRule(name, url, controller, **kwargs) WebobDispatchRule = DispatchRuleFactory(middleware=WsgiToRoutesWebobMiddleware) def get_middleware_app(dispatch_rules, http_error_controller_map=None): controller_map = {} mapper = routes.Mapper() for rule in dispatch_rules: controller_id = str(id(rule.controller)) controller_map[controller_id] = rule.controller mapper.connect(rule.name, rule.url, controller=controller_id, **rule.kwargs) mapper.create_regs(controller_map.keys()) routes_dispatcher = RoutesDispatcher( controller_map, mapper, http_error_controller_map) return RoutesMiddleware( routes_dispatcher.WsgiApp, mapper, use_method_override=False)