From 78310d3eee9ab7fe95110349fff4b959ea7e1132 Mon Sep 17 00:00:00 2001 From: helmutm Date: Sun, 11 Jun 2006 14:37:18 +0000 Subject: [PATCH] include setup upon loops site creation in the organize and knowledge packages git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1247 fd906abe-77d9-0310-91a1-e0d9ade77398 --- helpers.txt | 10 +++---- knowledge/README.txt | 65 ++++++++++++++-------------------------- knowledge/configure.zcml | 4 +++ knowledge/setup.py | 61 +++++++++++++++++++++++++++++++++++++ organize/README.txt | 50 ++++++++++++++----------------- organize/__init__.py | 1 - organize/configure.zcml | 5 ++++ organize/setup.py | 44 +++++++++++++++++++++++++++ setup.py | 25 +++++++++------- 9 files changed, 176 insertions(+), 89 deletions(-) create mode 100644 knowledge/setup.py create mode 100644 organize/setup.py diff --git a/helpers.txt b/helpers.txt index b75a1c1..0990848 100755 --- a/helpers.txt +++ b/helpers.txt @@ -30,15 +30,13 @@ Now we can setup a simple loops site with its manager objects, using a loops setup manager: >>> from loops import Loops - >>> site['loops'] = Loops() - >>> loopsRoot = site['loops'] + >>> loopsRoot = site['loops'] = Loops() >>> from loops.setup import SetupManager >>> setup = SetupManager(loopsRoot) - >>> setup.setup() - >>> concepts = loopsRoot['concepts'] - >>> resources = loopsRoot['resources'] - >>> views = loopsRoot['views'] + >>> concepts, resources, views = setup.setup() + >>> concepts['hasType'].title + u'has Type' We also add some example concepts, diff --git a/knowledge/README.txt b/knowledge/README.txt index bf2a566..ee773ca 100644 --- a/knowledge/README.txt +++ b/knowledge/README.txt @@ -18,62 +18,36 @@ and setup a simple loops site with a concept manager and some concepts (with all the type machinery, what in real life is done via standard ZCML setup): - >>> from loops import Loops - >>> from loops.concept import ConceptManager, Concept - >>> from loops.resource import ResourceManager - >>> from loops.interfaces import IResource, IConcept, ITypeConcept - - >>> loopsRoot = site['loops'] = Loops() - >>> from cybertools.relation.interfaces import IRelationRegistry >>> from cybertools.relation.registry import DummyRelationRegistry >>> relations = DummyRelationRegistry() >>> component.provideUtility(relations, IRelationRegistry) >>> from cybertools.typology.interfaces import IType + >>> from loops.interfaces import IConcept, ITypeConcept >>> from loops.type import ConceptType, TypeConcept >>> component.provideAdapter(ConceptType, (IConcept,), IType) >>> component.provideAdapter(TypeConcept, (IConcept,), ITypeConcept) - >>> concepts = loopsRoot['concepts'] = ConceptManager() - >>> resources = loopsRoot['resources'] = ResourceManager() - - >>> hasType = concepts['hasType'] = Concept(u'has type') - >>> type = concepts['type'] = Concept(u'Type') - >>> type.conceptType = type - - >>> predicate = concepts['predicate'] = Concept(u'Predicate') - >>> predicate.conceptType = type - >>> hasType.conceptType = predicate - -We need some predicates to set up the relationships between our concepts: - - >>> standard = concepts['standard'] = Concept(u'subobject') - >>> depends = concepts['depends'] = Concept(u'depends') - >>> knows = concepts['knows'] = Concept(u'knows') - >>> requires = concepts['requires'] = Concept(u'requires') - >>> provides = concepts['provides'] = Concept(u'provides') + >>> from loops.interfaces import ILoops + >>> from loops.setup import ISetupManager + >>> from loops.knowledge.setup import SetupManager + >>> component.provideAdapter(SetupManager, (ILoops,), ISetupManager, + ... name='knowledge') - >>> for p in (standard, depends, knows, requires, provides): - ... p.conceptType = predicate + >>> from loops import Loops + >>> loopsRoot = site['loops'] = Loops() -And last not least we need some type concepts for controlling the -meaning of the concepts objects: - - >>> from cybertools.knowledge.interfaces import IKnowledgeElement - >>> topic = concepts['topic'] = Concept(u'Topic') - >>> topic.conceptType = type - >>> ITypeConcept(topic).typeInterface = IKnowledgeElement - - >>> from loops.knowledge.interfaces import IPerson - >>> person = concepts['person'] = Concept(u'Person') - >>> person.conceptType = type - >>> ITypeConcept(person).typeInterface = IPerson + >>> from loops.setup import SetupManager + >>> setup = SetupManager(loopsRoot) + >>> concepts, resources, views = setup.setup() - >>> from loops.knowledge.interfaces import ITask - >>> task = concepts['task'] = Concept(u'Task') - >>> task.conceptType = type - >>> ITypeConcept(task).typeInterface = ITask +We need some type concepts for controlling the meaning of the concepts objects, +these have already been created during setup: + + >>> topic = concepts['topic'] + >>> person = concepts['person'] + >>> task = concepts['task'] Manage knowledge and knowledge requirements @@ -82,6 +56,9 @@ Manage knowledge and knowledge requirements The classes used in this package are just adapters to IConcept. >>> from loops.knowledge.knowledge import Person, Topic, Task + >>> from loops.knowledge.interfaces import IPerson + >>> from cybertools.knowledge.interfaces import IKnowledgeElement + >>> from loops.knowledge.interfaces import ITask >>> component.provideAdapter(Person, (IConcept,), IPerson) >>> component.provideAdapter(Topic, (IConcept,), IKnowledgeElement) >>> component.provideAdapter(Task, (IConcept,), ITask) @@ -91,6 +68,7 @@ interdependencies. Note that in order to discern the concepts created from their typeInterface adapters we here append a 'C' to the name of the variables: + >>> from loops.concept import Concept >>> progLangC = concepts['progLang'] = Concept(u'Programming Language') >>> ooProgC = concepts['ooProg'] = Concept(u'Object-oriented Programming') >>> pythonC = concepts['python'] = Concept(u'Python') @@ -142,6 +120,7 @@ a position with the requirement profile: Luckily there are a few elearning content objects out there that provide some of the knowledge needed: + >>> from loops.interfaces import IResource >>> from cybertools.knowledge.interfaces import IKnowledgeProvider >>> from loops.knowledge.knowledge import ConceptKnowledgeProvider >>> component.provideAdapter(ConceptKnowledgeProvider, (IConcept,)) diff --git a/knowledge/configure.zcml b/knowledge/configure.zcml index 96cf2c0..28f93b9 100644 --- a/knowledge/configure.zcml +++ b/knowledge/configure.zcml @@ -75,5 +75,9 @@ permission="zope.View" /> + + + diff --git a/knowledge/setup.py b/knowledge/setup.py new file mode 100644 index 0000000..33df5bc --- /dev/null +++ b/knowledge/setup.py @@ -0,0 +1,61 @@ +# +# Copyright (c) 2006 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Automatic setup of a loops site for the organize package. + +$Id$ +""" + +from zope.component import adapts +from zope.interface import implements, Interface + +from cybertools.knowledge.interfaces import IKnowledgeElement +from loops.concept import Concept +from loops.interfaces import ITypeConcept +from loops.knowledge.interfaces import IPerson, ITask +from loops.setup import SetupManager as BaseSetupManager + + +class SetupManager(BaseSetupManager): + + def setup(self): + concepts = self.context.getConceptManager() + type = concepts.getTypeConcept() + predicate = concepts['predicate'] + # type concepts: + person = self.addObject(concepts, Concept, 'person', title=u'Person', + conceptType=type) + ITypeConcept(person).typeInterface = IPerson # this may override other packages! + topic = self.addObject(concepts, Concept, 'topic', title=u'Topic', + conceptType=type) + ITypeConcept(topic).typeInterface = IKnowledgeElement + task = self.addObject(concepts, Concept, 'task', title=u'Task', + conceptType=type) + ITypeConcept(task).typeInterface = ITask + # predicates: + depends = self.addObject(concepts, Concept, 'depends', title=u'depends', + conceptType=predicate) + knows = self.addObject(concepts, Concept, 'knows', title=u'knows', + conceptType=predicate) + requires = self.addObject(concepts, Concept, 'requires', title=u'requires', + conceptType=predicate) + provides = self.addObject(concepts, Concept, 'provides', title=u'provides', + conceptType=predicate) + + diff --git a/organize/README.txt b/organize/README.txt index a7baa07..a12565f 100644 --- a/organize/README.txt +++ b/organize/README.txt @@ -18,38 +18,35 @@ and setup a simple loops site with a concept manager and some concepts (with all the type machinery, what in real life is done via standard ZCML setup): - >>> from loops import Loops - >>> from loops.concept import ConceptManager, Concept - >>> from loops.interfaces import IConcept, ITypeConcept - - >>> loopsRoot = site['loops'] = Loops() - >>> from cybertools.relation.interfaces import IRelationRegistry >>> from cybertools.relation.registry import DummyRelationRegistry >>> relations = DummyRelationRegistry() >>> component.provideUtility(relations, IRelationRegistry) >>> from cybertools.typology.interfaces import IType + >>> from loops.interfaces import IConcept, ITypeConcept >>> from loops.type import ConceptType, TypeConcept >>> component.provideAdapter(ConceptType, (IConcept,), IType) >>> component.provideAdapter(TypeConcept, (IConcept,), ITypeConcept) - >>> loopsRoot['concepts'] = ConceptManager() - >>> concepts = loopsRoot['concepts'] - - >>> concepts['hasType'] = Concept(u'has type') - >>> concepts['type'] = Concept(u'Type') - >>> type = concepts['type'] - >>> type.conceptType = type - - >>> from loops.organize.interfaces import IPerson - >>> concepts['person'] = Concept(u'Person') - >>> person = concepts['person'] - >>> person.conceptType = type - >>> ITypeConcept(person).typeInterface = IPerson + >>> from loops.interfaces import ILoops + >>> from loops.setup import ISetupManager + >>> from loops.organize.setup import SetupManager + >>> component.provideAdapter(SetupManager, (ILoops,), ISetupManager, + ... name='organize') - >>> johnC = Concept(u'John') - >>> concepts['john'] = johnC + >>> from loops import Loops + >>> loopsRoot = site['loops'] = Loops() + + >>> from loops.setup import SetupManager + >>> setup = SetupManager(loopsRoot) + >>> concepts, resources, views = setup.setup() + + >>> type = concepts['type'] + >>> person = concepts['person'] + + >>> from loops.concept import Concept + >>> johnC = concepts['john'] = Concept(u'John') >>> johnC.conceptType = person @@ -58,6 +55,7 @@ Organizations: Persons (and Users), Institutions, Addresses... The classes used in this package are just adapters to IConcept. + >>> from loops.organize.interfaces import IPerson >>> from loops.organize.party import Person >>> component.provideAdapter(Person, (IConcept,), IPerson) @@ -71,7 +69,7 @@ The classes used in this package are just adapters to IConcept. True >>> john.someOtherAttribute Traceback (most recent call last): - ... + ... AttributeError: someOtherAttribute We can use the age calculations from the base Person class: @@ -102,7 +100,6 @@ For testing, we first have to provide the needed utilities and settings >>> component.provideUtility(principalAnnotations, IPrincipalAnnotationUtility) >>> principal = auth.definePrincipal('users.john', u'John', login='john') - >>> john.userId = 'users.john' >>> annotations = principalAnnotations.getAnnotationsById('users.john') @@ -154,8 +151,7 @@ concept assigned we should get an error: >>> john.userId = 'users.john' - >>> marthaC = Concept(u'Martha') - >>> concepts['martha'] = marthaC + >>> marthaC = concepts['martha'] = Concept(u'Martha') >>> marthaC.conceptType = person >>> martha = IPerson(marthaC) @@ -192,14 +188,12 @@ with a principal folder: In addition, we have to create at least one node in the view space and register an IMemberRegistrationManager adapter for the loops root object: - >>> from loops.view import ViewManager, Node - >>> views = loopsRoot['views'] = ViewManager() + >>> from loops.view import Node >>> menu = views['menu'] = Node('Home') >>> menu.nodeType = 'menu' >>> from loops.organize.member import MemberRegistrationManager >>> from loops.organize.interfaces import IMemberRegistrationManager - >>> from loops.interfaces import ILoops >>> component.provideAdapter(MemberRegistrationManager) Now we can enter the registration info for a new member (after having made diff --git a/organize/__init__.py b/organize/__init__.py index 4bc90fb..38314f3 100644 --- a/organize/__init__.py +++ b/organize/__init__.py @@ -1,4 +1,3 @@ """ $Id$ """ - diff --git a/organize/configure.zcml b/organize/configure.zcml index bcfbbad..b11eb2c 100644 --- a/organize/configure.zcml +++ b/organize/configure.zcml @@ -90,4 +90,9 @@ permission="zope.Public" /> + + + + diff --git a/organize/setup.py b/organize/setup.py new file mode 100644 index 0000000..c9ba971 --- /dev/null +++ b/organize/setup.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2006 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Automatic setup of a loops site for the organize package. + +$Id$ +""" + +from zope.component import adapts +from zope.interface import implements, Interface + +from loops.concept import Concept +from loops.interfaces import ITypeConcept +from loops.organize.interfaces import IPerson +from loops.setup import SetupManager as BaseSetupManager + + +class SetupManager(BaseSetupManager): + + def setup(self): + concepts = self.context.getConceptManager() + type = concepts.getTypeConcept() + person = self.addObject(concepts, Concept, 'person', title=u'Person', + conceptType=type) + personTypeAdapter = ITypeConcept(person) + if not personTypeAdapter.typeInterface: # only set if not set yet + personTypeAdapter.typeInterface = IPerson + diff --git a/setup.py b/setup.py index 25370a8..6d5af56 100644 --- a/setup.py +++ b/setup.py @@ -22,12 +22,11 @@ Automatic setup of a loops site. $Id$ """ -import transaction from zope.app.event.objectevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.event import notify +from zope import component from zope.component import adapts from zope.interface import implements, Interface -from zope.cachedescriptors.property import Lazy from loops.interfaces import ILoops from loops.concept import ConceptManager, Concept @@ -56,6 +55,11 @@ class SetupManager(object): def setup(self): concepts, resources, views = self.setupManagers() self.setupCoreConcepts(concepts) + appSetups = dict(component.getAdapters((self.context,), ISetupManager)) + for smName in appSetups: + if smName: # skip core (unnamed), i.e. this, adapter + appSetups[smName].setup() + return concepts, resources, views # just for convenience when testing def setupManagers(self): loopsRoot = self.context @@ -65,22 +69,21 @@ class SetupManager(object): return concepts, resources, views def setupCoreConcepts(self, conceptManager): - typeConcept = self.addObject(conceptManager, Concept, 'type', u'Type') - hasType = self.addObject(conceptManager, Concept, 'hasType', u'has type') - predicate = self.addObject(conceptManager, Concept, 'predicate', u'Predicate') - standard = self.addObject(conceptManager, Concept, 'standard', u'subobject') + typeConcept = self.addObject(conceptManager, Concept, 'type', title=u'Type') + hasType = self.addObject(conceptManager, Concept, 'hasType', title=u'has Type') + predicate = self.addObject(conceptManager, Concept, 'predicate', title=u'Predicate') + standard = self.addObject(conceptManager, Concept, 'standard', title=u'subobject') typeConcept.conceptType = typeConcept predicate.conceptType = typeConcept hasType.conceptType = predicate standard.conceptType = predicate - def addObject(self, container, class_, name, title=None): + def addObject(self, container, class_, name, **kw): if name in container: return container[name] - if title: - obj = container[name] = class_(title) - else: - obj = container[name] = class_() + obj = container[name] = class_() + for attr in kw: + setattr(obj, attr, kw[attr]) notify(ObjectCreatedEvent(obj)) notify(ObjectModifiedEvent(obj)) return obj