Skip to content

Commit

Permalink
Merge branch 'feature.usemetapredicates'
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdonc committed Aug 7, 2012
2 parents 7d5cf83 + ec556f4 commit 1e45dd9
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 32 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
README = CHANGES = '' README = CHANGES = ''


install_requires = [ install_requires = [
'pyramid', 'pyramid>=1.4dev',
'ZODB3', 'ZODB3',
'hypatia>=0.1a2', 'hypatia>=0.1a2',
'venusian', 'venusian',
Expand Down
14 changes: 13 additions & 1 deletion substanced/content/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -167,7 +167,19 @@ def add_provides(*arg, **kw):
add_provides.__orig__ = factory add_provides.__orig__ = factory
return add_provides return add_provides


class ContentTypePredicate(object):
def __init__(self, val, config):
self.val = val

def text(self):
return 'content_type = %s' % (self.val,)

phash = text

def __call__(self, context, request):
return get_content_type(context) == self.val

def includeme(config): # pragma: no cover def includeme(config): # pragma: no cover
config.registry.content = ContentRegistry() config.registry.content = ContentRegistry()
config.add_directive('add_content_type', add_content_type) config.add_directive('add_content_type', add_content_type)

config.add_view_predicate('content_type', ContentTypePredicate)
26 changes: 26 additions & 0 deletions substanced/content/tests.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -238,6 +238,32 @@ def factory():
self.assertTrue(IDummy.providedBy(ob)) self.assertTrue(IDummy.providedBy(ob))
self.assertTrue(IDummy in directlyProvidedBy(ob)) self.assertTrue(IDummy in directlyProvidedBy(ob))


class TestContentTypePredicate(unittest.TestCase):
def _makeOne(self, val):
from . import ContentTypePredicate
return ContentTypePredicate(val, None)

def test___call___true(self):
inst = self._makeOne('abc')
context = Dummy()
context.__content_type__ = 'abc'
result = inst(context, None)
self.assertTrue(result)

def test___call___false(self):
inst = self._makeOne(True)
context = Dummy()
result = inst(context, None)
self.assertFalse(result)

def test_text(self):
inst = self._makeOne('abc')
self.assertEqual(inst.text(), 'content_type = abc')

def test_phash(self):
inst = self._makeOne('abc')
self.assertEqual(inst.phash(), 'content_type = abc')

class DummyContentRegistry(object): class DummyContentRegistry(object):
def __init__(self): def __init__(self):
self.added = [] self.added = []
Expand Down
86 changes: 64 additions & 22 deletions substanced/sdi/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
from pyramid.compat import is_nonstr_iter from pyramid.compat import is_nonstr_iter
from pyramid.exceptions import ConfigurationError from pyramid.exceptions import ConfigurationError
from pyramid.httpexceptions import HTTPBadRequest from pyramid.httpexceptions import HTTPBadRequest
from pyramid.interfaces import IView
from pyramid.request import Request from pyramid.request import Request
from pyramid.security import authenticated_userid from pyramid.security import authenticated_userid
from pyramid.session import UnencryptedCookieSessionFactoryConfig from pyramid.session import UnencryptedCookieSessionFactoryConfig
from pyramid.traversal import resource_path_tuple from pyramid.traversal import resource_path_tuple
from pyramid.registry import (
predvalseq,
Deferred,
)


from ..service import find_service from ..service import find_service


Expand All @@ -36,40 +39,79 @@ def check_csrf_token(request, token='csrf_token'):
@viewdefaults @viewdefaults
@action_method @action_method
def add_mgmt_view( def add_mgmt_view(
config, view=None, name="", permission=None, request_method=None, config,
request_param=None, containment=None, attr=None, renderer=None, view=None,
wrapper=None, xhr=False, accept=None, header=None, path_info=None, name="",
custom_predicates=(), context=None, decorator=None, mapper=None, permission=None,
http_cache=None, match_param=None, request_type=None, tab_title=None, request_method=None,
tab_condition=None, check_csrf=False, csrf_token='csrf_token', request_param=None,
): containment=None,
attr=None,
renderer=None,
wrapper=None,
xhr=False,
accept=None,
header=None,
path_info=None,
custom_predicates=(),
context=None,
decorator=None,
mapper=None,
http_cache=None,
match_param=None,
request_type=None,
tab_title=None,
tab_condition=None,
check_csrf=False,
csrf_token='csrf_token',
**other_predicates
):

view = config.maybe_dotted(view) view = config.maybe_dotted(view)
context = config.maybe_dotted(context) context = config.maybe_dotted(context)
containment = config.maybe_dotted(containment) containment = config.maybe_dotted(containment)
mapper = config.maybe_dotted(mapper) mapper = config.maybe_dotted(mapper)
decorator = config.maybe_dotted(decorator) decorator = config.maybe_dotted(decorator)


if request_method is not None:
request_method = as_sorted_tuple(request_method)
if 'GET' in request_method and 'HEAD' not in request_method:
# GET implies HEAD too
request_method = as_sorted_tuple(request_method + ('HEAD',))

if check_csrf: if check_csrf:
def _check_csrf_token(context, request): def _check_csrf_token(context, request):
check_csrf_token(request, csrf_token) check_csrf_token(request, csrf_token)
return True return True
custom_predicates = tuple(custom_predicates) + (_check_csrf_token,) custom_predicates = tuple(custom_predicates) + (_check_csrf_token,)


route_name = MANAGE_ROUTE_NAME route_name = MANAGE_ROUTE_NAME
view_discriminator = [
'view', context, name, request_type, IView, containment, pvals = other_predicates
request_param, request_method, route_name, attr, pvals.update(
xhr, accept, header, path_info, match_param] dict(
view_discriminator.extend(sorted([hash(x) for x in custom_predicates])) xhr=xhr,
view_discriminator = tuple(view_discriminator) request_method=request_method,

path_info=path_info,
discriminator = ('sdi view',) + view_discriminator[1:] request_param=request_param,
header=header,
accept=accept,
containment=containment,
request_type=request_type,
match_param=match_param,
custom=predvalseq(custom_predicates),
)
)

predlist = config.view_predlist

def view_discrim_func():
# We need to defer the discriminator until we know what the phash
# is. It can't be computed any sooner because thirdparty
# predicates may not yet exist when add_view is called.
order, preds, phash = predlist.make(config, **pvals)
return ('view', context, name, route_name, phash)

def sdi_view_discrim_func():
order, preds, phash = predlist.make(config, **pvals)
return ('sdi view', context, name, route_name, phash)

view_discriminator = Deferred(view_discrim_func)
discriminator = Deferred(sdi_view_discrim_func)


if inspect.isclass(view) and attr: if inspect.isclass(view) and attr:
view_desc = 'method %r of %s' % (attr, config.object_description(view)) view_desc = 'method %r of %s' % (attr, config.object_description(view))
Expand Down
14 changes: 6 additions & 8 deletions substanced/sdi/tests/test_sdi.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,16 +25,10 @@ def _makeConfig(self):
config = DummyConfigurator() config = DummyConfigurator()
return config return config


def test_with_request_method_sorted(self): def test_with_request_method(self):
config = self._makeConfig() config = self._makeConfig()
self._callFUT(config, request_method=('HEAD', 'GET')) self._callFUT(config, request_method=('HEAD', 'GET'))
self.assertEqual(config._added['request_method'], ('GET', 'HEAD')) self.assertEqual(config._added['request_method'], ('HEAD', 'GET'))
self.assertTrue(config._actions)

def test_with_request_method_get_implies_head(self):
config = self._makeConfig()
self._callFUT(config, request_method='GET')
self.assertEqual(config._added['request_method'], ('GET', 'HEAD'))
self.assertTrue(config._actions) self.assertTrue(config._actions)


def test_with_check_csrf(self): def test_with_check_csrf(self):
Expand Down Expand Up @@ -648,12 +642,16 @@ def attach(self, wrapped, callback, category):
self.category = category self.category = category
return self.info return self.info


class DummyPredicateList(object):
pass

class DummyConfigurator(object): class DummyConfigurator(object):
_ainfo = None _ainfo = None
def __init__(self): def __init__(self):
self._intr = DummyIntrospectable() self._intr = DummyIntrospectable()
self._actions = [] self._actions = []
self._added = None self._added = None
self.view_predlist = DummyPredicateList()


def object_description(self, ob): def object_description(self, ob):
return ob return ob
Expand Down

0 comments on commit 1e45dd9

Please sign in to comment.