예제 #1
0
파일: common.py 프로젝트: rxncon/workbench
class UUIDAware(Behavior):
    uuid = default(None)
    overwrite_recursiv_on_copy = default(True)

    @plumb
    def __init__(_next, self, *args, **kw):
        _next(self, *args, **kw)
        self.uuid = uuid.uuid4()

    @plumb
    def copy(_next, self):
        raise RuntimeError(u"Shallow copy useless on UUID aware node trees, "
                           u"use deepcopy.")

    @plumb
    def deepcopy(_next, self):
        copied = _next(self)
        self.set_uuid_for(copied, True, self.overwrite_recursiv_on_copy)
        return copied

    @default
    def set_uuid_for(self, node, override=False, recursiv=False):
        if IUUIDAware.providedBy(node):
            if override or not node.uuid:
                node.uuid = uuid.uuid4()
        if recursiv:
            for child in node.values():
                self.set_uuid_for(child, override, recursiv)
예제 #2
0
class ProtectedAttributesForm(Behavior):
    """Plumbing behavior supposed to be used for yafowil forms calculating
    widget modes based on security checks.

    Security declarations for attributes are stored at
    ``self.attribute_permissions`` containing the attribute names as key, and
    a 2-tuple containing required edit and view permission for this attribute.
    """

    attribute_permissions = default(dict())
    attribute_default_permissions = default(('edit', 'view'))

    @default
    def mode_for(self, name):
        """Calculate mode by checking permission defined in
        ``self.attribute_permissions`` for attribute ``name`` against model.

        If no permissions defined for attribute name,
        ``self.attribute_default_permissions`` is used.
        """
        permissions = self.attribute_permissions.get(name)
        if not permissions:
            permissions = self.attribute_default_permissions
        if has_permission(permissions[0], self.model, self.request):
            return 'edit'
        if has_permission(permissions[1], self.model, self.request):
            return 'display'
        return 'skip'
예제 #3
0
 def test_default(self):
     # First default wins from left to right
     def1 = default(1)
     self.assertTrue(def1 + def1 is def1)
     def2 = default(2)
     self.assertTrue(def1 + def2 is def1)
     self.assertTrue(def2 + def1 is def2)
     # Override wins over default
     ext3 = override(3)
     self.assertTrue(def1 + ext3 is ext3)
     # Finalize wins over default
     fin4 = finalize(4)
     self.assertTrue(def1 + fin4 is fin4)
     # Adding with something else than default/override, raises
     # ``PlumbingCollision``
     err = None
     try:
         def1 + Instruction('foo')
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'default')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 'foo')
예제 #4
0
 class Behavior2(Behavior1):
     # overrides ``J`` of ``Behavior1``
     J = default('Behavior2')
     L = default('Behavior2')
     # this one wins, even if ``M`` on superclass is ``override``
     # instruction due to ordinary inheritance behavior.
     M = default('Behavior2')
예제 #5
0
 def test_default(self):
     # First default wins from left to right
     def1 = default(1)
     self.assertTrue(def1 + def1 is def1)
     def2 = default(2)
     self.assertTrue(def1 + def2 is def1)
     self.assertTrue(def2 + def1 is def2)
     # Override wins over default
     ext3 = override(3)
     self.assertTrue(def1 + ext3 is ext3)
     # Finalize wins over default
     fin4 = finalize(4)
     self.assertTrue(def1 + fin4 is fin4)
     # Adding with something else than default/override, raises
     # ``PlumbingCollision``
     err = None
     try:
         def1 + Instruction('foo')
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'default')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 'foo')
예제 #6
0
class ContentForm(FormHeading):
    """Form behavior rendering to content area.
    """
    show_heading = default(True)
    show_contextmenu = default(True)

    @default
    @property
    def form_heading(self):
        return _('content_form_heading', default='Content Form Heading')

    @default
    @property
    def rendered_contextmenu(self):
        return render_tile(self.model, self.request, 'contextmenu')

    @plumb
    def __call__(_next, self, model, request):
        ajax_form_fiddle(request, '#content', 'inner')
        form = _next(self, model, request)
        if not form:
            form = u''
        self.rendered_form = form
        path = self.path
        if not path:
            path = 'cone.app.browser:templates/content_form.pt'
        return render_template(path,
                               request=request,
                               model=model,
                               context=self)
