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:
helmutm 2007-10-09 15:19:13 +00:00
parent eee4e198c0
commit 96d0462b18
13 changed files with 161 additions and 14 deletions

View file

@ -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
View file

@ -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

View file

@ -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:

View file

@ -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

View 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>

View file

@ -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>

View file

@ -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',

View file

@ -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')

View file

@ -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

View file

@ -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

View file

@ -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):

View file

@ -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
View file

@ -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.