1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
from zope.interface import implements
from zope.interface import classProvides
from routes import Mapper
from routes import request_config
from repoze.bfg.interfaces import IURLDispatchModel
from repoze.bfg.interfaces import ITraverserFactory
from repoze.bfg.interfaces import ITraverser
class RoutesModel(object):
implements(IURLDispatchModel)
def __init__(self, **kw):
self.__dict__.update(kw)
class RoutesMapper(object):
""" The RoutesMapper is a wrapper for the ``get_root`` callable
passed in to the repoze.bfg Router at initialization time. When
it is instantiated, it wraps the get_root of an application in
such a way that the `Routes
<http://routes.groovie.org/index.html>`_ engine has the 'first
crack' at resolving the current request URL to a repoze.bfg view.
If the ``RoutesModelTraverser`` is configured in your
application's configure.zcml, any view that claims it is 'for' the
interface ``repoze.bfg.interfaces.IURLDispatchModel`` will be
called if its *name* matches the Routes 'controller' name for the
match. It will be passed a context object that has attributes
that match the Routes match arguments dictionary keys. If no
Routes route matches the current request, the 'fallback' get_root
is called."""
def __init__(self, get_root):
self.get_root = get_root
self.mapper = Mapper(controller_scan=None, directory=None,
explicit=True, always_scan=False)
self.mapper.explicit = True
self._regs_created = False
def __call__(self, environ):
if not self._regs_created:
self.mapper.create_regs([])
self._regs_created = True
path = environ.get('PATH_INFO', '/')
args = self.mapper.match(path)
if args:
config = request_config()
config.mapper = self.mapper
config.mapper_dict = args
config.host = environ.get('HTTP_HOST', environ['SERVER_NAME'])
config.protocol = environ['wsgi.url_scheme']
config.redirect = None
model = RoutesModel(**args)
return model
# fall back to original get_root
return self.get_root(environ)
def connect(self, *arg, **kw):
""" Add a route to the Routes mapper associated with this
request. This method accepts the same arguments as a Routes
*Mapper* object"""
self.mapper.connect(*arg, **kw)
class RoutesModelTraverser(object):
classProvides(ITraverserFactory)
implements(ITraverser)
def __init__(self, model, request):
self.model = model
self.request = request
def __call__(self, environ):
return self.model, self.model.controller, ''
|