예제 #7
0
class ZODBAttributes(Behavior):
    attribute_access_for_attrs = default(False)
    attributes_factory = default(None)

    @finalize
    @property
    def attrs(self):
        try:
            attrs = self._attrs
        except AttributeError:
            self._attrs = attrs = self.attributes_factory(name='_attrs',
                                                          parent=self)
        if self.attribute_access_for_attrs:
            return AttributeAccess(attrs)
        return attrs
예제 #8
0
class SQLRowStorage(Behavior):
    # SQL alchemy model class
    record_class = default(None)
    # SQL alchemy session
    session = default(None)

    @override
    def __init__(self, name=None, parent=None, record=None):
        self.__name__ = name
        self.__parent__ = parent
        self._new = False
        if record is None:
            self._new = True
            record = self.record_class()
        self.record = record

    @override
    def attributes_factory(self, name, parent):
        return SQLRowNodeAttributes(name, parent, self.record)

    @finalize
    def __setitem__(self, name, value):
        raise KeyError(name)

    @finalize
    def __getitem__(self, name):
        raise KeyError(name)

    @finalize
    def __delitem__(self, name):  # pragma: no cover
        # not reached by default SQLRowNode, KeyError already thrown in
        # Lifecycle plumbing Behavior
        raise KeyError(name)

    @finalize
    def __iter__(self):
        return iter([])

    @finalize
    def __call__(self):
        session = self.session
        if self._new:
            session.add(self.record)
            self._new = False
        if use_tm():
            self.session.flush()
        else:
            self.session.commit()
예제 #9
0
 def test_finalize(self):
     # First override wins against following equal overrides and arbitrary
     # defaults
     fin1 = finalize(1)
     self.assertTrue(fin1 + fin1 is fin1)
     self.assertTrue(fin1 + finalize(1) is fin1)
     self.assertTrue(fin1 + default(2) is fin1)
     self.assertTrue(fin1 + override(2) is fin1)
     # Two unequal finalize collide
     err = None
     try:
         fin1 + finalize(2)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'finalize')
         self.assertEqual(err.right.payload, 2)
     # Everything except default/override collides
     try:
         fin1 + Instruction(1)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 1)
예제 #10
0
class AppNode(Behavior):
    node_info_name = default('')

    @default
    @property
    def __acl__(self):
        return acl_registry.lookup(self.__class__, self.node_info_name)

    @default
    @instance_property
    def properties(self):
        props = Properties()
        props.in_navtree = False
        return props

    @default
    @instance_property
    def metadata(self):
        name = self.name
        if not name:
            name = _('no_title', default='No Title')
        metadata = Metadata()
        metadata.title = name
        return metadata

    @default
    @property
    def nodeinfo(self):
        info = get_node_info(self.node_info_name)
        if not info:
            info = NodeInfo()
            info.title = str(self.__class__)
            info.node = self.__class__
            info.icon = app_config().default_node_icon
        return info
예제 #11
0
 def test_finalize(self):
     # First override wins against following equal overrides and arbitrary
     # defaults
     fin1 = finalize(1)
     self.assertTrue(fin1 + fin1 is fin1)
     self.assertTrue(fin1 + finalize(1) is fin1)
     self.assertTrue(fin1 + default(2) is fin1)
     self.assertTrue(fin1 + override(2) is fin1)
     # Two unequal finalize collide
     err = None
     try:
         fin1 + finalize(2)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'finalize')
         self.assertEqual(err.right.payload, 2)
     # Everything except default/override collides
     try:
         fin1 + Instruction(1)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'finalize')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 1)
