work in progress: classifier
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2106 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
eee4e198c0
commit
96d0462b18
13 changed files with 161 additions and 14 deletions
19
README.txt
19
README.txt
|
@ -768,6 +768,25 @@ target object's view here:
|
||||||
'http://127.0.0.1/loops/views/m1/m11/m111/.target23'
|
'http://127.0.0.1/loops/views/m1/m11/m111/.target23'
|
||||||
|
|
||||||
|
|
||||||
|
Collecting Information about Parents
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Sometimes, e.g. when checking permissions, it is important to collect
|
||||||
|
informations about all parents of an object.
|
||||||
|
|
||||||
|
>>> parents = m113.getAllParents()
|
||||||
|
>>> for p in parents:
|
||||||
|
... print p.object.title
|
||||||
|
Zope
|
||||||
|
Menu
|
||||||
|
|
||||||
|
>>> parents = resources['test_note'].getAllParents()
|
||||||
|
>>> for p in parents:
|
||||||
|
... print p.object.title, len(p.relations)
|
||||||
|
Note 1
|
||||||
|
Type 2
|
||||||
|
|
||||||
|
|
||||||
Import/Export
|
Import/Export
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
12
base.py
12
base.py
|
@ -29,6 +29,7 @@ from zope.app.folder.interfaces import IFolder
|
||||||
from zope.traversing.api import getPath, traverse
|
from zope.traversing.api import getPath, traverse
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
|
|
||||||
|
from cybertools.util.jeep import Jeep
|
||||||
from loops.interfaces import ILoops
|
from loops.interfaces import ILoops
|
||||||
|
|
||||||
loopsPrefix = '.loops'
|
loopsPrefix = '.loops'
|
||||||
|
@ -58,6 +59,9 @@ class Loops(Folder):
|
||||||
def getLoopsRoot(self):
|
def getLoopsRoot(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False):
|
||||||
|
return Jeep()
|
||||||
|
|
||||||
def getConceptManager(self):
|
def getConceptManager(self):
|
||||||
return self['concepts']
|
return self['concepts']
|
||||||
|
|
||||||
|
@ -76,6 +80,14 @@ class Loops(Folder):
|
||||||
return traverse(self, uri[len(prefix):])
|
return traverse(self, uri[len(prefix):])
|
||||||
|
|
||||||
|
|
||||||
|
class ParentInfo(object):
|
||||||
|
|
||||||
|
def __init__(self, obj, relations=None, grants=None):
|
||||||
|
self.object = obj
|
||||||
|
self.relations = relations or []
|
||||||
|
self.grants = grants or []
|
||||||
|
|
||||||
|
|
||||||
# backward compatibility for old loops sites that got their Loops object
|
# backward compatibility for old loops sites that got their Loops object
|
||||||
# directly from loops/__init__.py
|
# directly from loops/__init__.py
|
||||||
import loops
|
import loops
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Classifier(AdapterBase):
|
||||||
for name in self.extractors.split():
|
for name in self.extractors.split():
|
||||||
extractor = component.getAdapter(adapted(resource), IExtractor, name=name)
|
extractor = component.getAdapter(adapted(resource), IExtractor, name=name)
|
||||||
infoSet.update(extractor.extractInformationSet())
|
infoSet.update(extractor.extractInformationSet())
|
||||||
analyzer = component.getAdapter(self, name=self.analyzer)
|
analyzer = component.getAdapter(self, IAnalyzer, name=self.analyzer)
|
||||||
statements = analyzer.extractStatements(infoSet)
|
statements = analyzer.extractStatements(infoSet)
|
||||||
defaultPredicate = self.context.getConceptManager().getDefaultPredicate()
|
defaultPredicate = self.context.getConceptManager().getDefaultPredicate()
|
||||||
for statement in statements:
|
for statement in statements:
|
||||||
|
|
|
@ -28,3 +28,36 @@ from zope.cachedescriptors.property import Lazy
|
||||||
|
|
||||||
from loops.browser.concept import ConceptView
|
from loops.browser.concept import ConceptView
|
||||||
from loops.common import adapted
|
from loops.common import adapted
|
||||||
|
|
||||||
|
|
||||||
|
class ClassifierView(ConceptView):
|
||||||
|
|
||||||
|
macro_template = ViewPageTemplateFile('classifier_macros.pt')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def macro(self):
|
||||||
|
return self.macro_template.macros['render_classifier']
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if 'update' in self.request.form:
|
||||||
|
cta = adapted(self.context)
|
||||||
|
if cta is not None:
|
||||||
|
for r in collectResources(self.context):
|
||||||
|
print '***', r.title
|
||||||
|
cta.process(r)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def collectResources(concept, checkedConcepts=None, result=None):
|
||||||
|
if result is None:
|
||||||
|
result = []
|
||||||
|
if checkedConcepts is None:
|
||||||
|
checkedConcepts = []
|
||||||
|
for r in concept.getResources():
|
||||||
|
if r not in result:
|
||||||
|
result.append(r)
|
||||||
|
for c in concept.getChildren():
|
||||||
|
if c not in checkedConcepts:
|
||||||
|
checkedConcepts.append(c)
|
||||||
|
collectResources(c, checkedConcepts, result)
|
||||||
|
return result
|
||||||
|
|
11
classifier/classifier_macros.pt
Normal file
11
classifier/classifier_macros.pt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<metal:resources define-macro="render_classifier"
|
||||||
|
tal:define="dummy item/update">
|
||||||
|
|
||||||
|
<metal:concept use-macro="item/template/macros/conceptdata" />
|
||||||
|
|
||||||
|
<form action="." method="post">
|
||||||
|
<input type="submit" name="update" value="Run Auto-Classification" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</metal:resources>
|
||||||
|
|
|
@ -30,15 +30,25 @@
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
||||||
<zope:adapter
|
<zope:adapter
|
||||||
factory="loops.classifier.sample.Analyzer"
|
factory="loops.classifier.sample.SampleAnalyzer"
|
||||||
name="sample"
|
name="sample"
|
||||||
trusted="True" />
|
trusted="True" />
|
||||||
|
|
||||||
<zope:class class="loops.classifier.sample.Analyzer">
|
<zope:class class="loops.classifier.sample.SampleAnalyzer">
|
||||||
<require permission="zope.View"
|
<require permission="zope.View"
|
||||||
interface="loops.classifier.interfaces.IAnalyzer" />
|
interface="loops.classifier.interfaces.IAnalyzer" />
|
||||||
<require permission="zope.ManageContent"
|
<require permission="zope.ManageContent"
|
||||||
set_schema="loops.classifier.interfaces.IAnalyzer" />
|
set_schema="loops.classifier.interfaces.IAnalyzer" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
||||||
|
<!-- view -->
|
||||||
|
|
||||||
|
<zope:adapter
|
||||||
|
name="classifier.html"
|
||||||
|
for="loops.interfaces.IConcept
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
|
provides="zope.interface.Interface"
|
||||||
|
factory="loops.classifier.browser.ClassifierView"
|
||||||
|
permission="zope.View" />
|
||||||
|
|
||||||
</configure>
|
</configure>
|
||||||
|
|
|
@ -43,8 +43,6 @@ class TestSite(BaseTestSite):
|
||||||
component.provideAdapter(OrganizeSetupManager, name='organize')
|
component.provideAdapter(OrganizeSetupManager, name='organize')
|
||||||
concepts, resources, views = self.baseSetup()
|
concepts, resources, views = self.baseSetup()
|
||||||
|
|
||||||
#catalog = component.getUtility(ICatalog)
|
|
||||||
#catalog['loops_text'] = TextIndex('text', IIndexAttributes, True)
|
|
||||||
# classifier and Co
|
# classifier and Co
|
||||||
tType = concepts.getTypeConcept()
|
tType = concepts.getTypeConcept()
|
||||||
tClassifier = addAndConfigureObject(concepts, Concept, 'classifier',
|
tClassifier = addAndConfigureObject(concepts, Concept, 'classifier',
|
||||||
|
|
20
concept.py
20
concept.py
|
@ -39,11 +39,14 @@ from cybertools.relation.registry import getRelations
|
||||||
from cybertools.relation.registry import getRelationSingle, setRelationSingle
|
from cybertools.relation.registry import getRelationSingle, setRelationSingle
|
||||||
from cybertools.relation.interfaces import IRelationRegistry, IRelatable
|
from cybertools.relation.interfaces import IRelationRegistry, IRelatable
|
||||||
from cybertools.typology.interfaces import IType, ITypeManager
|
from cybertools.typology.interfaces import IType, ITypeManager
|
||||||
|
from cybertools.util.jeep import Jeep
|
||||||
|
|
||||||
|
from loops.base import ParentInfo
|
||||||
from loops.interfaces import IConcept, IConceptRelation, IConceptView
|
from loops.interfaces import IConcept, IConceptRelation, IConceptView
|
||||||
from loops.interfaces import IConceptManager, IConceptManagerContained
|
from loops.interfaces import IConceptManager, IConceptManagerContained
|
||||||
from loops.interfaces import ILoopsContained
|
from loops.interfaces import ILoopsContained
|
||||||
from loops.interfaces import IIndexAttributes
|
from loops.interfaces import IIndexAttributes
|
||||||
|
from loops import util
|
||||||
from loops.view import TargetRelation
|
from loops.view import TargetRelation
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,6 +135,20 @@ class Concept(Contained, Persistent):
|
||||||
def getConceptManager(self):
|
def getConceptManager(self):
|
||||||
return self.getLoopsRoot().getConceptManager()
|
return self.getLoopsRoot().getConceptManager()
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False, result=None):
|
||||||
|
if result is None:
|
||||||
|
result = Jeep()
|
||||||
|
for rel in self.getParentRelations():
|
||||||
|
obj = rel.first
|
||||||
|
uid = util.getUidForObject(obj)
|
||||||
|
pi = result.get(uid)
|
||||||
|
if pi is None:
|
||||||
|
result[uid] = ParentInfo(obj, [rel])
|
||||||
|
obj.getAllParents(collectGrants, result)
|
||||||
|
elif rel not in pi.relations:
|
||||||
|
pi.relations.append(rel)
|
||||||
|
return result
|
||||||
|
|
||||||
# concept relations
|
# concept relations
|
||||||
|
|
||||||
def getClients(self, relationships=None):
|
def getClients(self, relationships=None):
|
||||||
|
@ -215,6 +232,9 @@ class ConceptManager(BTreeContainer):
|
||||||
def getLoopsRoot(self):
|
def getLoopsRoot(self):
|
||||||
return zapi.getParent(self)
|
return zapi.getParent(self)
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False):
|
||||||
|
return Jeep()
|
||||||
|
|
||||||
def getTypePredicate(self):
|
def getTypePredicate(self):
|
||||||
return self.get('hasType')
|
return self.get('hasType')
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ from zope.cachedescriptors.property import Lazy
|
||||||
|
|
||||||
from cybertools.typology.interfaces import IType
|
from cybertools.typology.interfaces import IType
|
||||||
from loops.browser.concept import ConceptView
|
from loops.browser.concept import ConceptView
|
||||||
|
from loops.common import adapted
|
||||||
|
|
||||||
|
|
||||||
class ExternalCollectionView(ConceptView):
|
class ExternalCollectionView(ConceptView):
|
||||||
|
@ -40,9 +41,8 @@ class ExternalCollectionView(ConceptView):
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
if 'update' in self.request.form:
|
if 'update' in self.request.form:
|
||||||
ti = IType(self.context).typeInterface
|
cta = adapted(self.context)
|
||||||
if ti is not None:
|
if cta is not None:
|
||||||
adapted = ti(self.context)
|
cta.update()
|
||||||
adapted.update()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -156,4 +156,6 @@ class DirectoryCollectionProvider(object):
|
||||||
base, ext = title.rsplit('.', 1)
|
base, ext = title.rsplit('.', 1)
|
||||||
if ext.lower() in mimetypes.extensions.values():
|
if ext.lower() in mimetypes.extensions.values():
|
||||||
title = base
|
title = base
|
||||||
return title.decode('UTF-8')
|
if not isinstance(title, unicode):
|
||||||
|
title = title.decode('UTF-8')
|
||||||
|
return title
|
||||||
|
|
|
@ -42,12 +42,20 @@ class ILoopsObject(Interface):
|
||||||
""" Common top-level interface.
|
""" Common top-level interface.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
title = Attribute(u'A short line of information about an object to be '
|
||||||
|
'used e.g. for menu items or listing entries.')
|
||||||
|
|
||||||
def getLoopsRoot():
|
def getLoopsRoot():
|
||||||
""" Return the loops root object.
|
""" Return the loops root object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
title = Attribute(u'A short line of information about an object to be '
|
def getAllParents(collectGrants=False):
|
||||||
'used e.g. for menu items or listing entries.')
|
""" Return a sequence (or an ordered mapping / Jeep object)
|
||||||
|
with informations about all parents of the object.
|
||||||
|
|
||||||
|
If ``collectGrants`` is set also collect grant information
|
||||||
|
(assigned/effective roles) together with the parents.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class IPotentialTarget(Interface):
|
class IPotentialTarget(Interface):
|
||||||
|
|
21
resource.py
21
resource.py
|
@ -49,7 +49,11 @@ from cybertools.relation.interfaces import IRelatable
|
||||||
from cybertools.storage.interfaces import IExternalStorage
|
from cybertools.storage.interfaces import IExternalStorage
|
||||||
from cybertools.text.interfaces import ITextTransform
|
from cybertools.text.interfaces import ITextTransform
|
||||||
from cybertools.typology.interfaces import IType, ITypeManager
|
from cybertools.typology.interfaces import IType, ITypeManager
|
||||||
|
from cybertools.util.jeep import Jeep
|
||||||
|
|
||||||
|
from loops.base import ParentInfo
|
||||||
|
from loops.common import ResourceAdapterBase, adapted
|
||||||
|
from loops.concept import ResourceRelation
|
||||||
from loops.interfaces import IBaseResource, IResource
|
from loops.interfaces import IBaseResource, IResource
|
||||||
from loops.interfaces import IFile, IExternalFile, INote
|
from loops.interfaces import IFile, IExternalFile, INote
|
||||||
from loops.interfaces import IDocument, ITextDocument, IDocumentSchema, IDocumentView
|
from loops.interfaces import IDocument, ITextDocument, IDocumentSchema, IDocumentView
|
||||||
|
@ -58,8 +62,7 @@ from loops.interfaces import IResourceManager, IResourceManagerContained
|
||||||
from loops.interfaces import ITypeConcept
|
from loops.interfaces import ITypeConcept
|
||||||
from loops.interfaces import ILoopsContained
|
from loops.interfaces import ILoopsContained
|
||||||
from loops.interfaces import IIndexAttributes
|
from loops.interfaces import IIndexAttributes
|
||||||
from loops.concept import ResourceRelation
|
from loops import util
|
||||||
from loops.common import ResourceAdapterBase, adapted
|
|
||||||
from loops.versioning.util import getMaster
|
from loops.versioning.util import getMaster
|
||||||
from loops.view import TargetRelation
|
from loops.view import TargetRelation
|
||||||
|
|
||||||
|
@ -76,6 +79,9 @@ class ResourceManager(BTreeContainer):
|
||||||
def getViewManager(self):
|
def getViewManager(self):
|
||||||
return self.getLoopsRoot().getViewManager()
|
return self.getLoopsRoot().getViewManager()
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False):
|
||||||
|
return Jeep()
|
||||||
|
|
||||||
|
|
||||||
class Resource(Image, Contained):
|
class Resource(Image, Contained):
|
||||||
|
|
||||||
|
@ -161,6 +167,17 @@ class Resource(Image, Contained):
|
||||||
def getLoopsRoot(self):
|
def getLoopsRoot(self):
|
||||||
return zapi.getParent(self).getLoopsRoot()
|
return zapi.getParent(self).getLoopsRoot()
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False):
|
||||||
|
result = Jeep()
|
||||||
|
for rel in self.getConceptRelations():
|
||||||
|
obj = rel.first
|
||||||
|
uid = util.getUidForObject(obj)
|
||||||
|
pi = result.setdefault(uid, ParentInfo(obj))
|
||||||
|
if rel not in pi.relations:
|
||||||
|
pi.relations.append(rel)
|
||||||
|
obj.getAllParents(collectGrants, result)
|
||||||
|
return result
|
||||||
|
|
||||||
# concept relations
|
# concept relations
|
||||||
# note: we always use the master version for relations, see getMaster()
|
# note: we always use the master version for relations, see getMaster()
|
||||||
|
|
||||||
|
|
17
view.py
17
view.py
|
@ -39,13 +39,16 @@ from persistent import Persistent
|
||||||
from cybertools.relation import DyadicRelation
|
from cybertools.relation import DyadicRelation
|
||||||
from cybertools.relation.registry import getRelations
|
from cybertools.relation.registry import getRelations
|
||||||
from cybertools.relation.interfaces import IRelationRegistry, IRelatable
|
from cybertools.relation.interfaces import IRelationRegistry, IRelatable
|
||||||
|
from cybertools.util.jeep import Jeep
|
||||||
|
|
||||||
|
from loops.base import ParentInfo
|
||||||
from loops.interfaces import IView, INode
|
from loops.interfaces import IView, INode
|
||||||
from loops.interfaces import IViewManager, INodeContained
|
from loops.interfaces import IViewManager, INodeContained
|
||||||
from loops.interfaces import ILoopsContained
|
from loops.interfaces import ILoopsContained
|
||||||
from loops.interfaces import ITargetRelation
|
from loops.interfaces import ITargetRelation
|
||||||
from loops.interfaces import IConcept
|
from loops.interfaces import IConcept
|
||||||
from loops.versioning.util import getVersion
|
from loops.versioning.util import getVersion
|
||||||
|
from loops import util
|
||||||
|
|
||||||
|
|
||||||
class View(object):
|
class View(object):
|
||||||
|
@ -103,6 +106,9 @@ class View(object):
|
||||||
def getLoopsRoot(self):
|
def getLoopsRoot(self):
|
||||||
return zapi.getParent(self).getLoopsRoot()
|
return zapi.getParent(self).getLoopsRoot()
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False):
|
||||||
|
return Jeep()
|
||||||
|
|
||||||
|
|
||||||
class Node(View, OrderedContainer):
|
class Node(View, OrderedContainer):
|
||||||
|
|
||||||
|
@ -128,6 +134,14 @@ class Node(View, OrderedContainer):
|
||||||
parent = zapi.getParent(parent)
|
parent = zapi.getParent(parent)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False):
|
||||||
|
result = Jeep()
|
||||||
|
parent = self.getParentNode()
|
||||||
|
while parent is not None:
|
||||||
|
result[util.getUidForObject(parent)] = ParentInfo(parent)
|
||||||
|
parent = parent.getParentNode()
|
||||||
|
return result
|
||||||
|
|
||||||
def getChildNodes(self, nodeTypes=None):
|
def getChildNodes(self, nodeTypes=None):
|
||||||
for item in self.values():
|
for item in self.values():
|
||||||
if INode.providedBy(item) \
|
if INode.providedBy(item) \
|
||||||
|
@ -170,6 +184,9 @@ class ViewManager(OrderedContainer):
|
||||||
def getViewManager(self):
|
def getViewManager(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def getAllParents(self, collectGrants=False):
|
||||||
|
return Jeep()
|
||||||
|
|
||||||
|
|
||||||
class TargetRelation(DyadicRelation):
|
class TargetRelation(DyadicRelation):
|
||||||
""" A relation between a view and its target.
|
""" A relation between a view and its target.
|
||||||
|
|
Loading…
Add table
Reference in a new issue