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'
|
||||
|
||||
|
||||
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
|
||||
=============
|
||||
|
||||
|
|
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.interface import implements
|
||||
|
||||
from cybertools.util.jeep import Jeep
|
||||
from loops.interfaces import ILoops
|
||||
|
||||
loopsPrefix = '.loops'
|
||||
|
@ -58,6 +59,9 @@ class Loops(Folder):
|
|||
def getLoopsRoot(self):
|
||||
return self
|
||||
|
||||
def getAllParents(self, collectGrants=False):
|
||||
return Jeep()
|
||||
|
||||
def getConceptManager(self):
|
||||
return self['concepts']
|
||||
|
||||
|
@ -76,6 +80,14 @@ class Loops(Folder):
|
|||
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
|
||||
# directly from loops/__init__.py
|
||||
import loops
|
||||
|
|
|
@ -61,7 +61,7 @@ class Classifier(AdapterBase):
|
|||
for name in self.extractors.split():
|
||||
extractor = component.getAdapter(adapted(resource), IExtractor, name=name)
|
||||
infoSet.update(extractor.extractInformationSet())
|
||||
analyzer = component.getAdapter(self, name=self.analyzer)
|
||||
analyzer = component.getAdapter(self, IAnalyzer, name=self.analyzer)
|
||||
statements = analyzer.extractStatements(infoSet)
|
||||
defaultPredicate = self.context.getConceptManager().getDefaultPredicate()
|
||||
for statement in statements:
|
||||
|
|
|
@ -28,3 +28,36 @@ from zope.cachedescriptors.property import Lazy
|
|||
|
||||
from loops.browser.concept import ConceptView
|
||||
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:adapter
|
||||
factory="loops.classifier.sample.Analyzer"
|
||||
factory="loops.classifier.sample.SampleAnalyzer"
|
||||
name="sample"
|
||||
trusted="True" />
|
||||
|
||||
<zope:class class="loops.classifier.sample.Analyzer">
|
||||
<zope:class class="loops.classifier.sample.SampleAnalyzer">
|
||||
<require permission="zope.View"
|
||||
interface="loops.classifier.interfaces.IAnalyzer" />
|
||||
<require permission="zope.ManageContent"
|
||||
set_schema="loops.classifier.interfaces.IAnalyzer" />
|
||||
</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>
|
||||
|
|
|
@ -43,8 +43,6 @@ class TestSite(BaseTestSite):
|
|||
component.provideAdapter(OrganizeSetupManager, name='organize')
|
||||
concepts, resources, views = self.baseSetup()
|
||||
|
||||
#catalog = component.getUtility(ICatalog)
|
||||
#catalog['loops_text'] = TextIndex('text', IIndexAttributes, True)
|
||||
# classifier and Co
|
||||
tType = concepts.getTypeConcept()
|
||||
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.interfaces import IRelationRegistry, IRelatable
|
||||
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 IConceptManager, IConceptManagerContained
|
||||
from loops.interfaces import ILoopsContained
|
||||
from loops.interfaces import IIndexAttributes
|
||||
from loops import util
|
||||
from loops.view import TargetRelation
|
||||
|
||||
|
||||
|
@ -132,6 +135,20 @@ class Concept(Contained, Persistent):
|
|||
def getConceptManager(self):
|
||||
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
|
||||
|
||||
def getClients(self, relationships=None):
|
||||
|
@ -215,6 +232,9 @@ class ConceptManager(BTreeContainer):
|
|||
def getLoopsRoot(self):
|
||||
return zapi.getParent(self)
|
||||
|
||||
def getAllParents(self, collectGrants=False):
|
||||
return Jeep()
|
||||
|
||||
def getTypePredicate(self):
|
||||
return self.get('hasType')
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ from zope.cachedescriptors.property import Lazy
|
|||
|
||||
from cybertools.typology.interfaces import IType
|
||||
from loops.browser.concept import ConceptView
|
||||
from loops.common import adapted
|
||||
|
||||
|
||||
class ExternalCollectionView(ConceptView):
|
||||
|
@ -40,9 +41,8 @@ class ExternalCollectionView(ConceptView):
|
|||
|
||||
def update(self):
|
||||
if 'update' in self.request.form:
|
||||
ti = IType(self.context).typeInterface
|
||||
if ti is not None:
|
||||
adapted = ti(self.context)
|
||||
adapted.update()
|
||||
cta = adapted(self.context)
|
||||
if cta is not None:
|
||||
cta.update()
|
||||
return True
|
||||
|
||||
|
|
|
@ -156,4 +156,6 @@ class DirectoryCollectionProvider(object):
|
|||
base, ext = title.rsplit('.', 1)
|
||||
if ext.lower() in mimetypes.extensions.values():
|
||||
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.
|
||||
"""
|
||||
|
||||
title = Attribute(u'A short line of information about an object to be '
|
||||
'used e.g. for menu items or listing entries.')
|
||||
|
||||
def getLoopsRoot():
|
||||
""" Return the loops root object.
|
||||
"""
|
||||
|
||||
title = Attribute(u'A short line of information about an object to be '
|
||||
'used e.g. for menu items or listing entries.')
|
||||
def getAllParents(collectGrants=False):
|
||||
""" 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):
|
||||
|
|
21
resource.py
21
resource.py
|
@ -49,7 +49,11 @@ from cybertools.relation.interfaces import IRelatable
|
|||
from cybertools.storage.interfaces import IExternalStorage
|
||||
from cybertools.text.interfaces import ITextTransform
|
||||
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 IFile, IExternalFile, INote
|
||||
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 ILoopsContained
|
||||
from loops.interfaces import IIndexAttributes
|
||||
from loops.concept import ResourceRelation
|
||||
from loops.common import ResourceAdapterBase, adapted
|
||||
from loops import util
|
||||
from loops.versioning.util import getMaster
|
||||
from loops.view import TargetRelation
|
||||
|
||||
|
@ -76,6 +79,9 @@ class ResourceManager(BTreeContainer):
|
|||
def getViewManager(self):
|
||||
return self.getLoopsRoot().getViewManager()
|
||||
|
||||
def getAllParents(self, collectGrants=False):
|
||||
return Jeep()
|
||||
|
||||
|
||||
class Resource(Image, Contained):
|
||||
|
||||
|
@ -161,6 +167,17 @@ class Resource(Image, Contained):
|
|||
def getLoopsRoot(self):
|
||||
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
|
||||
# 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.registry import getRelations
|
||||
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 IViewManager, INodeContained
|
||||
from loops.interfaces import ILoopsContained
|
||||
from loops.interfaces import ITargetRelation
|
||||
from loops.interfaces import IConcept
|
||||
from loops.versioning.util import getVersion
|
||||
from loops import util
|
||||
|
||||
|
||||
class View(object):
|
||||
|
@ -103,6 +106,9 @@ class View(object):
|
|||
def getLoopsRoot(self):
|
||||
return zapi.getParent(self).getLoopsRoot()
|
||||
|
||||
def getAllParents(self, collectGrants=False):
|
||||
return Jeep()
|
||||
|
||||
|
||||
class Node(View, OrderedContainer):
|
||||
|
||||
|
@ -128,6 +134,14 @@ class Node(View, OrderedContainer):
|
|||
parent = zapi.getParent(parent)
|
||||
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):
|
||||
for item in self.values():
|
||||
if INode.providedBy(item) \
|
||||
|
@ -170,6 +184,9 @@ class ViewManager(OrderedContainer):
|
|||
def getViewManager(self):
|
||||
return self
|
||||
|
||||
def getAllParents(self, collectGrants=False):
|
||||
return Jeep()
|
||||
|
||||
|
||||
class TargetRelation(DyadicRelation):
|
||||
""" A relation between a view and its target.
|
||||
|
|
Loading…
Add table
Reference in a new issue