예제 #12
0
class OwnerSupport(Behavior):
    """Plumbing behavior providing ownership information.
    """

    @plumb
    def __init__(_next, self, *args, **kw):
        _next(self, *args, **kw)
        if not self.owner:
            request = get_current_request()
            self.owner = authenticated_userid(request)

    @plumb
    @property
    def __acl__(_next, self):
        acl = _next(self)
        if self.owner:
            for ace in acl:
                if ace[1] == 'role:owner':
                    return [(Allow, self.owner, ace[2])] + acl
        return acl

    def _get_owner(self):
        return self.attrs.get('owner')

    def _set_owner(self, value):
        self.attrs['owner'] = value

    owner = default(property(_get_owner, _set_owner))
예제 #13
0
class PrincipalACL(Behavior):
    """Plumbing behavior providing principal ACL's.

    Warning: This behavior works only for nodes defining the ``__acl__``
    attribute as property function. Plumber does not support class property
    plumbing (yet).
    """
    role_inheritance = default(False)

    @default
    @property
    def principal_roles(self):
        raise NotImplementedError(u"Abstract ``PrincipalACL`` does not "
                                  u"implement ``principal_roles``.")

    @default
    @property
    def aggregated_roles(self):
        aggregated = dict()
        model = self
        while model:
            if not IPrincipalACL.providedBy(model):
                model = model.parent
                continue
            for id, roles in model.principal_roles.items():
                if aggregated.get(id):
                    aggregated[id].update(roles)
                else:
                    aggregated[id] = set(roles)
            model = model.parent
        return aggregated

    @default
    def aggregated_roles_for(self, principal_id):
        return list(self.aggregated_roles.get(principal_id, list()))

    @plumb
    @property
    def __acl__(_next, self):
        base_acl = _next(self)
        acl = list()
        if self.role_inheritance:
            principal_roles = self.aggregated_roles
        else:
            principal_roles = self.principal_roles
        for id, roles in principal_roles.items():
            aggregated = set()
            for role in roles:
                aggregated.update(self._permissions_for_role(base_acl, role))
            acl.append((Allow, id, list(aggregated)))
        for ace in base_acl:
            acl.append(ace)
        return acl

    @default
    def _permissions_for_role(self, acl, role):
        for ace in acl:
            if ace[1] == 'role:%s' % role:
                return ace[2]
        return list()
예제 #14
0
class SubscriberDecoratorBehavior(Behavior):
    attr = EventAttribute()

    @attr.subscriber
    def attr_changed(self, value):
        self.changed_value = value

    attr = default(attr)
예제 #15
0
파일: model.py 프로젝트: SaiyaGin/cone.app
class UUIDAttributeAware(UUIDAware):
    def _get_uuid(self):
        return self.attrs['uuid']

    def _set_uuid(self, value):
        self.attrs['uuid'] = value

    uuid = default(property(_get_uuid, _set_uuid))
예제 #16
0
class Lifecycle(Behavior):

    events = default({
        'created': NodeCreatedEvent,
        'added': NodeAddedEvent,
        'modified': NodeModifiedEvent,
        'removed': NodeRemovedEvent,
        'detached': NodeDetachedEvent,
    })

    _notify_suppress = default(False)

    @plumb
    def __init__(_next, self, *args, **kw):
        _next(self, *args, **kw)
        objectEventNotify(self.events['created'](self))

    @plumb
    def __setitem__(_next, self, key, val):
        _next(self, key, val)
        if self._notify_suppress:
            return
        objectEventNotify(self.events['added'](val,
                                               newParent=self,
                                               newName=key))

    @plumb
    def __delitem__(_next, self, key):
        delnode = self[key]
        _next(self, key)
        if self._notify_suppress:
            return
        objectEventNotify(self.events['removed'](delnode,
                                                 oldParent=self,
                                                 oldName=key))

    @plumb
    def detach(_next, self, key):
        self._notify_suppress = True
        node = _next(self, key)
        self._notify_suppress = False
        objectEventNotify(self.events['detached'](node,
                                                  oldParent=self,
                                                  oldName=key))
        return node
