summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcguardia <carlos.delaguardia@gmail.com>2011-04-16 21:51:03 -0500
committercguardia <carlos.delaguardia@gmail.com>2011-04-16 21:51:03 -0500
commit66cda3dbdf336e82b395a8b99e637509e23967bd (patch)
tree74b3757f861cc39c00d89675a5e094b4a188ef95
parenta6e30eb7c937023fb2e987571cc1b31df5deb270 (diff)
downloadpyramid-66cda3dbdf336e82b395a8b99e637509e23967bd.tar.gz
pyramid-66cda3dbdf336e82b395a8b99e637509e23967bd.tar.bz2
pyramid-66cda3dbdf336e82b395a8b99e637509e23967bd.zip
start playing with paster command to show matching views for url
-rw-r--r--pyramid/config.py17
-rw-r--r--pyramid/paster.py134
-rw-r--r--setup.py1
3 files changed, 152 insertions, 0 deletions
diff --git a/pyramid/config.py b/pyramid/config.py
index 9fda75daa..ef520e053 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -2441,6 +2441,7 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
if xhr:
def xhr_predicate(context, request):
return request.is_xhr
+ xhr_predicate.__text__ = "XHR = True"
weights.append(1 << 1)
predicates.append(xhr_predicate)
h.update('xhr:%r' % bool(xhr))
@@ -2448,6 +2449,8 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
if request_method is not None:
def request_method_predicate(context, request):
return request.method == request_method
+ msg = "Request method = %s"
+ request_method_predicate.__text__ = msg % request_method
weights.append(1 << 2)
predicates.append(request_method_predicate)
h.update('request_method:%r' % request_method)
@@ -2459,6 +2462,8 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
raise ConfigurationError(why[0])
def path_info_predicate(context, request):
return path_info_val.match(request.path_info) is not None
+ msg = "path_info = %s"
+ path_info_predicate.__text__ = msg % path_info
weights.append(1 << 3)
predicates.append(path_info_predicate)
h.update('path_info:%r' % path_info)
@@ -2471,6 +2476,11 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
if request_param_val is None:
return request_param in request.params
return request.params.get(request_param) == request_param_val
+ if request_param_val is None:
+ msg = "request_param %s" % request_param
+ else:
+ msg = "request_param %s = %s" % (request_param, request_param_val)
+ request_param_predicate.__text__ = msg
weights.append(1 << 4)
predicates.append(request_param_predicate)
h.update('request_param:%r=%r' % (request_param, request_param_val))
@@ -2491,6 +2501,11 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
if val is None:
return False
return header_val.match(val) is not None
+ if header_val is None:
+ msg = "header %s" % header_name
+ else:
+ msg = "header %s = %s" % (header_name, header_val)
+ header_predicate.__text__ = msg
weights.append(1 << 5)
predicates.append(header_predicate)
h.update('header:%r=%r' % (header_name, header_val))
@@ -2654,6 +2669,7 @@ def preserve_view_attrs(view, wrapped_view):
pass
try:
wrapped_view.__predicated__ = view.__predicated__
+ wrapped_view.__predicates__ = view.__predicates__
except AttributeError:
pass
try:
@@ -2791,6 +2807,7 @@ class ViewDeriver(object):
return all((predicate(context, request) for predicate in
predicates))
predicate_wrapper.__predicated__ = checker
+ predicate_wrapper.__predicates__ = predicates
return predicate_wrapper
@wraps_view
diff --git a/pyramid/paster.py b/pyramid/paster.py
index bc1573fb8..7ff77522e 100644
--- a/pyramid/paster.py
+++ b/pyramid/paster.py
@@ -195,3 +195,137 @@ class PRoutesCommand(PCommand):
(IViewClassifier, request_iface, Interface),
IView, name='', default=None)
self.out(fmt % (route.name, route.pattern, view_callable))
+
+class PViewsCommand(PCommand):
+ """Print, for a given URL, the views that might match. Underneath each
+ potentially matching route, list the predicates required. Underneath
+ each route+predicate set, print each view that might match and its
+ predicates.
+
+ This command accepts three positional arguments:
+
+ ``config_file`` -- specifies the PasteDeploy config file to use
+ for the interactive shell.
+
+ ``section_name`` -- specifies the section name in the PasteDeploy
+ config file that represents the application.
+
+ ``url`` -- specifies the URL that will be used to find matching views.
+
+ Example::
+
+ $ paster proutes myapp.ini main url
+
+ .. note:: You should use a ``section_name`` that refers to the
+ actual ``app`` section in the config file that points at
+ your Pyramid app without any middleware wrapping, or this
+ command will almost certainly fail.
+ """
+ summary = "Print all views in an application that might match a URL"
+ min_args = 3
+ max_args = 3
+ stdout = sys.stdout
+
+ parser = Command.standard_parser(simulate=True)
+
+ def out(self, msg): # pragma: no cover
+ print msg
+
+ def _find_view(self, url, registry):
+ """
+ Accept ``url`` and ``registry``; create a :term:`request` and
+ find a :app:`Pyramid` view based on introspection of :term:`view
+ configuration` within the application registry; return the view.
+ """
+ from zope.interface import providedBy
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IRootFactory
+ from pyramid.interfaces import IRouteRequest
+ from pyramid.interfaces import IRequestFactory
+ from pyramid.interfaces import IRoutesMapper
+ from pyramid.interfaces import ITraverser
+ from pyramid.interfaces import IView
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.request import Request
+ from pyramid.traversal import DefaultRootFactory
+ from pyramid.traversal import ResourceTreeTraverser
+
+ q = registry.queryUtility
+ root_factory = q(IRootFactory, default=DefaultRootFactory)
+ routes_mapper = q(IRoutesMapper)
+ request_factory = q(IRequestFactory, default=Request)
+
+ adapters = registry.adapters
+ request = None
+
+ # create the request
+ environ = {
+ 'wsgi.url_scheme':'http',
+ 'SERVER_NAME':'localhost',
+ 'SERVER_PORT':'8080',
+ 'REQUEST_METHOD':'GET',
+ 'PATH_INFO':url,
+ }
+ request = request_factory(environ)
+ context = None
+ attrs = request.__dict__
+ attrs['registry'] = registry
+ request_iface = IRequest
+
+ # find the root object
+ root_factory = root_factory
+ if routes_mapper is not None:
+ info = routes_mapper(request)
+ match, route = info['match'], info['route']
+ if route is not None:
+ attrs['matchdict'] = match
+ attrs['matched_route'] = route
+
+ request_iface = registry.queryUtility(
+ IRouteRequest,
+ name=route.name,
+ default=IRequest)
+ root_factory = route.factory or root_factory
+
+ root = root_factory(request)
+ attrs['root'] = root
+
+ # find a context
+ traverser = adapters.queryAdapter(root, ITraverser)
+ if traverser is None:
+ traverser = ResourceTreeTraverser(root)
+ tdict = traverser(request)
+ context, view_name, subpath, traversed, vroot, vroot_path =(
+ tdict['context'], tdict['view_name'], tdict['subpath'],
+ tdict['traversed'], tdict['virtual_root'],
+ tdict['virtual_root_path'])
+ attrs.update(tdict)
+
+ # find a view callable
+ context_iface = providedBy(context)
+ view_callable = adapters.lookup(
+ (IViewClassifier, request_iface, context_iface),
+ IView, name=view_name, default=None)
+
+ return view_callable
+
+ def command(self):
+ from pyramid.interfaces import IMultiView
+
+ config_file, section_name, url = self.args
+ app = self.get_app(config_file, section_name, loadapp=self.loadapp[0])
+ registry = app.registry
+ view = self._find_view(url, registry)
+ self.out('')
+ self.out(url)
+ if IMultiView.providedBy(view):
+ for dummy, view_wrapper, dummy in view.views:
+ self.out('')
+ for p in view_wrapper.__predicates__:
+ text = getattr(p, '__text__', p.__name__)
+ self.out(" %s" % text)
+ self.out(" %s" % str(view_wrapper.__original_view__))
+ else:
+ self.out('')
+ self.out(view)
+
diff --git a/setup.py b/setup.py
index 7c7c80040..4ab4cca82 100644
--- a/setup.py
+++ b/setup.py
@@ -85,6 +85,7 @@ setup(name='pyramid',
[paste.paster_command]
pshell=pyramid.paster:PShellCommand
proutes=pyramid.paster:PRoutesCommand
+ pviews=pyramid.paster:PViewsCommand
[console_scripts]
bfg2pyramid = pyramid.fixers.fix_bfg_imports:main
"""