allow for adoption of relations to a predicate interface;
with example implementation for a 'has Role' predicate in loops.organize
This commit is contained in:
parent
2709f73f94
commit
a8fce100fa
8 changed files with 111 additions and 29 deletions
|
@ -6,6 +6,8 @@ $Id$
|
|||
1.1
|
||||
---
|
||||
|
||||
- allow for adoption of relations to a predicate interface;
|
||||
with example implementation for a 'has Role' predicate in loops.organize
|
||||
- external collection: provide functionality for automatically populate
|
||||
meta information of media assets
|
||||
- new query for retrieving work items independently of task or user
|
||||
|
|
|
@ -729,6 +729,12 @@ class IPredicate(IConceptSchema):
|
|||
required=False)
|
||||
|
||||
|
||||
class IRelationAdapter(Interface):
|
||||
""" Base interface for adapters to relations that allow the specification
|
||||
of special properties of a relation.
|
||||
"""
|
||||
|
||||
|
||||
# probably not useful
|
||||
class xxIMappingAttributeRelation(IConceptSchema):
|
||||
""" A relation based on a predicate ('mappingAttribute') that provides
|
||||
|
|
|
@ -390,15 +390,6 @@ Events listing
|
|||
>>> list(listing.events())
|
||||
[<loops.browser.concept.ConceptRelationView ...>]
|
||||
|
||||
Allocation of persons to tasks
|
||||
------------------------------
|
||||
|
||||
>>> from loops.organize.interfaces import IAllocated
|
||||
>>> predicate = concepts['predicate']
|
||||
>>> allocated = addAndConfigureObject(concepts, Concept, 'allocated',
|
||||
... title=u'allocated',
|
||||
... conceptType=predicate, predicateInterface=IAllocated)
|
||||
|
||||
|
||||
Send Email to Members
|
||||
=====================
|
||||
|
@ -423,6 +414,45 @@ Show Presence of Other Users
|
|||
>>> component.provideUtility(Presence())
|
||||
|
||||
|
||||
Roles of Persons
|
||||
================
|
||||
|
||||
When persons are assigned to a parent (e.g. an instutution or a project)
|
||||
this assignment may be characterized by a certain role. This role may
|
||||
be specified by using a special predicate that is associated with a
|
||||
predicate interface that allows to specify the role.
|
||||
|
||||
(Note that the security-relevant assignment of persons is managed via
|
||||
other special predicates: 'ismember', 'ismaster'. The 'hasrole'
|
||||
predicate described here is intended for situations where the roles
|
||||
may be chosen from an arbitrary list.)
|
||||
|
||||
>>> from loops.organize.interfaces import IHasRole
|
||||
>>> predicate = concepts['predicate']
|
||||
>>> hasRole = addAndConfigureObject(concepts, Concept, 'hasrole',
|
||||
... title=u'has Role',
|
||||
... conceptType=predicate, predicateInterface=IHasRole)
|
||||
|
||||
Let's now assign john to task01 and have a look at the relation created.
|
||||
|
||||
>>> task01.assignChild(john, hasRole)
|
||||
>>> relation = task01.getChildRelations([hasRole])[0]
|
||||
|
||||
The role may be accessed by getting a relation adapter
|
||||
|
||||
>>> from loops.predicate import adaptedRelation
|
||||
>>> adRelation = adaptedRelation(relation)
|
||||
>>> adRelation.role is None
|
||||
True
|
||||
|
||||
>>> adRelation.role = 'member'
|
||||
>>> relation._role
|
||||
'member'
|
||||
>>> adRelation = adaptedRelation(relation)
|
||||
>>> adRelation.role
|
||||
'member'
|
||||
|
||||
|
||||
Calendar
|
||||
========
|
||||
|
||||
|
|
|
@ -39,6 +39,16 @@
|
|||
set_schema="loops.organize.interfaces.ITask" />
|
||||
</zope:class>
|
||||
|
||||
<zope:adapter factory="loops.organize.party.HasRole"
|
||||
provides="loops.organize.interfaces.IHasRole"
|
||||
trusted="True" />
|
||||
<zope:class class="loops.organize.party.HasRole">
|
||||
<require permission="zope.View"
|
||||
interface="loops.organize.interfaces.IHasRole" />
|
||||
<require permission="zope.ManageContent"
|
||||
set_schema="loops.organize.interfaces.IHasRole" />
|
||||
</zope:class>
|
||||
|
||||
<!-- member registration -->
|
||||
|
||||
<zope:adapter factory="loops.organize.member.MemberRegistrationManager"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2009 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -32,9 +32,8 @@ from zope.security.proxy import removeSecurityProxy
|
|||
from cybertools.organize.interfaces import IAddress as IBaseAddress
|
||||
from cybertools.organize.interfaces import IPerson as IBasePerson
|
||||
from cybertools.organize.interfaces import ITask
|
||||
from loops.interfaces import IConceptSchema
|
||||
from loops.interfaces import ILoopsAdapter, IConceptSchema, IRelationAdapter
|
||||
from loops.organize.util import getPrincipalFolder
|
||||
from loops.interfaces import ILoopsAdapter
|
||||
from loops import util
|
||||
from loops.util import _
|
||||
|
||||
|
@ -164,19 +163,20 @@ class ITask(IConceptSchema, ITask, ILoopsAdapter):
|
|||
pass
|
||||
|
||||
|
||||
# 'allocated' predicate
|
||||
# 'hasrole' predicate
|
||||
|
||||
class IAllocated(IConceptSchema):
|
||||
class IHasRole(IRelationAdapter):
|
||||
|
||||
allocType = schema.Choice(
|
||||
title=_(u'Allocation Type'),
|
||||
role = schema.Choice(
|
||||
title=_(u'Role'),
|
||||
description=_(u'Specifies the kind of interaction a person or another '
|
||||
u'party has with the task or project it is allocated to.'),
|
||||
u'party has with an institution, a task, or a project '
|
||||
u'it is associated with.'),
|
||||
source=util.KeywordVocabulary((
|
||||
('standard', _(u'Standard')),
|
||||
('member', _(u'Member')),
|
||||
('master', _(u'Master')),
|
||||
)),
|
||||
default='standard',
|
||||
default='member',
|
||||
required=True)
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2009 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -40,8 +40,9 @@ from cybertools.typology.interfaces import IType
|
|||
from loops.common import AdapterBase
|
||||
from loops.concept import Concept
|
||||
from loops.interfaces import IConcept
|
||||
from loops.organize.interfaces import IAddress, IPerson, IAllocated
|
||||
from loops.organize.interfaces import IAddress, IPerson, IHasRole
|
||||
from loops.organize.interfaces import ANNOTATION_KEY
|
||||
from loops.predicate import RelationAdapter
|
||||
from loops.security.common import assignOwner, removeOwner, allowEditingForOwner
|
||||
from loops.type import TypeInterfaceSourceList
|
||||
from loops.predicate import PredicateInterfaceSourceList
|
||||
|
@ -51,7 +52,7 @@ from loops import util
|
|||
# register type interfaces - (TODO: use a function for this)
|
||||
|
||||
TypeInterfaceSourceList.typeInterfaces += (IPerson, IAddress)
|
||||
PredicateInterfaceSourceList.typeInterfaces += (IAllocated,)
|
||||
PredicateInterfaceSourceList.predicateInterfaces += (IHasRole,)
|
||||
|
||||
|
||||
def getPersonForUser(context, request=None, principal=None):
|
||||
|
@ -177,3 +178,11 @@ class Address(AdapterBase):
|
|||
self.context._lines = value
|
||||
lines = property(getLines, setLines)
|
||||
|
||||
|
||||
class HasRole(RelationAdapter):
|
||||
""" Allows specification of a role for a relation.
|
||||
"""
|
||||
|
||||
implements(IHasRole)
|
||||
|
||||
_contextAttributes = list(IHasRole)
|
||||
|
|
|
@ -23,8 +23,8 @@ from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
|
|||
from cybertools.util.jeep import Jeep
|
||||
from loops.common import adapted
|
||||
from loops.concept import Concept
|
||||
from loops.organize.interfaces import IPerson
|
||||
from loops.organize.party import Person
|
||||
from loops.organize.interfaces import IPerson, IHasRole
|
||||
from loops.organize.party import Person, HasRole
|
||||
from loops.organize.task import Task
|
||||
from loops.setup import addAndConfigureObject
|
||||
from loops.tests.auth import login
|
||||
|
@ -38,6 +38,7 @@ def setupUtilitiesAndAdapters(loopsRoot):
|
|||
component.provideAdapter(Person, provides=IPerson)
|
||||
component.provideAdapter(Task)
|
||||
component.provideAdapter(FoundPrincipalFactory)
|
||||
component.provideAdapter(HasRole, provides=IHasRole)
|
||||
return Jeep((
|
||||
('auth', auth),
|
||||
('principalAnnotations', principalAnnotations),
|
||||
|
|
34
predicate.py
34
predicate.py
|
@ -30,10 +30,10 @@ from zope.dottedname.resolve import resolve
|
|||
from zope.security.proxy import removeSecurityProxy
|
||||
from zope.traversing.api import getName
|
||||
|
||||
from loops.interfaces import ILoopsObject, IConcept, IResource
|
||||
from loops.interfaces import IPredicate #, IMappingAttributeRelation
|
||||
from loops.interfaces import ILoopsObject, IConcept, IResource, IConceptRelation
|
||||
from loops.interfaces import IPredicate, IRelationAdapter #, IMappingAttributeRelation
|
||||
from loops.concept import Concept
|
||||
from loops.common import AdapterBase
|
||||
from loops.common import adapted, AdapterBase
|
||||
from loops.type import TypeInterfaceSourceList
|
||||
|
||||
|
||||
|
@ -60,12 +60,36 @@ class PredicateInterfaceSourceList(TypeInterfaceSourceList):
|
|||
may be used for specifying additional attributes of relations.
|
||||
"""
|
||||
|
||||
typeInterfaces = ()
|
||||
predicateInterfaces = ()
|
||||
|
||||
@property
|
||||
def typeInterfaces(self):
|
||||
return self.predicateInterfaces
|
||||
|
||||
|
||||
class RelationAdapter(AdapterBase):
|
||||
""" Base class for adapters to relations that may be used for
|
||||
specifying additional attributes for relations.
|
||||
"""
|
||||
|
||||
implements(IRelationAdapter)
|
||||
adapts(IConceptRelation)
|
||||
|
||||
|
||||
def adaptedRelation(relation):
|
||||
if isinstance(relation, RelationAdapter):
|
||||
return obj
|
||||
ifc = adapted(relation.predicate).predicateInterface
|
||||
if ifc is not None:
|
||||
adRelation = component.queryAdapter(relation, ifc)
|
||||
if adRelation is not None:
|
||||
return adRelation
|
||||
return relation
|
||||
|
||||
|
||||
# standard relation adapters
|
||||
|
||||
#PredicateInterfaceSourceList.typeInterfaces += (IMappingAttributeRelation,)
|
||||
#PredicateInterfaceSourceList.predicateInterfaces += (IMappingAttributeRelation,)
|
||||
|
||||
|
||||
#class MappingAttributeRelation(AdapterBase):
|
||||
|
|
Loading…
Add table
Reference in a new issue