예제 #17
0
class Attributes(Behavior):
    attribute_access_for_attrs = default(False)
    attributes_factory = default(NodeAttributes)

    @finalize
    @property
    def attrs(self):
        try:
            attrs = self.nodespaces['__attrs__']
        except KeyError:
            attrs = self.nodespaces['__attrs__'] = \
                self.attributes_factory(name='__attrs__', parent=self)
        if self.attribute_access_for_attrs:
            return AttributeAccess(attrs)
        return attrs

    # BBB
    attributes = finalize(attrs)
예제 #18
0
파일: ugm.py 프로젝트: zworkb/cone.sql
class PrincipalBehavior(Behavior):

    record = default(None)
    """Reference to sqlalchemy record instance."""

    @override
    def __init__(self, parent, record):
        self.__parent__ = parent
        self.record = record

    @default
    @property
    def __name__(self):
        return self.id

    @default
    @property
    def ugm(self):
        return self.parent.parent

    @default
    @property
    def id(self):
        return self.record.id

    @default
    def add_role(self, role):
        if role not in self.own_roles:
            self.own_roles = self.own_roles + [role]

    @default
    def remove_role(self, role):
        if role in self.own_roles:
            # to trigger the json field
            self.own_roles = [r for r in self.own_roles if r != role]

    @property
    def own_roles(self):
        return self.record.principal_roles

    @default
    @own_roles.setter
    def own_roles(self, roles):
        self.record.principal_roles = roles

    @default
    @property
    def roles(self):
        return self.own_roles

    @default
    def __call__(self):
        if use_tm():
            self.session.flush()
        else:
            self.session.commit()
예제 #19
0
파일: common.py 프로젝트: rxncon/workbench
class NodeChildValidate(Behavior):
    allow_non_node_childs = default(False)

    @plumb
    def __setitem__(_next, self, key, val):
        if not self.allow_non_node_childs and inspect.isclass(val):
            raise ValueError(u"It isn't allowed to use classes as values.")
        if not self.allow_non_node_childs and not INode.providedBy(val):
            raise ValueError("Non-node childs are not allowed.")
        _next(self, key, val)
예제 #20
0
class YAMLForm(Behavior):
    """Plumbing behavior for rendering yaml forms.
    """

    action_resource = default(u'')

    # B/C
    form_template_path = default(None)

    # use form_template for pointing yaml files
    form_template = default(None)

    # considered in form_action, either 'add' or 'edit'
    form_flavor = default('edit')

    @default
    @property
    def message_factory(self):
        return None

    @default
    def form_action(self, widget, data):
        resource = self.action_resource
        if self.form_flavor == 'add':
            return make_url(self.request,
                            node=self.model.parent,
                            resource=resource)
        return make_url(self.request, node=self.model, resource=resource)

    @override
    def prepare(self):
        if self.form_template:
            self.form = parse_from_YAML(self.form_template, self,
                                        self.message_factory)
            return
        # BBB
        self.form = parse_from_YAML(self.form_template_path, self,
                                    self.message_factory)
