diff --git a/browser/configure.zcml b/browser/configure.zcml
index cc85c29..a30e766 100644
--- a/browser/configure.zcml
+++ b/browser/configure.zcml
@@ -7,67 +7,60 @@
>
-
-
diff --git a/concept.py b/concept.py
index f51c27b..f0bb321 100644
--- a/concept.py
+++ b/concept.py
@@ -17,193 +17,67 @@
#
"""
-Definition of the Task class.
+Definition of the Concept class.
$Id$
"""
-from zope.interface import implements
-from zope.app.container.ordered import OrderedContainer
-from zope.app.copypastemove import ObjectCopier
from zope.app import zapi
-from zope.schema.fieldproperty import FieldProperty
-from zope.component.interfaces import IFactory
+from zope.interface import implements
+from persistent import Persistent
from cybertools.relation.interfaces import IRelationsRegistry
from cybertools.relation import DyadicRelation
-#from relation import Relation, Relations
-from resource import Resource
-from interfaces import ITask
-
-from copy import copy
+from interfaces import IConcept
-class SubtaskRelation(DyadicRelation):
- """ Relation of a first task (the parent task) to a second task
- (the subtask).
- """
+class Concept(Persistent):
+ implements(IConcept)
-class Task(OrderedContainer):
-
- implements(ITask)
-
- title = u''
- qualifier = u''
- priority = FieldProperty(ITask['priority'])
+ _title = u''
+ def getTitle(self): return self._title
+ def setTitle(self, title): self._title = title
+ title = property(getTitle, setTitle)
def __init__(self, name=None, title=u''):
- OrderedContainer.__init__(self)
- if name:
- self.__name__ = name
- if title:
- self.title = title
+ self.title = title
- # subtasks:
+ # concept relations:
- def getSubtasks(self, taskTypes=None):
+ def getSubConcepts(self, relationships=None):
+ rels = getRelations(first=self, relationships=relationships)
+ return [r.second for r in rels]
+ # TODO: sort...
+
+ def getParentConcepts(self, relationships=None):
+ rels = getRelations(second=self, relationships=relationships)
+ return [r.first for r in rels]
+
+ def assignConcept(self, concept, relationship):
registry = zapi.getUtility(IRelationsRegistry)
- return [r.second
- for r in registry.query(relationship=SubtaskRelation,
- first=self)]
- # TODO: sort according to priority
-
- def getParentTasks(self, taskTypes=None):
- registry = zapi.getUtility(IRelationsRegistry)
- return [r.first
- for r in registry.query(relationship=SubtaskRelation,
- second=self)]
-
- def assignSubtask(self, task):
- registry = zapi.getUtility(IRelationsRegistry)
- registry.register(SubtaskRelation(self, task))
+ registry.register(relationship(self, concept))
# TODO (?): avoid duplicates
- def createSubtask(self, taskType=None, container=None, name=None):
- container = container or zapi.getParent(self)
- task = Task()
- name = name or task._createTaskName(container)
- container[name] = task
- self.assignSubtask(task)
- return task
+ def deassignConcept(self, concept, relationships=None):
+ pass # TODO
- def deassignSubtask(self, task):
- hits = [ r for r in self._subtasks if r._target == task ]
- if hits:
- self._subtasks.remove(hits[0])
- task._parentTasks.remove(hits[0])
- # resource allocations:
+# TODO: move this to the relation package
- def getAllocatedResources(self, allocTypes=None, resTypes=None):
- from sets import Set
- allocs = self._resourceAllocs
- res = Set()
- for at in allocTypes or allocs.keys():
- res.union_update(allocs[at])
- if resTypes:
- res = [ r for r in res if r in resTypes ]
- return tuple(res)
+def getRelations(first=None, second=None, third=None, relationships=None):
+ registry = zapi.getUtility(IRelationsRegistry)
+ query = {}
+ if first: query['first'] = first
+ if second: query['second'] = second
+ if third: query['third'] = third
+ if not relationships:
+ return registry.query(**query)
+ else:
+ result = []
+ for r in relationships:
+ query['relationship'] = r
+ result.extend(registry.query(**query))
+ return result
- def allocateResource(self, resource, allocType='standard'):
- allocs = self._resourceAllocs
- rList = allocs.get(allocType, [])
- if resource not in rList:
- rList.append(resource)
- allocs[allocType] = rList
- resource._addAllocation(self, allocType)
-
- def createAndAllocateResource(self, resourceType=None, allocType='standard',
- container=None, name=None):
- container = container or zapi.getParent(self)
- rClass = resourceType or Resource
- resource = rClass()
- name = name or resource._createResourceName(container)
- container[name] = resource
- self.allocateResource(resource, allocType)
- return resource
-
- def deallocateResource(self, resource, allocTypes=None):
- allocs = self._resourceAllocs
- for at in allocTypes or allocs.keys():
- if resource in allocs[at]:
- allocs[at].remove(resource)
- resource._removeAllocations(self, allocTypes)
-
- def allocatedUserIds(self):
- return ()
-
- def getAllocTypes(self, resource):
- return ('standard',)
-
- def getAllAllocTypes(self):
- return ('standard',)
-
- # resource constraint stuff:
-
- def isResourceAllowed(self, resource, rcDontCheck=None):
- rc = self.resourceConstraints
- if not rc:
- return True
- for c in rc:
- if rcDontCheck and c == rcDontCheck: # don't check constraint already checked
- continue
- # that's too simple, we must check all constraints for constraintType:
- if not c.isResourceAllowed(resource):
- return False
- return True
-
- def getCandidateResources(self):
- rc = self.resourceConstraints
- if not rc:
- return ()
- for c in rc:
- candidates = c.getAllowedResources()
- if candidates is not None:
- return tuple([ r for r in candidates if self.isResourceAllowed(r, c) ])
- return ()
-
- def getAllowedResources(self, candidates=None):
- rc = self.resourceConstraints
- if not rc:
- return None
- if candidates is None:
- result = self.getCandidateResources()
- # Empty result means: can't tell
- return result and result or None
- return tuple([ r for r in candidates if self.isResourceAllowed(r) ])
-
- def isValid(self, checkSubtasks=True):
- if self.resourceConstraints is not None:
- for r in self.getAllocatedResources():
- if not self.isResourceAllowed(r):
- return False
- if checkSubtasks:
- for t in self.getSubtasks():
- if not t.isValid():
- return False
- return True
-
- # Task object as prototype:
-
- def copyTask(self, targetContainer=None):
- targetContainer = targetContainer or zapi.getParent(self)
- newName = self._createTaskName(targetContainer)
- newTask = copy(self)
- targetContainer[newName] = newTask
- subtasks = self.getSubtasks()
- newTask._subtasks.clear()
- for st in subtasks:
- newSt = st.copyTask(targetContainer)
- newSt._parentTasks.clear()
- newTask.assignSubtask(newSt)
- return newTask
-
- # Helper methods:
-
- def _createTaskName(self, container=None):
- prefix = 'tsk'
- container = container or zapi.getParent(self)
- last = max([ int(n[len(prefix):]) for n in container.keys() ] or [0])
- return prefix + str(last+1)
diff --git a/configure.zcml b/configure.zcml
index 5eb5965..fb3fb48 100644
--- a/configure.zcml
+++ b/configure.zcml
@@ -10,22 +10,19 @@
-
+
-
-
+ id="loops.Concept"
+ description="Concept object" />