From 7e2c6cbb452aa986891b2a99653a147bfb053e19 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 1 Sep 2008 01:52:14 +0000 Subject: - New API module: ``repoze.bfg.view``. This module contains the functions named ``render_view_to_response``, ``render_view_to_iterable`` and ``is_response``, which are documented in the API docs. These features aid programmatic (non-request-driven) view execution. --- repoze/bfg/view.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 repoze/bfg/view.py (limited to 'repoze/bfg/view.py') diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py new file mode 100644 index 000000000..180c020a0 --- /dev/null +++ b/repoze/bfg/view.py @@ -0,0 +1,71 @@ +from zope.component import queryMultiAdapter +from zope.component import queryUtility + +from repoze.bfg.interfaces import ISecurityPolicy +from repoze.bfg.interfaces import IViewPermission +from repoze.bfg.interfaces import IView +from repoze.bfg.security import Unauthorized + +def render_view_to_response(context, request, name='', secure=True): + """ Render the view named ``name`` against the specified + ``context`` and ``request`` to an object implementing + ``repoze.bfg.interfaces.IResponse`` or ``None`` if no such view + exists. This function will return ``None`` if a corresponding + view cannot be found. If ``secure`` is ``True``, and the view is + protected by a permission, the permission will be checked before + calling the view function. If the permission check disallows view + execution (based on the current security policy), a + ``repoze.bfg.security.Unauthorized`` exception will be raised; its + ``message`` attribute explains why the view access was disallowed. + If ``secure`` is ``False``, no permission checking is done.""" + if secure: + security_policy = queryUtility(ISecurityPolicy) + if security_policy: + permission = queryMultiAdapter((context, request), IViewPermission, + name=name) + if permission is not None: + result = permission(security_policy) + if not result: + raise Unauthorized(result) + return queryMultiAdapter((context, request), IView, name=name) + +def render_view_to_iterable(context, request, name='', secure=True): + """ Render the view named ``name`` against the specified + ``context`` and ``request``, and return an iterable representing + the view response's ``app_iter`` (see the interface named + ``repoze.bfg.interfaces.IResponse``). This function will return + ``None`` if a corresponding view cannot be found. Additionally, + this function will raise a ``ValueError`` if a view function is + found and called but the view does not return an object which + implements ``repoze.bfg.interfaces.IResponse``. You can usually + get the string representation of the return value of this function + by calling ``''.join(iterable)``. If ``secure`` is ``True``, and + the view is protected by a permission, the permission will be + checked before calling the view function. If the permission check + disallows view execution (based on the current security policy), a + ``repoze.bfg.security.Unauthorized`` exception will be raised; its + ``message`` attribute explains why the view access was disallowed. + If ``secure`` is ``False``, no permission checking is done.""" + response = render_view_to_response(context, request, name, secure) + if response is None: + return None + if not is_response(response): + raise ValueError('response did not implement IResponse: %r' % response) + return response.app_iter + +def is_response(ob): + """ Return True if ``ob`` implements the + ``repoze.bfg.interfaces.IResponse`` interface, False if not. Note + that this isn't actually a true Zope interface check, it's a + duck-typing check, as response objects are not obligated to + actually implement a Zope interface.""" + # response objects aren't obligated to implement a Zope interface, + # so we do it the hard way + if ( hasattr(ob, 'app_iter') and hasattr(ob, 'headerlist') and + hasattr(ob, 'status') ): + if ( hasattr(ob.app_iter, '__iter__') and + hasattr(ob.headerlist, '__iter__') and + isinstance(ob.status, basestring) ) : + return True + return False + -- cgit v1.2.3