예제 #21
0
class Nodespaces(Behavior):
    _nodespaces = default(None)

    @finalize
    @property
    def nodespaces(self):
        """A storage and general way to access our nodespaces.

        An ``AttributedNode`` uses this to store the ``attrs`` nodespace i.e.
        """
        if self._nodespaces is None:
            self._nodespaces = odict()
            self._nodespaces['__children__'] = self
        return self._nodespaces

    @plumb
    def __getitem__(_next, self, key):
        # blend in our nodespaces as children, with name __<name>__
        # isinstance check is required because odict tries to get item possibly
        # with ``_nil`` key, which is actually an object
        if isinstance(key, basestring) \
          and key.startswith('__') \
          and key.endswith('__'):
            # a reserved child key mapped to the nodespace behind
            # nodespaces[key], nodespaces is an odict
            return self.nodespaces[key]
        return _next(self, key)

    @plumb
    def __setitem__(_next, self, key, val):
        # blend in our nodespaces as children, with name __<name>__
        if key.startswith('__') and key.endswith('__'):
            # a reserved child key mapped to the nodespace behind
            # nodespaces[key], nodespaces is an odict
            val.__name__ = key
            val.__parent__ = self
            self.nodespaces[key] = val
            # index checks below must not happen for other nodespace.
            return
        _next(self, key, val)

    @plumb
    def __delitem__(_next, self, key):
        # blend in our nodespaces as children, with name __<name>__
        if key.startswith('__') and key.endswith('__'):
            # a reserved child key mapped to the nodespace behind
            # nodespaces[key], nodespaces is an odict
            del self.nodespaces[key]
            return
        _next(self, key)
예제 #22
0
class LDAPGroups(LDAPGroupsMapping):

    principal_factory = default(Group)

    @override
    @locktree
    def __delitem__(self, key):
        key = decode_utf8(key)
        group = self[key]
        parent = self.parent
        if parent and parent.rcfg is not None:
            for role in group.roles:
                group.remove_role(role)
        del self.context[key]
예제 #23
0
class LDAPGroups(LDAPGroupsMapping):
    principal_factory = default(Group)

    @override
    @locktree
    def __delitem__(self, key):
        group = self[key]
        parent = self.parent
        if parent and parent.rcfg is not None:
            for role in group.roles:
                group.remove_role(role)
        context = group.context
        del context.parent[context.name]
        del self.storage[key]
예제 #24
0
class WorkflowState(Behavior):
    """Behavior for nodes providing workflow states.

    This implementation persists to self.attrs['state']
    """
    workflow_tsf = default(None)
    workflow_name = default(None)

    @plumb
    def __init__(_next, self, *args, **kw):
        _next(self, *args, **kw)
        initialize_workflow(self)

    @plumb
    def copy(_next, self):
        """Set initial state for copied node and all children providing
        ``cone.app.interfaces.IWorkflowState``.
        """
        ret = _next(self)

        def recursiv_initial_state(node):
            if IWorkflowState.providedBy(node):
                initialize_workflow(node, force=True)
                for child in node.values():
                    recursiv_initial_state(child)

        recursiv_initial_state(ret)
        return ret

    @property
    def state(self):
        return self.attrs.get('state', None)

    @default
    @state.setter
    def state(self, val):
        self.attrs['state'] = val
예제 #25
0
class Alias(Behavior):
    aliaser = default(None)

    @plumb
    def __getitem__(_next, self, key):
        if self.aliaser:
            unaliased_key = self.aliaser.unalias(key)
        else:
            unaliased_key = key
        try:
            return _next(self, unaliased_key)
        except KeyError:
            raise KeyError(key)

    @plumb
    def __setitem__(_next, self, key, val):
        if self.aliaser:
            unaliased_key = self.aliaser.unalias(key)
        else:
            unaliased_key = key
        try:
            _next(self, unaliased_key, val)
        except KeyError:
            raise KeyError(key)

    @plumb
    def __delitem__(_next, self, key):
        if self.aliaser:
            unaliased_key = self.aliaser.unalias(key)
        else:
            unaliased_key = key
        try:
            _next(self, unaliased_key)
        except KeyError:
            raise KeyError(key)

    @plumb
    def __iter__(_next, self):
        for key in _next(self):
            try:
                if self.aliaser:
                    yield self.aliaser.alias(key)
                else:
                    yield key
            except KeyError:
                if IEnumerableMapping.providedBy(self.aliaser):
                    # an enumerable aliaser whitelists, we skip non-listed keys
                    continue
                raise
