Source code for clink.routing.router

from clink.com import read_stamp
from clink.iface import ILv2Handler
from clink.error.http import Http400Error, Http404Error, Http405Error

from .error import RouteExistError
from .route import Route
from .mapper import CTL_PATH_ATTR, CTL_METHOD_ATTR


[docs]class Router(ILv2Handler): ''' Store and find routes ''' def __init__(self, routes=[]): ''' :param list<Router> routes: ''' self._map = {} self.add_routes(routes)
[docs] def add_ctl(self, ctl): ''' Collect routing information from controller :param object ctl: ''' ctl_type = type(ctl) ctl_path = read_stamp(ctl, CTL_PATH_ATTR) for attr_name in dir(ctl_type): ctl_attr = getattr(ctl_type, attr_name) try: ctl_method = read_stamp(ctl_attr, CTL_METHOD_ATTR) abs_path = ctl_path + ctl_method.path abs_path = abs_path.replace('//', '/') if len(abs_path) > 1 and abs_path[-1] == '/': abs_path = abs_path[:len(abs_path) - 1] route = Route( abs_path, ctl_method.method, ctl_method.req_type, getattr(ctl, attr_name) ) self.add_route(route) except KeyError: pass except TypeError: pass
[docs] def add_route(self, route): ''' Put route into map :param Route route: :raise RouteExistError: ''' if route.path not in self._map: self._map[route.path] = {} if route.method not in self._map: self._map[route.path][route.method] = {} if route.req_type in self._map[route.path][route.method]: raise RouteExistError(route) self._map[route.path][route.method][route.req_type] = route
[docs] def add_routes(self, routes): ''' Put routes into map :param list[Route] routes: ''' for route in routes: self.add_route(route)
[docs] def handle(self, req): ''' Find handle which match with request :param Request req: :rtype: function :raise Http400Error: :raise Http404Error: :raise Http405Error: ''' path = req.path method = req.method if path not in self._map: raise Http404Error(req) if method not in self._map[path]: raise Http405Error(req) if req.content_type not in self._map[path][method]: raise Http400Error(req) return self._map[path][method][req.content_type].handle