merge branch master
This commit is contained in:
commit
7813f8d806
25 changed files with 357 additions and 140 deletions
|
@ -27,7 +27,7 @@ configuration):
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
|
|
||||||
>>> len(concepts), len(resources)
|
>>> len(concepts), len(resources)
|
||||||
(20, 0)
|
(15, 0)
|
||||||
|
|
||||||
Let's now add an external collection that reads in a set of resources
|
Let's now add an external collection that reads in a set of resources
|
||||||
from external files so we have something to work with.
|
from external files so we have something to work with.
|
||||||
|
|
|
@ -24,7 +24,7 @@ from loops.integrator.collection import DirectoryCollectionProvider
|
||||||
from loops.integrator.collection import ExternalCollectionAdapter
|
from loops.integrator.collection import ExternalCollectionAdapter
|
||||||
from loops.integrator.interfaces import IExternalCollection, IExternalCollectionProvider
|
from loops.integrator.interfaces import IExternalCollection, IExternalCollectionProvider
|
||||||
from loops.organize.setup import SetupManager as OrganizeSetupManager
|
from loops.organize.setup import SetupManager as OrganizeSetupManager
|
||||||
from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
#from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
||||||
from loops.knowledge.knowledge import Person
|
from loops.knowledge.knowledge import Person
|
||||||
from loops.knowledge.interfaces import IPerson
|
from loops.knowledge.interfaces import IPerson
|
||||||
from loops.setup import SetupManager, addAndConfigureObject
|
from loops.setup import SetupManager, addAndConfigureObject
|
||||||
|
@ -39,7 +39,7 @@ class TestSite(BaseTestSite):
|
||||||
self.site = site
|
self.site = site
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
#component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
||||||
component.provideAdapter(OrganizeSetupManager, name='organize')
|
component.provideAdapter(OrganizeSetupManager, name='organize')
|
||||||
concepts, resources, views = self.baseSetup()
|
concepts, resources, views = self.baseSetup()
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ configuration):
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
|
|
||||||
>>> len(concepts) + len(resources)
|
>>> len(concepts) + len(resources)
|
||||||
33
|
37
|
||||||
|
|
||||||
>>> loopsRoot = site['loops']
|
>>> loopsRoot = site['loops']
|
||||||
|
|
||||||
|
@ -47,19 +47,19 @@ Type- and text-based queries
|
||||||
>>> from loops.expert import query
|
>>> from loops.expert import query
|
||||||
>>> qu = query.Title('ty*')
|
>>> qu = query.Title('ty*')
|
||||||
>>> list(qu.apply())
|
>>> list(qu.apply())
|
||||||
[0, 1, 47]
|
[0, 1, 68]
|
||||||
|
|
||||||
>>> qu = query.Type('loops:*')
|
>>> qu = query.Type('loops:*')
|
||||||
>>> len(list(qu.apply()))
|
>>> len(list(qu.apply()))
|
||||||
33
|
37
|
||||||
|
|
||||||
>>> qu = query.Type('loops:concept:predicate')
|
>>> qu = query.Type('loops:concept:predicate')
|
||||||
>>> len(list(qu.apply()))
|
>>> len(list(qu.apply()))
|
||||||
7
|
8
|
||||||
|
|
||||||
>>> qu = query.Type('loops:concept:predicate') & query.Title('t*')
|
>>> qu = query.Type('loops:concept:predicate') & query.Title('t*')
|
||||||
>>> list(qu.apply())
|
>>> list(qu.apply())
|
||||||
[1, 43]
|
[1, 29]
|
||||||
|
|
||||||
State-based queries
|
State-based queries
|
||||||
-------------------
|
-------------------
|
||||||
|
|
|
@ -66,13 +66,13 @@ zcml in real life:
|
||||||
|
|
||||||
>>> t = searchView.typesForSearch()
|
>>> t = searchView.typesForSearch()
|
||||||
>>> len(t)
|
>>> len(t)
|
||||||
14
|
16
|
||||||
>>> t.getTermByToken('loops:resource:*').title
|
>>> t.getTermByToken('loops:resource:*').title
|
||||||
'Any Resource'
|
'Any Resource'
|
||||||
|
|
||||||
>>> t = searchView.conceptTypesForSearch()
|
>>> t = searchView.conceptTypesForSearch()
|
||||||
>>> len(t)
|
>>> len(t)
|
||||||
11
|
13
|
||||||
>>> t.getTermByToken('loops:concept:*').title
|
>>> t.getTermByToken('loops:concept:*').title
|
||||||
'Any Concept'
|
'Any Concept'
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ a controller attribute for the search view.
|
||||||
|
|
||||||
>>> searchView.submitReplacing('1.results', '1.search.form', pageView)
|
>>> searchView.submitReplacing('1.results', '1.search.form', pageView)
|
||||||
'submitReplacing("1.results", "1.search.form",
|
'submitReplacing("1.results", "1.search.form",
|
||||||
"http://127.0.0.1/loops/views/page/.target80/@@searchresults.html");...'
|
"http://127.0.0.1/loops/views/page/.target99/@@searchresults.html");...'
|
||||||
|
|
||||||
Basic (text/title) search
|
Basic (text/title) search
|
||||||
-------------------------
|
-------------------------
|
||||||
|
@ -177,7 +177,7 @@ of the concepts' titles:
|
||||||
>>> request = TestRequest(form=form)
|
>>> request = TestRequest(form=form)
|
||||||
>>> view = Search(page, request)
|
>>> view = Search(page, request)
|
||||||
>>> view.listConcepts()
|
>>> view.listConcepts()
|
||||||
u"{identifier: 'id', items: [{label: 'Zope (Topic)', name: 'Zope', id: '85'}, {label: 'Zope 2 (Topic)', name: 'Zope 2', id: '87'}, {label: 'Zope 3 (Topic)', name: 'Zope 3', id: '89'}]}"
|
u"{identifier: 'id', items: [{label: 'Zope (Thema)', name: 'Zope', id: '104'}, {label: 'Zope 2 (Thema)', name: 'Zope 2', id: '106'}, {label: 'Zope 3 (Thema)', name: 'Zope 3', id: '108'}]}"
|
||||||
|
|
||||||
Preset Concept Types on Search Forms
|
Preset Concept Types on Search Forms
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
@ -219,13 +219,13 @@ and thus include the customer type in the preset search types.
|
||||||
|
|
||||||
>>> searchView.conceptsForType('loops:concept:customer')
|
>>> searchView.conceptsForType('loops:concept:customer')
|
||||||
[{'token': 'none', 'title': u'not selected'},
|
[{'token': 'none', 'title': u'not selected'},
|
||||||
{'token': '58', 'title': u'Customer 1'},
|
{'token': '77', 'title': u'Customer 1'},
|
||||||
{'token': '60', 'title': u'Customer 2'},
|
{'token': '79', 'title': u'Customer 2'},
|
||||||
{'token': '62', 'title': u'Customer 3'}]
|
{'token': '81', 'title': u'Customer 3'}]
|
||||||
|
|
||||||
Let's use this new search option for querying:
|
Let's use this new search option for querying:
|
||||||
|
|
||||||
>>> form = {'search.4.text_selected': u'58'}
|
>>> form = {'search.4.text_selected': u'77'}
|
||||||
>>> resultsView = SearchResults(page, TestRequest(form=form))
|
>>> resultsView = SearchResults(page, TestRequest(form=form))
|
||||||
>>> results = list(resultsView.results)
|
>>> results = list(resultsView.results)
|
||||||
>>> results[0].title
|
>>> results[0].title
|
||||||
|
|
|
@ -14,7 +14,8 @@ from loops.expert.setup import SetupManager as ExpertSetupManager
|
||||||
from loops.resource import Resource
|
from loops.resource import Resource
|
||||||
from loops.knowledge.interfaces import IPerson
|
from loops.knowledge.interfaces import IPerson
|
||||||
from loops.knowledge.knowledge import Person
|
from loops.knowledge.knowledge import Person
|
||||||
from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
#from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
||||||
|
from loops.knowledge.tests import importData
|
||||||
from loops.setup import SetupManager, addObject
|
from loops.setup import SetupManager, addObject
|
||||||
from loops.tests.setup import TestSite as BaseTestSite
|
from loops.tests.setup import TestSite as BaseTestSite
|
||||||
from loops.type import ConceptType, ResourceType, TypeConcept
|
from loops.type import ConceptType, ResourceType, TypeConcept
|
||||||
|
@ -32,10 +33,11 @@ class TestSite(BaseTestSite):
|
||||||
|
|
||||||
component.provideAdapter(Person, provides=IPerson)
|
component.provideAdapter(Person, provides=IPerson)
|
||||||
|
|
||||||
component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
#component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
||||||
component.provideAdapter(ExpertSetupManager, name='expert')
|
component.provideAdapter(ExpertSetupManager, name='expert')
|
||||||
setup = SetupManager(loopsRoot)
|
setup = SetupManager(loopsRoot)
|
||||||
concepts, resources, views = setup.setup()
|
concepts, resources, views = setup.setup()
|
||||||
|
importData(loopsRoot)
|
||||||
|
|
||||||
tType = concepts.getTypeConcept()
|
tType = concepts.getTypeConcept()
|
||||||
tDomain = concepts['domain']
|
tDomain = concepts['domain']
|
||||||
|
|
8
external/README.txt
vendored
8
external/README.txt
vendored
|
@ -17,7 +17,7 @@ Let's set up a loops site with basic and example concepts and resources.
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
>>> loopsRoot = site['loops']
|
>>> loopsRoot = site['loops']
|
||||||
>>> len(concepts), len(resources), len(views)
|
>>> len(concepts), len(resources), len(views)
|
||||||
(30, 3, 1)
|
(34, 3, 1)
|
||||||
|
|
||||||
|
|
||||||
Importing loops Objects
|
Importing loops Objects
|
||||||
|
@ -44,7 +44,7 @@ Creating the corresponding objects
|
||||||
>>> loader = Loader(loopsRoot)
|
>>> loader = Loader(loopsRoot)
|
||||||
>>> loader.load(elements)
|
>>> loader.load(elements)
|
||||||
>>> len(concepts), len(resources), len(views)
|
>>> len(concepts), len(resources), len(views)
|
||||||
(31, 3, 1)
|
(35, 3, 1)
|
||||||
|
|
||||||
>>> from loops.common import adapted
|
>>> from loops.common import adapted
|
||||||
>>> adMyquery = adapted(concepts['myquery'])
|
>>> adMyquery = adapted(concepts['myquery'])
|
||||||
|
@ -131,7 +131,7 @@ Extracting elements
|
||||||
>>> extractor = Extractor(loopsRoot, os.path.join(dataDirectory, 'export'))
|
>>> extractor = Extractor(loopsRoot, os.path.join(dataDirectory, 'export'))
|
||||||
>>> elements = list(extractor.extract())
|
>>> elements = list(extractor.extract())
|
||||||
>>> len(elements)
|
>>> len(elements)
|
||||||
53
|
68
|
||||||
|
|
||||||
Writing object information to the external storage
|
Writing object information to the external storage
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
@ -143,6 +143,7 @@ Writing object information to the external storage
|
||||||
>>> writer = PyWriter()
|
>>> writer = PyWriter()
|
||||||
>>> writer.write(elements, output)
|
>>> writer.write(elements, output)
|
||||||
>>> print output.getvalue()
|
>>> print output.getvalue()
|
||||||
|
type(u'task', ...)...
|
||||||
type(u'country', u'Country', viewName=u'', typeInterface=u''..., options=u''...)...
|
type(u'country', u'Country', viewName=u'', typeInterface=u''..., options=u''...)...
|
||||||
type(u'query', u'Query', viewName=u'', typeInterface='loops.expert.concept.IQueryConcept'..., options=u''...)...
|
type(u'query', u'Query', viewName=u'', typeInterface='loops.expert.concept.IQueryConcept'..., options=u''...)...
|
||||||
concept(u'myquery', u'My Query', u'query', options=u'option1\noption2',
|
concept(u'myquery', u'My Query', u'query', options=u'option1\noption2',
|
||||||
|
@ -184,6 +185,7 @@ corresponding extractor adapter.
|
||||||
>>> PyWriter().write(extractor.extract(), output)
|
>>> PyWriter().write(extractor.extract(), output)
|
||||||
|
|
||||||
>>> print output.getvalue()
|
>>> print output.getvalue()
|
||||||
|
type(u'task', ...)...
|
||||||
type(u'country', u'Country', viewName=u'', typeInterface=u''..., options=u''...)...
|
type(u'country', u'Country', viewName=u'', typeInterface=u''..., options=u''...)...
|
||||||
concept(u'myquery', u'My Query', u'query', options=u'option1\noption2',
|
concept(u'myquery', u'My Query', u'query', options=u'option1\noption2',
|
||||||
viewName=u'mystuff.html')[
|
viewName=u'mystuff.html')[
|
||||||
|
|
33
external/element.py
vendored
33
external/element.py
vendored
|
@ -30,10 +30,11 @@ from zope.traversing.api import getName, traverse
|
||||||
|
|
||||||
from cybertools.composer.interfaces import IInstance
|
from cybertools.composer.interfaces import IInstance
|
||||||
from cybertools.composer.schema.interfaces import ISchemaFactory
|
from cybertools.composer.schema.interfaces import ISchemaFactory
|
||||||
|
from cybertools.tracking.btree import TrackingStorage
|
||||||
from cybertools.typology.interfaces import IType
|
from cybertools.typology.interfaces import IType
|
||||||
from loops.common import adapted
|
from loops.common import adapted
|
||||||
from loops.interfaces import IConceptSchema
|
|
||||||
from loops.external.interfaces import IElement
|
from loops.external.interfaces import IElement
|
||||||
|
from loops.interfaces import IConceptSchema
|
||||||
from loops.i18n.common import I18NValue
|
from loops.i18n.common import I18NValue
|
||||||
from loops.layout.base import LayoutNode
|
from loops.layout.base import LayoutNode
|
||||||
from loops.predicate import adaptedRelation
|
from loops.predicate import adaptedRelation
|
||||||
|
@ -132,6 +133,33 @@ class TypeElement(ConceptElement):
|
||||||
adapted(self.object).typeInterface = kw['typeInterface']
|
adapted(self.object).typeInterface = kw['typeInterface']
|
||||||
|
|
||||||
|
|
||||||
|
class RecordManagerElement(Element):
|
||||||
|
|
||||||
|
elementType = 'records'
|
||||||
|
posArgs = ('name', 'trackFactory')
|
||||||
|
|
||||||
|
def __init__(self, name, trackFactory, **kw):
|
||||||
|
self['name'] = name
|
||||||
|
tf = self['trackFactory'] = trackFactory
|
||||||
|
if not isinstance(tf, basestring):
|
||||||
|
self['trackFactory'] = '.'.join((tf.__module__, tf.__name__))
|
||||||
|
for k, v in kw.items():
|
||||||
|
self[k] = v
|
||||||
|
|
||||||
|
def execute(self, loader):
|
||||||
|
name = self['name']
|
||||||
|
tf = resolve(self['trackFactory'])
|
||||||
|
records = loader.context.getRecordManager()
|
||||||
|
obj = records.get(name)
|
||||||
|
if obj is None:
|
||||||
|
obj = records[name] = TrackingStorage(trackFactory=tf)
|
||||||
|
else:
|
||||||
|
obj.trackFactory = tf
|
||||||
|
obj.indexAttributes = tf.index_attributes
|
||||||
|
obj.setupIndexes()
|
||||||
|
self.object = obj
|
||||||
|
|
||||||
|
|
||||||
class ChildElement(Element):
|
class ChildElement(Element):
|
||||||
|
|
||||||
elementType = 'child'
|
elementType = 'child'
|
||||||
|
@ -261,6 +289,7 @@ class LayoutNodeElement(NodeElement):
|
||||||
elementTypes = dict(
|
elementTypes = dict(
|
||||||
type=TypeElement,
|
type=TypeElement,
|
||||||
concept=ConceptElement,
|
concept=ConceptElement,
|
||||||
|
records=RecordManagerElement,
|
||||||
child=ChildElement,
|
child=ChildElement,
|
||||||
resource=ResourceElement,
|
resource=ResourceElement,
|
||||||
resourceRelation=ResourceRelationElement,
|
resourceRelation=ResourceRelationElement,
|
||||||
|
@ -270,5 +299,5 @@ elementTypes = dict(
|
||||||
I18NValue=I18NValue,
|
I18NValue=I18NValue,
|
||||||
)
|
)
|
||||||
|
|
||||||
toplevelElements = ('type', 'concept', 'resource',
|
toplevelElements = ('type', 'concept', 'resource', 'records',
|
||||||
'child', 'resourceRelation', 'node', 'deassign')
|
'child', 'resourceRelation', 'node', 'deassign')
|
||||||
|
|
|
@ -18,15 +18,15 @@ ZCML setup):
|
||||||
>>> from loops.interfaces import ILoops, IConcept
|
>>> from loops.interfaces import ILoops, IConcept
|
||||||
>>> from loops.concept import Concept
|
>>> from loops.concept import Concept
|
||||||
>>> from loops.setup import ISetupManager
|
>>> from loops.setup import ISetupManager
|
||||||
>>> from loops.knowledge.setup import SetupManager
|
|
||||||
>>> component.provideAdapter(SetupManager, (ILoops,), ISetupManager,
|
|
||||||
... name='knowledge')
|
|
||||||
|
|
||||||
>>> from loops.tests.setup import TestSite
|
>>> from loops.tests.setup import TestSite
|
||||||
>>> t = TestSite(site)
|
>>> t = TestSite(site)
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
>>> loopsRoot = site['loops']
|
>>> loopsRoot = site['loops']
|
||||||
|
|
||||||
|
>>> from loops.knowledge.tests import importData
|
||||||
|
>>> importData(loopsRoot)
|
||||||
|
|
||||||
>>> from loops.knowledge.knowledge import Topic
|
>>> from loops.knowledge.knowledge import Topic
|
||||||
>>> component.provideAdapter(Topic)
|
>>> component.provideAdapter(Topic)
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ configuration):
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
|
|
||||||
>>> len(concepts) + len(resources)
|
>>> len(concepts) + len(resources)
|
||||||
18
|
11
|
||||||
|
|
||||||
>>> loopsRoot = site['loops']
|
>>> loopsRoot = site['loops']
|
||||||
>>> #loopsRoot.options = ['useVersioning:rev']
|
>>> #loopsRoot.options = ['useVersioning:rev']
|
||||||
|
|
|
@ -18,7 +18,7 @@ from loops.resource import Resource, FileAdapter, ExternalFileAdapter
|
||||||
from loops.integrator.interfaces import IExternalSourceInfo, IExternalCollection
|
from loops.integrator.interfaces import IExternalSourceInfo, IExternalCollection
|
||||||
from loops.integrator.interfaces import IOfficeFile
|
from loops.integrator.interfaces import IOfficeFile
|
||||||
from loops.integrator.office.base import OfficeFile
|
from loops.integrator.office.base import OfficeFile
|
||||||
from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
#from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
||||||
from loops.setup import SetupManager, addAndConfigureObject
|
from loops.setup import SetupManager, addAndConfigureObject
|
||||||
from loops.tests.setup import TestSite as BaseTestSite
|
from loops.tests.setup import TestSite as BaseTestSite
|
||||||
from loops.versioning.versionable import VersionableResource
|
from loops.versioning.versionable import VersionableResource
|
||||||
|
@ -32,7 +32,7 @@ class TestSite(BaseTestSite):
|
||||||
self.site = site
|
self.site = site
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
#component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
||||||
concepts, resources, views = self.baseSetup()
|
concepts, resources, views = self.baseSetup()
|
||||||
|
|
||||||
component.provideAdapter(FileAdapter, provides=IFile)
|
component.provideAdapter(FileAdapter, provides=IFile)
|
||||||
|
|
|
@ -2,33 +2,32 @@
|
||||||
loops - Linked Objects for Organization and Processing Services
|
loops - Linked Objects for Organization and Processing Services
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
($Id$)
|
Note: This package depends on cybertools.knowledge and loops.organize.
|
||||||
|
|
||||||
Note: This package depends on cybertools.knowledge and cybertools.organize.
|
|
||||||
|
|
||||||
Let's do some basic set up
|
Let's do some basic set up
|
||||||
|
|
||||||
|
>>> from zope import component, interface
|
||||||
|
|
||||||
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
||||||
>>> site = placefulSetUp(True)
|
>>> site = placefulSetUp(True)
|
||||||
|
|
||||||
>>> from zope import component, interface
|
|
||||||
|
|
||||||
and setup a simple loops site with a concept manager and some concepts
|
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
|
(with all the type machinery, what in real life is done via standard
|
||||||
ZCML setup):
|
ZCML setup):
|
||||||
|
|
||||||
>>> from loops.interfaces import ILoops, IConcept
|
|
||||||
>>> from loops.setup import ISetupManager
|
|
||||||
>>> from loops.knowledge.setup import SetupManager
|
|
||||||
>>> component.provideAdapter(SetupManager, (ILoops,), ISetupManager,
|
|
||||||
... name='knowledge')
|
|
||||||
|
|
||||||
>>> from loops.tests.setup import TestSite
|
>>> from loops.tests.setup import TestSite
|
||||||
>>> t = TestSite(site)
|
>>> t = TestSite(site)
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
|
>>> loopsRoot = site['loops']
|
||||||
|
|
||||||
|
We then import a loops .dmp file containing all necessary types and
|
||||||
|
predicates.
|
||||||
|
|
||||||
|
>>> from loops.knowledge.tests import importData
|
||||||
|
>>> importData(loopsRoot)
|
||||||
|
|
||||||
We need some type concepts for controlling the meaning of the concepts objects,
|
We need some type concepts for controlling the meaning of the concepts objects,
|
||||||
these have already been created during setup:
|
these have already been created during setup and .dmp import:
|
||||||
|
|
||||||
>>> topic = concepts['topic']
|
>>> topic = concepts['topic']
|
||||||
>>> person = concepts['person']
|
>>> person = concepts['person']
|
||||||
|
@ -40,6 +39,7 @@ Manage knowledge and knowledge requirements
|
||||||
|
|
||||||
The classes used in this package are just adapters to IConcept.
|
The classes used in this package are just adapters to IConcept.
|
||||||
|
|
||||||
|
>>> from loops.interfaces import IConcept
|
||||||
>>> from loops.knowledge.knowledge import Person, Topic, Task
|
>>> from loops.knowledge.knowledge import Person, Topic, Task
|
||||||
>>> from loops.knowledge.interfaces import IPerson
|
>>> from loops.knowledge.interfaces import IPerson
|
||||||
>>> from cybertools.knowledge.interfaces import IKnowledgeElement
|
>>> from cybertools.knowledge.interfaces import IKnowledgeElement
|
||||||
|
@ -166,6 +166,34 @@ For testing, we first have to provide the needed utilities and settings
|
||||||
>>> view = MyKnowledge(task01C, request)
|
>>> view = MyKnowledge(task01C, request)
|
||||||
>>> prov = view.myKnowledgeProvidersForTask()
|
>>> prov = view.myKnowledgeProvidersForTask()
|
||||||
|
|
||||||
|
|
||||||
|
Competence and Certification Management
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
>>> from cybertools.stateful.interfaces import IStatesDefinition
|
||||||
|
>>> from loops.knowledge.qualification import qualificationStates
|
||||||
|
>>> from loops.knowledge.interfaces import IQualificationRecords
|
||||||
|
>>> from loops.knowledge.qualification import QualificationRecords
|
||||||
|
>>> component.provideUtility(qualificationStates,
|
||||||
|
... provides=IStatesDefinition,
|
||||||
|
... name='knowledge.qualification')
|
||||||
|
>>> component.provideAdapter(QualificationRecords,
|
||||||
|
... provides=IQualificationRecords)
|
||||||
|
|
||||||
|
>>> qurecs = loopsRoot.getRecordManager()['qualification']
|
||||||
|
|
||||||
|
We first create a training that provides knowledge in Python specials.
|
||||||
|
|
||||||
|
>>> trainingPySpecC = concepts['trpyspec'] = Concept(
|
||||||
|
... u'Python Specials Training')
|
||||||
|
>>> trainingPySpecC.assignParent(pySpecialsC)
|
||||||
|
|
||||||
|
Then we record the need for John to acquire this knowledge.
|
||||||
|
|
||||||
|
>>> from loops.knowledge.browser import CreateQualificationRecordForm
|
||||||
|
>>> from loops.knowledge.browser import CreateQualificationRecord
|
||||||
|
|
||||||
|
|
||||||
Glossaries
|
Glossaries
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,8 +19,6 @@
|
||||||
"""
|
"""
|
||||||
Definition of view classes and other browser related stuff for the
|
Definition of view classes and other browser related stuff for the
|
||||||
loops.knowledge package.
|
loops.knowledge package.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope import interface, component
|
from zope import interface, component
|
||||||
|
@ -32,11 +30,17 @@ from cybertools.typology.interfaces import IType
|
||||||
from loops.browser.action import DialogAction
|
from loops.browser.action import DialogAction
|
||||||
from loops.browser.common import BaseView
|
from loops.browser.common import BaseView
|
||||||
from loops.browser.concept import ConceptView
|
from loops.browser.concept import ConceptView
|
||||||
|
from loops.expert.browser.report import ResultsConceptView
|
||||||
from loops.knowledge.interfaces import IPerson, ITask
|
from loops.knowledge.interfaces import IPerson, ITask
|
||||||
|
from loops.organize.work.browser import CreateWorkItemForm, CreateWorkItem
|
||||||
from loops.organize.party import getPersonForUser
|
from loops.organize.party import getPersonForUser
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
|
||||||
|
|
||||||
|
template = ViewPageTemplateFile('knowledge_macros.pt')
|
||||||
|
knowledge_macros = template.macros
|
||||||
|
|
||||||
|
|
||||||
actions.register('createTopic', 'portlet', DialogAction,
|
actions.register('createTopic', 'portlet', DialogAction,
|
||||||
title=_(u'Create Topic...'),
|
title=_(u'Create Topic...'),
|
||||||
description=_(u'Create a new topic.'),
|
description=_(u'Create a new topic.'),
|
||||||
|
@ -54,10 +58,19 @@ actions.register('editTopic', 'portlet', DialogAction,
|
||||||
dialogName='editTopic',
|
dialogName='editTopic',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
actions.register('createQualification', 'portlet', DialogAction,
|
||||||
|
title=_(u'Create Qualification Record...'),
|
||||||
|
description=_(u'Create a work item for this person.'),
|
||||||
|
viewName='create_qualification.html',
|
||||||
|
dialogName='createQualification',
|
||||||
|
prerequisites=['registerDojoDateWidget', 'registerDojoNumberWidget',
|
||||||
|
'registerDojoTextarea'],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MyKnowledge(ConceptView):
|
class MyKnowledge(ConceptView):
|
||||||
|
|
||||||
template = ViewPageTemplateFile('knowledge_macros.pt')
|
template = template
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
|
@ -90,9 +103,30 @@ class MyKnowledge(ConceptView):
|
||||||
|
|
||||||
class Candidates(ConceptView):
|
class Candidates(ConceptView):
|
||||||
|
|
||||||
template = ViewPageTemplateFile('knowledge_macros.pt')
|
template = template
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
return self.template.macros['requirement_candidates']
|
return self.template.macros['requirement_candidates']
|
||||||
|
|
||||||
|
|
||||||
|
# qualification stuff
|
||||||
|
|
||||||
|
class PersonQualificationView(ResultsConceptView):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CreateQualificationRecordForm(CreateWorkItemForm):
|
||||||
|
|
||||||
|
macros = knowledge_macros
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def macro(self):
|
||||||
|
return self.macros['create_qualification']
|
||||||
|
|
||||||
|
|
||||||
|
class CreateQualificationRecord(CreateWorkItem):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,22 @@
|
||||||
interface="cybertools.knowledge.interfaces.IKnowledgeProvider" />
|
interface="cybertools.knowledge.interfaces.IKnowledgeProvider" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
||||||
|
<!-- records -->
|
||||||
|
|
||||||
|
<zope:class class="loops.knowledge.qualification.QualificationRecord">
|
||||||
|
<require permission="zope.View"
|
||||||
|
interface="loops.knowledge.interfaces.IQualificationRecord" />
|
||||||
|
<require permission="zope.ManageContent"
|
||||||
|
set_schema="loops.knowledge.interfaces.IQualificationRecord" />
|
||||||
|
</zope:class>
|
||||||
|
|
||||||
|
<zope:adapter factory="loops.knowledge.qualification.QualificationRecords"
|
||||||
|
provides="loops.knowledge.interfaces.IQualificationRecords" />
|
||||||
|
|
||||||
|
<zope:utility factory="loops.knowledge.qualification.qualificationStates"
|
||||||
|
provides="cybertools.stateful.interfaces.IStatesDefinition"
|
||||||
|
name="knowledge.qualification" />
|
||||||
|
|
||||||
<!-- views -->
|
<!-- views -->
|
||||||
|
|
||||||
<zope:adapter
|
<zope:adapter
|
||||||
|
@ -88,9 +104,6 @@
|
||||||
|
|
||||||
<zope:adapter factory="loops.knowledge.schema.PersonSchemaFactory" />
|
<zope:adapter factory="loops.knowledge.schema.PersonSchemaFactory" />
|
||||||
|
|
||||||
<zope:adapter factory="loops.knowledge.setup.SetupManager"
|
|
||||||
name="knowledge" />
|
|
||||||
|
|
||||||
<!-- sub-packages -->
|
<!-- sub-packages -->
|
||||||
|
|
||||||
<include package=".glossary" />
|
<include package=".glossary" />
|
||||||
|
|
44
knowledge/data/loops_knowledge_de.dmp
Normal file
44
knowledge/data/loops_knowledge_de.dmp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
type(u'competence', u'Competence', viewName=u'',
|
||||||
|
typeInterface=u'', options=u'action.portlet:edit_concept')
|
||||||
|
type(u'person', u'Person', viewName=u'',
|
||||||
|
typeInterface=u'loops.knowledge.interfaces.IPerson',
|
||||||
|
options=u'action.portlet:editPerson')
|
||||||
|
type(u'task', u'Aufgabe', viewName=u'',
|
||||||
|
typeInterface=u'loops.knowledge.interfaces.ITask',
|
||||||
|
options=u'action.portlet:createTopic,editTopic')
|
||||||
|
type(u'topic', u'Thema', viewName=u'',
|
||||||
|
typeInterface=u'loops.knowledge.interfaces.ITopic',
|
||||||
|
options=u'action.portlet:createTopic,editTopic')
|
||||||
|
type(u'training', u'Schulung', viewName=u'',
|
||||||
|
typeInterface=u'loops.organize.interfaces.ITask',
|
||||||
|
options=u'action.portlet:create_subtype,edit_concept')
|
||||||
|
|
||||||
|
concept(u'general', u'Allgemein', u'domain')
|
||||||
|
concept(u'system', u'System', u'domain')
|
||||||
|
|
||||||
|
# predicates
|
||||||
|
concept(u'depends', u'depends', u'predicate')
|
||||||
|
concept(u'knows', u'knows', u'predicate')
|
||||||
|
concept(u'provides', u'provides', u'predicate')
|
||||||
|
concept(u'requires', u'requires', u'predicate')
|
||||||
|
|
||||||
|
concept(u'issubtype', u'is Subtype', u'predicate', options=u'hide_children',
|
||||||
|
predicateInterface='loops.interfaces.IIsSubtype')
|
||||||
|
|
||||||
|
# structure
|
||||||
|
child(u'competence', u'general', u'standard')
|
||||||
|
child(u'depends', u'general', u'standard')
|
||||||
|
child(u'knows', u'general', u'standard')
|
||||||
|
child(u'person', u'general', u'standard')
|
||||||
|
child(u'provides', u'general', u'standard')
|
||||||
|
child(u'requires', u'general', u'standard')
|
||||||
|
child(u'task', u'general', u'standard')
|
||||||
|
child(u'topic', u'general', u'standard')
|
||||||
|
child(u'training', u'general', u'standard')
|
||||||
|
|
||||||
|
child(u'issubtype', u'system', u'standard')
|
||||||
|
|
||||||
|
child(u'training', u'competence', u'issubtype', usePredicate=u'provides')
|
||||||
|
|
||||||
|
# records
|
||||||
|
records(u'qualification', u'loops.knowledge.qualification.QualificationRecord')
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Interfaces for knowledge management and elearning with loops.
|
Interfaces for knowledge management and elearning with loops.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.interface import Interface, Attribute
|
from zope.interface import Interface, Attribute
|
||||||
|
@ -29,6 +27,7 @@ from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
from cybertools.knowledge.interfaces import IKnowing, IRequirementProfile
|
from cybertools.knowledge.interfaces import IKnowing, IRequirementProfile
|
||||||
from cybertools.knowledge.interfaces import IKnowledgeElement
|
from cybertools.knowledge.interfaces import IKnowledgeElement
|
||||||
|
from cybertools.organize.interfaces import IWorkItem, IWorkItems
|
||||||
from loops.interfaces import IConceptSchema, ILoopsAdapter
|
from loops.interfaces import IConceptSchema, ILoopsAdapter
|
||||||
from loops.organize.interfaces import IPerson as IBasePerson
|
from loops.organize.interfaces import IPerson as IBasePerson
|
||||||
from loops.organize.interfaces import ITask as IBaseTask
|
from loops.organize.interfaces import ITask as IBaseTask
|
||||||
|
@ -63,3 +62,13 @@ class ITopic(IConceptSchema, IKnowledgeElement, ILoopsAdapter):
|
||||||
""" Just a topic, some general classification concept.
|
""" Just a topic, some general classification concept.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class IQualificationRecord(IWorkItem):
|
||||||
|
""" Records needs for qualification (acqusition of competence)
|
||||||
|
and corresponding participations in training events etc.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class IQualificationRecords(IWorkItems):
|
||||||
|
""" Container for qualification records.
|
||||||
|
"""
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2007 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2012 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,8 +19,6 @@
|
||||||
"""
|
"""
|
||||||
Adapters for IConcept providing interfaces from the
|
Adapters for IConcept providing interfaces from the
|
||||||
cybertools.knowledge package.
|
cybertools.knowledge package.
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope import interface, component
|
from zope import interface, component
|
||||||
|
|
|
@ -57,4 +57,19 @@
|
||||||
</metal:candidates>
|
</metal:candidates>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- forms -->
|
||||||
|
|
||||||
|
<metal:block define-macro="create_qualification">
|
||||||
|
<form method="post" id="addQualification_form" class="dialog"
|
||||||
|
dojoType="dijit.form.Form">
|
||||||
|
<div class="buttons">
|
||||||
|
<input value="Save" type="submit"
|
||||||
|
i18n:attributes="value">
|
||||||
|
<input type="button" value="Cancel"
|
||||||
|
onClick="return closeDialog(false)"
|
||||||
|
i18n:attributes="value"></div>
|
||||||
|
</form>
|
||||||
|
</metal:block>
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
96
knowledge/qualification.py
Normal file
96
knowledge/qualification.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2012 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
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Controlling qualification activities of persons.
|
||||||
|
|
||||||
|
Central part of CCM competence and certification management framework.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from zope.component import adapts
|
||||||
|
from zope.interface import implementer, implements
|
||||||
|
|
||||||
|
from cybertools.stateful.base import Stateful
|
||||||
|
from cybertools.stateful.definition import StatesDefinition
|
||||||
|
from cybertools.stateful.definition import State, Transition
|
||||||
|
from cybertools.stateful.interfaces import IStatesDefinition
|
||||||
|
from cybertools.tracking.interfaces import ITrackingStorage
|
||||||
|
from loops.knowledge.interfaces import IQualificationRecord, \
|
||||||
|
IQualificationRecords
|
||||||
|
from loops.organize.work.base import WorkItem, WorkItems
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(IStatesDefinition)
|
||||||
|
def qualificationStates():
|
||||||
|
return StatesDefinition('qualification',
|
||||||
|
State('open', 'open',
|
||||||
|
('register', 'pass', 'fail', 'cancel', 'modify'),
|
||||||
|
color='red'),
|
||||||
|
State('registered', 'registered',
|
||||||
|
('register', 'pass', 'fail', 'unregister', 'cancel', 'modify'),
|
||||||
|
color='yellow'),
|
||||||
|
State('passed', 'passed',
|
||||||
|
('cancel', 'close', 'modify', 'open', 'expire'),
|
||||||
|
color='green'),
|
||||||
|
State('failed', 'failed',
|
||||||
|
('register', 'cancel', 'modify', 'open'),
|
||||||
|
color='green'),
|
||||||
|
State('expired', 'expired',
|
||||||
|
('register', 'cancel', 'modify', 'open'),
|
||||||
|
color='red'),
|
||||||
|
State('cancelled', 'cancelled', ('modify', 'open'),
|
||||||
|
color='grey'),
|
||||||
|
State('closed', 'closed', ('modify', 'open'),
|
||||||
|
color='lightblue'),
|
||||||
|
# not directly reachable states:
|
||||||
|
State('open_x', 'open', ('modify',), color='red'),
|
||||||
|
State('registered_x', 'registered', ('modify',), color='yellow'),
|
||||||
|
# transitions:
|
||||||
|
Transition('register', 'register', 'registered'),
|
||||||
|
Transition('pass', 'pass', 'passed'),
|
||||||
|
Transition('fail', 'fail', 'failed'),
|
||||||
|
Transition('unregister', 'unregister', 'open'),
|
||||||
|
Transition('cancel', 'cancel', 'cancelled'),
|
||||||
|
Transition('close', 'close', 'closed'),
|
||||||
|
Transition('open', 'open', 'open'),
|
||||||
|
initialState='open')
|
||||||
|
|
||||||
|
|
||||||
|
class QualificationRecord(WorkItem):
|
||||||
|
|
||||||
|
implements(IQualificationRecord)
|
||||||
|
|
||||||
|
typeName = 'QualificationRecord'
|
||||||
|
typeInterface = IQualificationRecord
|
||||||
|
statesDefinition = 'knowledge.qualification'
|
||||||
|
|
||||||
|
def doAction(self, action, userName, **kw):
|
||||||
|
new = self.createNew(action, userName, **kw)
|
||||||
|
new.userName = self.userName
|
||||||
|
new.doTransition(action)
|
||||||
|
new.reindex()
|
||||||
|
return new
|
||||||
|
|
||||||
|
|
||||||
|
class QualificationRecords(WorkItems):
|
||||||
|
""" A tracking storage adapter managing qualification records.
|
||||||
|
"""
|
||||||
|
|
||||||
|
implements(IQualificationRecords)
|
||||||
|
adapts(ITrackingStorage)
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
#
|
|
||||||
# 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, ITopic
|
|
||||||
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 = ITopic
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
# $Id$
|
# tests.py - loops.knowledge package
|
||||||
|
|
||||||
|
import os
|
||||||
import unittest, doctest
|
import unittest, doctest
|
||||||
from zope.testing.doctestunit import DocFileSuite
|
from zope.testing.doctestunit import DocFileSuite
|
||||||
from zope.app.testing import ztapi
|
from zope.app.testing import ztapi
|
||||||
from zope.interface.verify import verifyClass
|
from zope.interface.verify import verifyClass
|
||||||
from loops.organize.party import Person
|
from loops.organize.party import Person
|
||||||
|
from loops.setup import importData as baseImportData
|
||||||
|
|
||||||
|
|
||||||
|
def importData(loopsRoot):
|
||||||
|
importPath = os.path.join(os.path.dirname(__file__), 'data')
|
||||||
|
baseImportData(loopsRoot, importPath, 'loops_knowledge_de.dmp')
|
||||||
|
|
||||||
|
|
||||||
class Test(unittest.TestCase):
|
class Test(unittest.TestCase):
|
||||||
"Basic tests for the knowledge sub-package."
|
"Basic tests for the knowledge sub-package."
|
||||||
|
|
|
@ -260,7 +260,7 @@ Automatic security settings on persons
|
||||||
|
|
||||||
>>> from zope.traversing.api import getName
|
>>> from zope.traversing.api import getName
|
||||||
>>> list(sorted(getName(c) for c in concepts['person'].getChildren()))
|
>>> list(sorted(getName(c) for c in concepts['person'].getChildren()))
|
||||||
[u'jim', u'john', u'martha', u'person.newuser']
|
[u'general', u'jim', u'john', u'martha', u'person.newuser']
|
||||||
|
|
||||||
Person objects that have a user assigned to them receive this user
|
Person objects that have a user assigned to them receive this user
|
||||||
(principal) as their owner.
|
(principal) as their owner.
|
||||||
|
@ -358,7 +358,7 @@ Task view with edit action
|
||||||
>>> from loops.organize.browser.task import TaskView
|
>>> from loops.organize.browser.task import TaskView
|
||||||
>>> view = TaskView(task01, TestRequest())
|
>>> view = TaskView(task01, TestRequest())
|
||||||
>>> list(view.getActions('portlet'))
|
>>> list(view.getActions('portlet'))
|
||||||
[]
|
[...]
|
||||||
|
|
||||||
OK, the action is not provided automatically any more by the TaskView
|
OK, the action is not provided automatically any more by the TaskView
|
||||||
but has to be entered as a type option.
|
but has to be entered as a type option.
|
||||||
|
@ -404,7 +404,7 @@ Send Email to Members
|
||||||
>>> form.subject
|
>>> form.subject
|
||||||
u"loops Notification from '$site'"
|
u"loops Notification from '$site'"
|
||||||
>>> form.mailBody
|
>>> form.mailBody
|
||||||
u'\n\nEvent #1\nhttp://127.0.0.1/loops/views/menu/.97\n\n'
|
u'\n\nEvent #1\nhttp://127.0.0.1/loops/views/menu/.116\n\n'
|
||||||
|
|
||||||
|
|
||||||
Show Presence of Other Users
|
Show Presence of Other Users
|
||||||
|
|
|
@ -18,7 +18,7 @@ Let's set up a loops site with basic and example concepts and resources.
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
>>> loopsRoot = site['loops']
|
>>> loopsRoot = site['loops']
|
||||||
>>> len(concepts), len(resources), len(views)
|
>>> len(concepts), len(resources), len(views)
|
||||||
(30, 3, 1)
|
(34, 3, 1)
|
||||||
|
|
||||||
>>> from cybertools.tracking.btree import TrackingStorage
|
>>> from cybertools.tracking.btree import TrackingStorage
|
||||||
>>> from loops.system.job import JobRecord
|
>>> from loops.system.job import JobRecord
|
||||||
|
|
|
@ -26,14 +26,12 @@ configuration):
|
||||||
>>> t = TestSite(site)
|
>>> t = TestSite(site)
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
|
|
||||||
>>> #sorted(concepts)
|
|
||||||
>>> #sorted(resources)
|
|
||||||
>>> len(concepts) + len(resources)
|
|
||||||
23
|
|
||||||
|
|
||||||
>>> loopsRoot = site['loops']
|
>>> loopsRoot = site['loops']
|
||||||
>>> loopsRoot.options = ['useVersioning']
|
>>> loopsRoot.options = ['useVersioning']
|
||||||
|
|
||||||
|
>>> len(concepts) + len(resources)
|
||||||
|
16
|
||||||
|
|
||||||
|
|
||||||
Version Information
|
Version Information
|
||||||
===================
|
===================
|
||||||
|
|
|
@ -33,7 +33,7 @@ from loops.config.base import LoopsOptions
|
||||||
from loops.interfaces import ILoopsObject, IConcept
|
from loops.interfaces import ILoopsObject, IConcept
|
||||||
from loops.resource import Resource
|
from loops.resource import Resource
|
||||||
from loops.resource import IndexAttributes as ResourceIndexAttributes
|
from loops.resource import IndexAttributes as ResourceIndexAttributes
|
||||||
from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
#from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
||||||
from loops.setup import SetupManager, addObject
|
from loops.setup import SetupManager, addObject
|
||||||
from loops.type import ConceptType, ResourceType, TypeConcept
|
from loops.type import ConceptType, ResourceType, TypeConcept
|
||||||
from loops.versioning.versionable import cleanupVersions
|
from loops.versioning.versionable import cleanupVersions
|
||||||
|
@ -74,7 +74,7 @@ class TestSite(object):
|
||||||
|
|
||||||
loopsRoot = site['loops'] = Loops()
|
loopsRoot = site['loops'] = Loops()
|
||||||
|
|
||||||
component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
#component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
||||||
setup = SetupManager(loopsRoot)
|
setup = SetupManager(loopsRoot)
|
||||||
concepts, resources, views = setup.setup()
|
concepts, resources, views = setup.setup()
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@ ZCML setup):
|
||||||
>>> from loops.setup import addObject
|
>>> from loops.setup import addObject
|
||||||
>>> from loops.organize.setup import SetupManager as OrganizeSetupManager
|
>>> from loops.organize.setup import SetupManager as OrganizeSetupManager
|
||||||
>>> component.provideAdapter(OrganizeSetupManager, name='organize')
|
>>> component.provideAdapter(OrganizeSetupManager, name='organize')
|
||||||
>>> from loops.knowledge.setup import SetupManager as KnowledgeSetupManager
|
|
||||||
>>> component.provideAdapter(KnowledgeSetupManager, name='knowledge')
|
|
||||||
>>> from loops.tests.setup import TestSite
|
>>> from loops.tests.setup import TestSite
|
||||||
>>> t = TestSite(site)
|
>>> t = TestSite(site)
|
||||||
>>> concepts, resources, views = t.setup()
|
>>> concepts, resources, views = t.setup()
|
||||||
|
@ -31,10 +29,13 @@ ZCML setup):
|
||||||
>>> loopsRoot = site['loops']
|
>>> loopsRoot = site['loops']
|
||||||
>>> loopsId = util.getUidForObject(loopsRoot)
|
>>> loopsId = util.getUidForObject(loopsRoot)
|
||||||
|
|
||||||
|
>>> from loops.knowledge.tests import importData
|
||||||
|
>>> importData(loopsRoot)
|
||||||
|
|
||||||
Let's look what setup has provided us with:
|
Let's look what setup has provided us with:
|
||||||
|
|
||||||
>>> len(concepts)
|
>>> len(concepts)
|
||||||
18
|
23
|
||||||
|
|
||||||
Now let's add a few more concepts:
|
Now let's add a few more concepts:
|
||||||
|
|
||||||
|
@ -71,10 +72,11 @@ note that the 'hasType' predicate is not shown as it should not be
|
||||||
applied in an explicit assignment.
|
applied in an explicit assignment.
|
||||||
|
|
||||||
>>> sorted(t['name'] for t in xrf.getConceptTypes())
|
>>> sorted(t['name'] for t in xrf.getConceptTypes())
|
||||||
[u'customer', u'domain', u'file', u'note', u'person', u'predicate',
|
[u'competence', u'customer', u'domain', u'file', u'note', u'person',
|
||||||
u'task', u'textdocument', u'topic', u'type']
|
u'predicate', u'task', u'textdocument', u'topic', u'training', u'type']
|
||||||
>>> sorted(t['name'] for t in xrf.getPredicates())
|
>>> sorted(t['name'] for t in xrf.getPredicates())
|
||||||
[u'depends', u'knows', u'ownedby', u'provides', u'requires', u'standard']
|
[u'depends', u'issubtype', u'knows', u'ownedby', u'provides', u'requires',
|
||||||
|
u'standard']
|
||||||
|
|
||||||
We can also retrieve a certain object by its id or its name:
|
We can also retrieve a certain object by its id or its name:
|
||||||
|
|
||||||
|
@ -93,8 +95,8 @@ All methods that retrieve one object also returns its children and parents:
|
||||||
>>> ch[0]['name']
|
>>> ch[0]['name']
|
||||||
u'hasType'
|
u'hasType'
|
||||||
>>> sorted(c['name'] for c in ch[0]['objects'])
|
>>> sorted(c['name'] for c in ch[0]['objects'])
|
||||||
[u'customer', u'domain', u'file', u'note', u'person', u'predicate',
|
[u'competence', u'customer', u'domain', u'file', u'note', u'person',
|
||||||
u'task', u'textdocument', u'topic', u'type']
|
u'predicate', u'task', u'textdocument', u'topic', u'training', u'type']
|
||||||
|
|
||||||
>>> pa = defaultPred['parents']
|
>>> pa = defaultPred['parents']
|
||||||
>>> len(pa)
|
>>> len(pa)
|
||||||
|
@ -112,8 +114,8 @@ We can also retrieve children and parents explicitely:
|
||||||
>>> ch[0]['name']
|
>>> ch[0]['name']
|
||||||
u'hasType'
|
u'hasType'
|
||||||
>>> sorted(c['name'] for c in ch[0]['objects'])
|
>>> sorted(c['name'] for c in ch[0]['objects'])
|
||||||
[u'customer', u'domain', u'file', u'note', u'person', u'predicate',
|
[u'competence', u'customer', u'domain', u'file', u'note', u'person',
|
||||||
u'task', u'textdocument', u'topic', u'type']
|
u'predicate', u'task', u'textdocument', u'topic', u'training', u'type']
|
||||||
|
|
||||||
>>> pa = xrf.getParents('6')
|
>>> pa = xrf.getParents('6')
|
||||||
>>> len(pa)
|
>>> len(pa)
|
||||||
|
@ -172,14 +174,14 @@ Updating the concept map
|
||||||
|
|
||||||
>>> topicId = xrf.getObjectByName('topic')['id']
|
>>> topicId = xrf.getObjectByName('topic')['id']
|
||||||
>>> xrf.createConcept(topicId, u'zope2', u'Zope 2')
|
>>> xrf.createConcept(topicId, u'zope2', u'Zope 2')
|
||||||
{'description': u'', 'title': u'Zope 2', 'type': '22', 'id': '54',
|
{'description': u'', 'title': u'Zope 2', 'type': '36', 'id': '75',
|
||||||
'name': u'zope2'}
|
'name': u'zope2'}
|
||||||
|
|
||||||
The name of the concept is checked by a name chooser; if the corresponding
|
The name of the concept is checked by a name chooser; if the corresponding
|
||||||
parameter is empty, the name will be generated from the title.
|
parameter is empty, the name will be generated from the title.
|
||||||
|
|
||||||
>>> xrf.createConcept(topicId, u'', u'Python')
|
>>> xrf.createConcept(topicId, u'', u'Python')
|
||||||
{'description': u'', 'title': u'Python', 'type': '22', 'id': '56',
|
{'description': u'', 'title': u'Python', 'type': '36', 'id': '77',
|
||||||
'name': u'python'}
|
'name': u'python'}
|
||||||
|
|
||||||
If we try to deassign a ``hasType`` relation nothing will happen; a
|
If we try to deassign a ``hasType`` relation nothing will happen; a
|
||||||
|
|
Loading…
Add table
Reference in a new issue