예제 #26
0
class WorkflowACL(Behavior):
    """Behavior providing ACL's by worfklow state.

    Requires ``WorkflowState`` behavior.
    """
    state_acls = default(dict())
    default_acl = default([
        (Allow, 'system.Authenticated', ['view']),
        (Allow, 'role:viewer', ['view']),
        (Allow, 'role:editor', ['view', 'add', 'edit']),
        (Allow, 'role:owner', [
            'view', 'add', 'edit', 'delete', 'change_state',
            'manage_permissions'
        ]),
        (Allow, 'role:admin', [
            'view', 'add', 'edit', 'delete', 'change_state',
            'manage_permissions'
        ]),
        (Allow, 'role:manager', [
            'view', 'add', 'edit', 'delete', 'change_state',
            'manage_permissions', 'manage'
        ]),
        (Allow, Everyone, ['login']),
        (Deny, Everyone, ALL_PERMISSIONS),
    ])

    @override
    @property
    def __acl__(self):
        acl = self.state_acls.get(self.state, self.default_acl)
        if not acl:
            raise ValueError(u"No ACL found for state '%s'" % self.state)
        if acl is self.default_acl:
            logger.warning(u"No ACL found for state "
                           u"'%s'. Using default" % self.state)
        return acl
예제 #27
0
파일: ugm.py 프로젝트: zworkb/cone.sql
class GroupsBehavior(PrincipalsBehavior, BaseGroups):
    record_class = default(SQLGroup)

    @default
    def create(self, _id, **kw):
        for name, value in kw.items():
            if value and name in self.ugm.binary_attrs:
                kw[name] = base64.b64encode(value).decode()
        sqlgroup = SQLGroup(id=_id, data=kw)
        self.session.add(sqlgroup)
        self.session.flush()
        return self[_id]

    @default
    def __getitem__(self, id, default=None):
        try:
            sqlgroup = self.session\
                .query(SQLGroup)\
                .filter(SQLGroup.id == id)\
                .one()
        except NoResultFound:
            raise KeyError(id)
        return Group(self, sqlgroup)

    @default
    def __delitem__(self, id):
        try:
            sqlgroup = self.session\
                .query(SQLGroup)\
                .filter(SQLGroup.id == id)\
                .one()
            self.session.delete(sqlgroup)
        except NoResultFound:
            raise KeyError(id)

    @default
    def __iter__(self):
        groups = self.session.query(SQLGroup)
        return iter(map(lambda u: u.id, groups))

    @default
    def __setitem__(self, key, value):
        msg = 'groups can only be added using the create() method'
        raise NotImplementedError(msg)

    @default
    def invalidate(self, key=None, *a, **kw):
        self.parent.invalidate(key='groups')
예제 #28
0
파일: common.py 프로젝트: rxncon/workbench
class ChildFactory(Behavior):
    factories = default(odict())

    @override
    def __iter__(self):
        return self.factories.__iter__()

    iterkeys = override(__iter__)

    @plumb
    def __getitem__(_next, self, key):
        try:
            child = _next(self, key)
        except KeyError:
            child = self.factories[key]()
            self[key] = child
        return child
예제 #29
0
파일: model.py 프로젝트: zworkb/cone.app
class NamespaceUUID(Behavior):
    """Behavior calculating ``uuid`` by node path and namespace.
    """
    uuid_namespace = default(uuid.UUID('83438507-fdff-45a2-af47-1e001884eab9'))

    @property
    def uuid(self):
        if self.__name__ is None and self.__parent__ is None:
            return None
        return uuid.uuid5(self.uuid_namespace,
                          '/'.join([_ for _ in self.path if _ is not None]))

    @finalize
    @uuid.setter
    def uuid(self, uuid):
        msg = 'Ignore attempt to set {}.uuid'.format(self.__class__.__name__)
        raise NotImplementedError(msg)
예제 #30
0
class AppNode(Behavior):
    node_info_name = default('')

    @default
    @property
    def __acl__(self):
        return acl_registry.lookup(self.__class__, self.node_info_name)

    @default
    @property
    def layout(self):
        props = self.properties
        if props.default_child:
            return self[props.default_child].layout
        # XXX: consider adding and return add model layout here?
        return get_current_registry().getAdapter(self, ILayout)

    @default
    @instance_property
    def properties(self):
        props = Properties()
        props.in_navtree = False
        return props

    @default
    @instance_property
    def metadata(self):
        name = self.name
        if not name:
            name = _('no_title', default='No Title')
        metadata = Metadata()
        metadata.title = name
        return metadata

    @default
    @property
    def nodeinfo(self):
        info = get_node_info(self.node_info_name)
        if not info:
            info = NodeInfo()
            info.title = str(self.__class__)
            info.node = self.__class__
            info.icon = app_config().default_node_icon
        return info
예제 #31
0
class RelatedViewProvider(Behavior):
    """Plumbing behavior for providing related view name.

    This behavior can be applied on tiles and is supposed to be used to set
    a related view name for the current request.

    This related view name can be used then by nested tiles to create browser
    URLs.
    """

    related_view = default(None)
    """Related view name to set on request.
    """
    @plumb
    def __call__(_next, self, model, request):
        """Set related view on request and call downstream function.
        """
        set_related_view(request, self.related_view)
        return _next(self, model, request)
예제 #32
0
class Fallback(Behavior):
    fallback_key = default(_marker)

    @plumb
    def __getitem__(_next, self, key):
        """If key not found, look for fallback_key on parent(s) with the same
        subpath, take it's children and look there, fall back to unvisited
        parents until no fallback left.
        """
        try:
            value = _next(self, key)
        except KeyError:
            with fallback_processing() as count:
                if count > 0:
                    raise
                value = _to_root(self, path=self.path + [key], visited=set())
                if value is _marker:
                    raise
        return value
예제 #33
0
 def test_override(self):
     # First override wins against following equal overrides and arbitrary
     # defaults
     ext1 = override(1)
     self.assertTrue(ext1 + ext1 is ext1)
     self.assertTrue(ext1 + override(1) is ext1)
     self.assertTrue(ext1 + override(2) is ext1)
     self.assertTrue(ext1 + default(2) is ext1)
     fin3 = finalize(3)
     self.assertTrue(ext1 + fin3 is fin3)
     # Everything except default/override collides
     err = None
     try:
         ext1 + Instruction(1)
     except PlumbingCollision as e:
         err = e
     finally:
         self.assertEqual(err.left.__class__.__name__, 'override')
         self.assertEqual(err.left.payload, 1)
         self.assertEqual(err.right.__class__.__name__, 'Instruction')
         self.assertEqual(err.right.payload, 1)
예제 #34
0
            except KeyError:
                # No attributes loaded, yet - cannot be changed
                pass
            childs = getattr(self, '_deleted', [])
            if self._keys is not None:
                childs.extend(
                    filter(lambda x: x is not None, self._keys.values()))
            for child in childs:
                if child.changed:
                    return
            self._changed = False
        # And propagate to parent
        if self._changed is not oldval and self.parent is not None:
            self.parent.changed = self._changed

    changed = default(property(_get_changed, _set_changed))

    # This is really ldap
    @default
    def child_dn(self, key):
        return self._child_dns[key]

    @default
    @debug
    def search(self, queryFilter=None, criteria=None, attrlist=None, 
               relation=None, relation_node=None, exact_match=False, 
               or_search=False):
        attrset = set(attrlist or [])
        attrset.discard('dn')
        # fetch also the key attribute
        if not self._key_attr == 'rdn':