use typology for type-related stuff on concepts and resources
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1124 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
b39e7548b8
commit
072318ea06
13 changed files with 105 additions and 199 deletions
25
README.txt
25
README.txt
|
@ -108,7 +108,14 @@ a special predicate 'hasType'.
|
||||||
>>> cc1.getConceptType().title
|
>>> cc1.getConceptType().title
|
||||||
u'Topic'
|
u'Topic'
|
||||||
|
|
||||||
We get a list of types using the ConceptTypeSourceList:
|
We get a list of types using the ConceptTypeSourceList.
|
||||||
|
In order for the type machinery to work we first have to provide a
|
||||||
|
type manager.
|
||||||
|
|
||||||
|
>>> from cybertools.typology.interfaces import ITypeManager
|
||||||
|
>>> from loops.interfaces import ILoopsObject
|
||||||
|
>>> from loops.type import LoopsTypeManager
|
||||||
|
>>> ztapi.provideAdapter(ILoopsObject, ITypeManager, LoopsTypeManager)
|
||||||
|
|
||||||
>>> from loops.concept import ConceptTypeSourceList
|
>>> from loops.concept import ConceptTypeSourceList
|
||||||
>>> types = ConceptTypeSourceList(cc1)
|
>>> types = ConceptTypeSourceList(cc1)
|
||||||
|
@ -167,10 +174,11 @@ underlying context object:
|
||||||
>>> sorted(c.title for c in cc1.getChildren())
|
>>> sorted(c.title for c in cc1.getChildren())
|
||||||
[u'loops for Zope 3']
|
[u'loops for Zope 3']
|
||||||
|
|
||||||
We can also create a new concept and assign it:
|
We can also create a new concept and assign it.
|
||||||
|
|
||||||
>>> params = {'action': 'create', 'create.name': 'cc4',
|
>>> params = {'action': 'create', 'create.name': 'cc4',
|
||||||
... 'create.title': u'New concept'}
|
... 'create.title': u'New concept',
|
||||||
|
... 'create.type': '.loops/concepts/topic'}
|
||||||
>>> view = ConceptConfigureView(cc1, TestRequest(**params))
|
>>> view = ConceptConfigureView(cc1, TestRequest(**params))
|
||||||
>>> view.update()
|
>>> view.update()
|
||||||
True
|
True
|
||||||
|
@ -178,7 +186,7 @@ We can also create a new concept and assign it:
|
||||||
[u'New concept', u'loops for Zope 3']
|
[u'New concept', u'loops for Zope 3']
|
||||||
|
|
||||||
The concept configuration view provides methods for displaying concept
|
The concept configuration view provides methods for displaying concept
|
||||||
types and predicates:
|
types and predicates.
|
||||||
|
|
||||||
>>> from zope.publisher.interfaces.browser import IBrowserRequest
|
>>> from zope.publisher.interfaces.browser import IBrowserRequest
|
||||||
>>> from loops.browser.common import LoopsTerms
|
>>> from loops.browser.common import LoopsTerms
|
||||||
|
@ -206,9 +214,6 @@ Index attributes adapter
|
||||||
>>> idx.title()
|
>>> idx.title()
|
||||||
u'cc2 Zope 3'
|
u'cc2 Zope 3'
|
||||||
|
|
||||||
>>> idx.type()
|
|
||||||
'loops:concept:unknown'
|
|
||||||
|
|
||||||
|
|
||||||
Resources and what they have to do with Concepts
|
Resources and what they have to do with Concepts
|
||||||
================================================
|
================================================
|
||||||
|
@ -307,9 +312,6 @@ Index attributes adapter
|
||||||
>>> idx.title()
|
>>> idx.title()
|
||||||
u'doc1 Zope Info'
|
u'doc1 Zope Info'
|
||||||
|
|
||||||
>>> idx.type()
|
|
||||||
'loops:resource:Document'
|
|
||||||
|
|
||||||
|
|
||||||
Views/Nodes: Menus, Menu Items, Listings, Pages, etc
|
Views/Nodes: Menus, Menu Items, Listings, Pages, etc
|
||||||
====================================================
|
====================================================
|
||||||
|
@ -463,7 +465,8 @@ to the node's target: associate an existing one or create a new one.
|
||||||
... 'create.type': 'loops.resource.MediaAsset',}
|
... 'create.type': 'loops.resource.MediaAsset',}
|
||||||
>>> view = ConfigureView(m111, TestRequest(form = form))
|
>>> view = ConfigureView(m111, TestRequest(form = form))
|
||||||
>>> sorted((t.token, t.title) for t in view.targetTypes())
|
>>> sorted((t.token, t.title) for t in view.targetTypes())
|
||||||
[('loops.concept.Concept', u'Concept'),
|
[('.loops/concepts/topic', u'Topic'), ('.loops/concepts/type', u'Type'),
|
||||||
|
('.loops/concepts/unknown', u'Unknown Type'),
|
||||||
('loops.resource.Document', u'Document'),
|
('loops.resource.Document', u'Document'),
|
||||||
('loops.resource.MediaAsset', u'Media Asset')]
|
('loops.resource.MediaAsset', u'Media Asset')]
|
||||||
>>> view.update()
|
>>> view.update()
|
||||||
|
|
|
@ -29,6 +29,7 @@ from zope.cachedescriptors.property import Lazy
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
|
from cybertools.typology.interfaces import IType
|
||||||
from loops import util
|
from loops import util
|
||||||
from loops.target import getTargetTypes
|
from loops.target import getTargetTypes
|
||||||
|
|
||||||
|
@ -69,14 +70,16 @@ class BaseView(object):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def typeTitle(self):
|
def typeTitle(self):
|
||||||
voc = util.KeywordVocabulary(getTargetTypes())
|
type = IType(self.context)
|
||||||
token = '.'.join((self.context.__module__,
|
return type is not None and type.title or None
|
||||||
self.context.__class__.__name__))
|
|
||||||
term = voc.getTermByToken(token)
|
|
||||||
return term.title
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def typeUrl(self):
|
def typeUrl(self):
|
||||||
|
type = IType(self.context)
|
||||||
|
if type is not None:
|
||||||
|
provider = type.typeProvider
|
||||||
|
if provider is not None:
|
||||||
|
return zapi.absoluteURL(provider, self.request)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def viewIterator(self, objs):
|
def viewIterator(self, objs):
|
||||||
|
|
|
@ -38,9 +38,9 @@ from zope.publisher.interfaces.browser import IBrowserRequest
|
||||||
from zope import schema
|
from zope import schema
|
||||||
from zope.schema.interfaces import IIterableSource
|
from zope.schema.interfaces import IIterableSource
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
from cybertools.typology.interfaces import ITypeManager
|
||||||
from loops.interfaces import IConcept
|
from loops.interfaces import IConcept
|
||||||
from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList
|
from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList
|
||||||
from loops.resource import getResourceTypes, getResourceTypesForSearch
|
|
||||||
from loops.target import getTargetTypes
|
from loops.target import getTargetTypes
|
||||||
from loops.browser.common import BaseView, LoopsTerms
|
from loops.browser.common import BaseView, LoopsTerms
|
||||||
from loops import util
|
from loops import util
|
||||||
|
@ -64,7 +64,7 @@ class ConceptView(BaseView):
|
||||||
|
|
||||||
def resources(self):
|
def resources(self):
|
||||||
for r in self.context.getResourceRelations():
|
for r in self.context.getResourceRelations():
|
||||||
yield ConceptResourceRelationView(r, self.request, contextIsSecond=True)
|
yield ConceptRelationView(r, self.request, contextIsSecond=True)
|
||||||
|
|
||||||
|
|
||||||
class ConceptConfigureView(ConceptView):
|
class ConceptConfigureView(ConceptView):
|
||||||
|
@ -121,18 +121,14 @@ class ConceptConfigureView(ConceptView):
|
||||||
if not name:
|
if not name:
|
||||||
raise(BadRequest, 'Empty name.')
|
raise(BadRequest, 'Empty name.')
|
||||||
title = request.get('create.title', u'')
|
title = request.get('create.title', u'')
|
||||||
conceptType = request.get('create.type')
|
token = self.request.get('create.type')
|
||||||
if conceptType and conceptType.startswith('loops.resource.'):
|
type = ITypeManager(self.context).getType(token)
|
||||||
factory = resolve(conceptType)
|
factory = type.factory
|
||||||
concept = factory(title)
|
container = type.defaultContainer
|
||||||
container = self.loopsRoot.getResourceManager()
|
concept = factory(title)
|
||||||
else:
|
|
||||||
concept = Concept(title)
|
|
||||||
container = self.loopsRoot.getConceptManager()
|
|
||||||
container[name] = concept
|
container[name] = concept
|
||||||
if conceptType:
|
if IConcept.providedBy(concept):
|
||||||
ctype = self.loopsRoot.loopsTraverse(conceptType)
|
concept.conceptType = type.typeProvider
|
||||||
concept.conceptType = ctype
|
|
||||||
notify(ObjectCreatedEvent(removeSecurityProxy(concept)))
|
notify(ObjectCreatedEvent(removeSecurityProxy(concept)))
|
||||||
assignAs = self.request.get('assignAs', 'child')
|
assignAs = self.request.get('assignAs', 'child')
|
||||||
predicate = request.get('create.predicate') or None
|
predicate = request.get('create.predicate') or None
|
||||||
|
@ -176,44 +172,28 @@ class ConceptConfigureView(ConceptView):
|
||||||
result = [r for r in result if r.conceptType is None]
|
result = [r for r in result if r.conceptType is None]
|
||||||
return self.viewIterator(result)
|
return self.viewIterator(result)
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def typeTitle(self):
|
|
||||||
return self.context.conceptType.title
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def typeUrl(self):
|
|
||||||
return zapi.absoluteURL(self.context.conceptType, self.request)
|
|
||||||
|
|
||||||
def viewIterator(self, objs):
|
def viewIterator(self, objs):
|
||||||
request = self.request
|
request = self.request
|
||||||
for o in objs:
|
for o in objs:
|
||||||
if IConcept.providedBy(o):
|
|
||||||
yield ConceptConfigureView(o, request)
|
|
||||||
else:
|
|
||||||
yield BaseView(o, request)
|
yield BaseView(o, request)
|
||||||
|
|
||||||
def conceptTypes(self):
|
def conceptTypes(self):
|
||||||
types = ConceptTypeSourceList(self.context)
|
return util.KeywordVocabulary([(t.token, t.title)
|
||||||
terms = zapi.getMultiAdapter((types, self.request), ITerms)
|
for t in ITypeManager(self.context).listTypes(('concept',))])
|
||||||
for type in types:
|
|
||||||
yield terms.getTerm(type)
|
|
||||||
|
|
||||||
def conceptTypesForSearch(self):
|
def conceptTypesForSearch(self):
|
||||||
types = ConceptTypeSourceList(self.context)
|
general = [('loops:concept:*', 'Any'),]
|
||||||
typesItems = [(':'.join(('loops:concept',
|
return util.KeywordVocabulary(general + [(t.tokenForSearch, t.title)
|
||||||
self.getConceptTypeTokenForSearch(t))), t.title)
|
for t in ITypeManager(self.context).listTypes(('concept',))])
|
||||||
for t in types]
|
|
||||||
return util.KeywordVocabulary(typesItems)
|
|
||||||
|
|
||||||
def getConceptTypeTokenForSearch(self, ct):
|
|
||||||
return ct is None and 'unknown' or zapi.getName(ct)
|
|
||||||
|
|
||||||
def resourceTypes(self):
|
def resourceTypes(self):
|
||||||
return util.KeywordVocabulary(getResourceTypes())
|
return util.KeywordVocabulary([(t.token, t.title)
|
||||||
|
for t in ITypeManager(self.context).listTypes(('resource',))])
|
||||||
|
|
||||||
def resourceTypesForSearch(self):
|
def resourceTypesForSearch(self):
|
||||||
return util.KeywordVocabulary(getResourceTypesForSearch())
|
general = [('loops:resource:*', 'Any'),]
|
||||||
|
return util.KeywordVocabulary(general + [(t.tokenForSearch, t.title)
|
||||||
|
for t in ITypeManager(self.context).listTypes(('resource',))])
|
||||||
|
|
||||||
def predicates(self):
|
def predicates(self):
|
||||||
preds = PredicateSourceList(self.context)
|
preds = PredicateSourceList(self.context)
|
||||||
|
@ -222,7 +202,7 @@ class ConceptConfigureView(ConceptView):
|
||||||
yield terms.getTerm(pred)
|
yield terms.getTerm(pred)
|
||||||
|
|
||||||
|
|
||||||
class ConceptRelationView(object):
|
class ConceptRelationView(BaseView):
|
||||||
|
|
||||||
def __init__(self, relation, request, contextIsSecond=False):
|
def __init__(self, relation, request, contextIsSecond=False):
|
||||||
if contextIsSecond:
|
if contextIsSecond:
|
||||||
|
@ -234,35 +214,11 @@ class ConceptRelationView(object):
|
||||||
self.predicate = relation.predicate
|
self.predicate = relation.predicate
|
||||||
self.request = request
|
self.request = request
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def loopsRoot(self):
|
|
||||||
return self.context.getLoopsRoot()
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def url(self):
|
|
||||||
return zapi.absoluteURL(self.context, self.request)
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def title(self):
|
|
||||||
return self.context.title
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def token(self):
|
def token(self):
|
||||||
return ':'.join((self.loopsRoot.getLoopsUri(self.context),
|
return ':'.join((self.loopsRoot.getLoopsUri(self.context),
|
||||||
self.loopsRoot.getLoopsUri(self.predicate)))
|
self.loopsRoot.getLoopsUri(self.predicate)))
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def conceptType(self):
|
|
||||||
return self.context.conceptType
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def typeTitle(self):
|
|
||||||
return self.conceptType.title
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def typeUrl(self):
|
|
||||||
return zapi.absoluteURL(self.conceptType, self.request)
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def predicateTitle(self):
|
def predicateTitle(self):
|
||||||
return self.predicate.title
|
return self.predicate.title
|
||||||
|
@ -271,23 +227,3 @@ class ConceptRelationView(object):
|
||||||
def predicateUrl(self):
|
def predicateUrl(self):
|
||||||
return zapi.absoluteURL(self.predicate, self.request)
|
return zapi.absoluteURL(self.predicate, self.request)
|
||||||
|
|
||||||
|
|
||||||
class ConceptResourceRelationView(ConceptRelationView):
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def conceptType(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def typeTitle(self):
|
|
||||||
voc = util.KeywordVocabulary(getTargetTypes())
|
|
||||||
token = '.'.join((self.context.__module__,
|
|
||||||
self.context.__class__.__name__))
|
|
||||||
term = voc.getTermByToken(token)
|
|
||||||
return term.title
|
|
||||||
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def typeUrl(self):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,6 @@
|
||||||
<metal:search fill-slot="topActions">
|
<metal:search fill-slot="topActions">
|
||||||
<metal:block use-macro="views/relation_macros/search">
|
<metal:block use-macro="views/relation_macros/search">
|
||||||
<select name="searchType" metal:fill-slot="types">
|
<select name="searchType" metal:fill-slot="types">
|
||||||
<option value="loops:resource:*"
|
|
||||||
tal:attributes="selected python:
|
|
||||||
searchType == 'loops:resource:*'">Any</option>
|
|
||||||
<tal:types repeat="type view/resourceTypesForSearch">
|
<tal:types repeat="type view/resourceTypesForSearch">
|
||||||
<option value="loops:resource:Document"
|
<option value="loops:resource:Document"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
|
|
|
@ -462,10 +462,6 @@
|
||||||
for="loops.concept.PredicateSourceList
|
for="loops.concept.PredicateSourceList
|
||||||
zope.publisher.interfaces.browser.IBrowserRequest" />
|
zope.publisher.interfaces.browser.IBrowserRequest" />
|
||||||
|
|
||||||
<zope:adapter factory="loops.browser.common.LoopsTerms"
|
|
||||||
for="loops.target.TargetSourceList
|
|
||||||
zope.publisher.interfaces.browser.IBrowserRequest" />
|
|
||||||
|
|
||||||
<zope:view factory="loops.view.NodeTraverser"
|
<zope:view factory="loops.view.NodeTraverser"
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
type="zope.publisher.interfaces.browser.IBrowserRequest"
|
type="zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
|
|
|
@ -35,6 +35,7 @@ from zope.proxy import removeAllProxies
|
||||||
from zope.security import canAccess, canWrite
|
from zope.security import canAccess, canWrite
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
|
from cybertools.typology.interfaces import ITypeManager
|
||||||
from loops.interfaces import IConcept, IDocument, IMediaAsset
|
from loops.interfaces import IConcept, IDocument, IMediaAsset
|
||||||
from loops.resource import MediaAsset
|
from loops.resource import MediaAsset
|
||||||
from loops.target import getTargetTypes, getTargetTypesForSearch
|
from loops.target import getTargetTypes, getTargetTypesForSearch
|
||||||
|
@ -183,13 +184,10 @@ class ConfigureView(BaseView):
|
||||||
def createAndAssign(self):
|
def createAndAssign(self):
|
||||||
form = self.request.form
|
form = self.request.form
|
||||||
root = self.loopsRoot
|
root = self.loopsRoot
|
||||||
type = self.request.form.get('create.type',
|
token = form.get('create.type', 'loops.resource.MediaAsset')
|
||||||
'loops.resource.MediaAsset')
|
type = ITypeManager(self.context).getType(token)
|
||||||
factory = resolve(type)
|
factory = type.factory
|
||||||
if '.resource.' in type:
|
container = type.defaultContainer
|
||||||
container = root.getResourceManager()
|
|
||||||
else:
|
|
||||||
container = root.getConceptManager()
|
|
||||||
name = form.get('create.name', '')
|
name = form.get('create.name', '')
|
||||||
if not name:
|
if not name:
|
||||||
viewManagerPath = zapi.getPath(root.getViewManager())
|
viewManagerPath = zapi.getPath(root.getViewManager())
|
||||||
|
@ -204,15 +202,21 @@ class ConfigureView(BaseView):
|
||||||
container[name] = removeSecurityProxy(factory())
|
container[name] = removeSecurityProxy(factory())
|
||||||
target = container[name]
|
target = container[name]
|
||||||
target.title = form.get('create.title', u'')
|
target.title = form.get('create.title', u'')
|
||||||
|
if IConcept.providedBy(target):
|
||||||
|
target.conceptType = type.typeProvider
|
||||||
notify(ObjectCreatedEvent(target))
|
notify(ObjectCreatedEvent(target))
|
||||||
self.context.target = target
|
self.context.target = target
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def targetTypes(self):
|
def targetTypes(self):
|
||||||
return util.KeywordVocabulary(getTargetTypes())
|
return util.KeywordVocabulary([(t.token, t.title)
|
||||||
|
for t in ITypeManager(self.context).types])
|
||||||
|
|
||||||
def targetTypesForSearch(self):
|
def targetTypesForSearch(self):
|
||||||
return util.KeywordVocabulary(getTargetTypesForSearch())
|
general = [('loops:*', 'Any'), ('loops:concept:*', 'Any Concept'),
|
||||||
|
('loops:resource:*', 'Any Resource'),]
|
||||||
|
return util.KeywordVocabulary(general + [(t.tokenForSearch, t.title)
|
||||||
|
for t in ITypeManager(self.context).types])
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def search(self):
|
def search(self):
|
||||||
|
@ -244,8 +248,9 @@ class ConfigureView(BaseView):
|
||||||
for o in objs:
|
for o in objs:
|
||||||
if o == self.context.target:
|
if o == self.context.target:
|
||||||
continue
|
continue
|
||||||
if IConcept.providedBy(o):
|
yield BaseView(o, request)
|
||||||
yield ConceptView(o, request)
|
#if IConcept.providedBy(o):
|
||||||
else:
|
# yield ConceptView(o, request)
|
||||||
yield BaseView(o, request)
|
#else:
|
||||||
|
# yield BaseView(o, request)
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,6 @@
|
||||||
tal:attributes="value type/token"
|
tal:attributes="value type/token"
|
||||||
tal:content="type/title">Topic</option>
|
tal:content="type/title">Topic</option>
|
||||||
</tal:types>
|
</tal:types>
|
||||||
<option>None</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div><br />
|
</div><br />
|
||||||
<div class="formControls">
|
<div class="formControls">
|
||||||
|
@ -135,9 +134,6 @@
|
||||||
tal:attributes="value searchTerm" />
|
tal:attributes="value searchTerm" />
|
||||||
<span i18n:translate="">Type</span>
|
<span i18n:translate="">Type</span>
|
||||||
<select name="searchType" metal:define-slot="types">
|
<select name="searchType" metal:define-slot="types">
|
||||||
<option value="loops:concept:*"
|
|
||||||
tal:attributes="selected python:
|
|
||||||
searchType == 'loops:concept:*'">Any</option>
|
|
||||||
<tal:types repeat="type view/conceptTypesForSearch">
|
<tal:types repeat="type view/conceptTypesForSearch">
|
||||||
<option value=".loops/concepts/topic"
|
<option value=".loops/concepts/topic"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
|
|
|
@ -124,7 +124,6 @@
|
||||||
tal:attributes="value searchTerm" />
|
tal:attributes="value searchTerm" />
|
||||||
<span i18n:translate="">Type</span>
|
<span i18n:translate="">Type</span>
|
||||||
<select name="searchType">
|
<select name="searchType">
|
||||||
<option>Any</option>
|
|
||||||
<tal:types repeat="type view/targetTypesForSearch">
|
<tal:types repeat="type view/targetTypesForSearch">
|
||||||
<option value=".loops/concepts/topic"
|
<option value=".loops/concepts/topic"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
|
|
24
concept.py
24
concept.py
|
@ -36,6 +36,7 @@ from cybertools.relation import DyadicRelation
|
||||||
from cybertools.relation.registry import getRelations
|
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 ITypeManager
|
||||||
|
|
||||||
from interfaces import IConcept, IConceptRelation, IConceptView
|
from interfaces import IConcept, IConceptRelation, IConceptView
|
||||||
from interfaces import IConceptManager, IConceptManagerContained
|
from interfaces import IConceptManager, IConceptManagerContained
|
||||||
|
@ -237,27 +238,14 @@ class ConceptTypeSourceList(object):
|
||||||
|
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
self.context = context
|
self.context = context
|
||||||
#self.context = removeSecurityProxy(context)
|
|
||||||
root = self.context.getLoopsRoot()
|
|
||||||
self.concepts = root.getConceptManager()
|
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self.conceptTypes)
|
return iter(self.conceptTypes)
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def conceptTypes(self):
|
def conceptTypes(self):
|
||||||
result = []
|
types = ITypeManager(self.context).listTypes(include=('concept',))
|
||||||
cm = self.concepts
|
return [t.typeProvider for t in types]
|
||||||
typeObject = cm.getTypeConcept()
|
|
||||||
unknownType = cm.get('unknown') # does this make sense?
|
|
||||||
if typeObject is not None:
|
|
||||||
types = typeObject.getChildren([cm.getTypePredicate()])
|
|
||||||
if typeObject not in types:
|
|
||||||
result.append(typeObject)
|
|
||||||
if unknownType is not None and unknownType not in types:
|
|
||||||
result.append(unknownType)
|
|
||||||
result.extend(types)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.conceptTypes)
|
return len(self.conceptTypes)
|
||||||
|
@ -308,9 +296,3 @@ class IndexAttributes(object):
|
||||||
def title(self):
|
def title(self):
|
||||||
return self.text()
|
return self.text()
|
||||||
|
|
||||||
def type(self):
|
|
||||||
context = self.context
|
|
||||||
conceptType = context.conceptType
|
|
||||||
typeName = conceptType is None and 'unknown' or zapi.getName(conceptType)
|
|
||||||
return ':'.join(('loops:concept', typeName,))
|
|
||||||
|
|
||||||
|
|
|
@ -264,10 +264,10 @@
|
||||||
name="loops.PredicateSource"
|
name="loops.PredicateSource"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<vocabulary
|
<!--<vocabulary
|
||||||
factory="loops.target.TargetSourceList"
|
factory="loops.target.TargetSourceList"
|
||||||
name="loops.targetSource"
|
name="loops.targetSource"
|
||||||
/>
|
/>-->
|
||||||
|
|
||||||
<!-- Register various browser related components, including all views -->
|
<!-- Register various browser related components, including all views -->
|
||||||
<include package=".browser" />
|
<include package=".browser" />
|
||||||
|
|
27
helpers.txt
27
helpers.txt
|
@ -130,6 +130,10 @@ lazy properties, one should always get a new adapter:
|
||||||
True
|
True
|
||||||
>>> topic_type.qualifiers
|
>>> topic_type.qualifiers
|
||||||
('concept',)
|
('concept',)
|
||||||
|
>>> topic_type.defaultContainer
|
||||||
|
<loops.concept.ConceptManager object ...>
|
||||||
|
>>> topic_type.factory
|
||||||
|
<class 'loops.concept.Concept'>
|
||||||
|
|
||||||
Now let's have a look at resources.
|
Now let's have a look at resources.
|
||||||
|
|
||||||
|
@ -141,11 +145,15 @@ Now let's have a look at resources.
|
||||||
>>> doc1_type.title
|
>>> doc1_type.title
|
||||||
u'Document'
|
u'Document'
|
||||||
>>> doc1_type.token
|
>>> doc1_type.token
|
||||||
'.loops/resources/document'
|
'loops.resource.Document'
|
||||||
>>> doc1_type.tokenForSearch
|
>>> doc1_type.tokenForSearch
|
||||||
'loops:resource:document'
|
'loops:resource:document'
|
||||||
>>> doc1_type.qualifiers
|
>>> doc1_type.qualifiers
|
||||||
('resource',)
|
('resource',)
|
||||||
|
>>> doc1_type.defaultContainer
|
||||||
|
<loops.resource.ResourceManager object ...>
|
||||||
|
>>> doc1_type.factory
|
||||||
|
<class 'loops.resource.Document'>
|
||||||
|
|
||||||
>>> img1_type = IType(img1)
|
>>> img1_type = IType(img1)
|
||||||
>>> img1_type.title
|
>>> img1_type.title
|
||||||
|
@ -167,7 +175,7 @@ get a type manager from all loops objects, always with the same context:
|
||||||
>>> types = typeManager.types
|
>>> types = typeManager.types
|
||||||
>>> sorted(t.token for t in types)
|
>>> sorted(t.token for t in types)
|
||||||
['.loops/concepts/topic', '.loops/concepts/type',
|
['.loops/concepts/topic', '.loops/concepts/type',
|
||||||
'.loops/resources/document', '.loops/resources/mediaasset']
|
'loops.resource.Document', 'loops.resource.MediaAsset']
|
||||||
|
|
||||||
>>> typeManager.getType('.loops/concepts/topic') == cc1_type
|
>>> typeManager.getType('.loops/concepts/topic') == cc1_type
|
||||||
True
|
True
|
||||||
|
@ -180,18 +188,5 @@ condition:
|
||||||
['.loops/concepts/topic', '.loops/concepts/type']
|
['.loops/concepts/topic', '.loops/concepts/type']
|
||||||
>>> types = typeManager.listTypes(exclude=('concept',))
|
>>> types = typeManager.listTypes(exclude=('concept',))
|
||||||
>>> sorted(t.token for t in types)
|
>>> sorted(t.token for t in types)
|
||||||
['.loops/resources/document', '.loops/resources/mediaasset']
|
['loops.resource.Document', 'loops.resource.MediaAsset']
|
||||||
|
|
||||||
Index attributes adapter
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
>>> from loops.concept import IndexAttributes
|
|
||||||
>>> idx = IndexAttributes(cc2)
|
|
||||||
>>> idx.type()
|
|
||||||
'loops:concept:unknown'
|
|
||||||
|
|
||||||
>>> from loops.resource import IndexAttributes
|
|
||||||
>>> idx = IndexAttributes(doc1)
|
|
||||||
>>> idx.type()
|
|
||||||
'loops:resource:Document'
|
|
||||||
|
|
||||||
|
|
16
resource.py
16
resource.py
|
@ -161,10 +161,6 @@ class IndexAttributes(object):
|
||||||
context = self.context
|
context = self.context
|
||||||
return ' '.join((zapi.getName(context), context.title,)).strip()
|
return ' '.join((zapi.getName(context), context.title,)).strip()
|
||||||
|
|
||||||
def type(self):
|
|
||||||
context = self.context
|
|
||||||
return ':'.join(('loops:resource', context.__class__.__name__))
|
|
||||||
|
|
||||||
|
|
||||||
class IndexableResource(object):
|
class IndexableResource(object):
|
||||||
|
|
||||||
|
@ -179,16 +175,4 @@ class IndexableResource(object):
|
||||||
icc = IndexContentCollector()
|
icc = IndexContentCollector()
|
||||||
icc.addBinary(fields[0], context.data, context.contentType, language='de')
|
icc.addBinary(fields[0], context.data, context.contentType, language='de')
|
||||||
return icc
|
return icc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getResourceTypes():
|
|
||||||
return (('loops.resource.Document', _(u'Document')),
|
|
||||||
('loops.resource.MediaAsset', _(u'Media Asset')),
|
|
||||||
)
|
|
||||||
|
|
||||||
def getResourceTypesForSearch():
|
|
||||||
return (('loops:resource:Document', _(u'Document')),
|
|
||||||
('loops:resource:MediaAsset', _(u'Media Asset')),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
48
type.py
48
type.py
|
@ -25,8 +25,10 @@ $Id$
|
||||||
from zope.app import zapi
|
from zope.app import zapi
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
from zope.dottedname.resolve import resolve
|
||||||
from cybertools.typology.type import BaseType, TypeManager
|
from cybertools.typology.type import BaseType, TypeManager
|
||||||
from loops.interfaces import ILoopsObject, IConcept, IResource
|
from loops.interfaces import ILoopsObject, IConcept, IResource
|
||||||
|
from loops.concept import Concept
|
||||||
from loops.resource import Document, MediaAsset
|
from loops.resource import Document, MediaAsset
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,14 +55,6 @@ class LoopsType(BaseType):
|
||||||
return self.context.getLoopsRoot()
|
return self.context.getLoopsRoot()
|
||||||
|
|
||||||
|
|
||||||
class LoopsTypeInfo(LoopsType):
|
|
||||||
""" A common class the instances of which are used as a generic type info.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, typeProvider):
|
|
||||||
self.typeProvider = self.context = typeProvider
|
|
||||||
|
|
||||||
|
|
||||||
class ConceptType(LoopsType):
|
class ConceptType(LoopsType):
|
||||||
""" The type adapter for concept objects.
|
""" The type adapter for concept objects.
|
||||||
"""
|
"""
|
||||||
|
@ -68,11 +62,16 @@ class ConceptType(LoopsType):
|
||||||
adapts(IConcept)
|
adapts(IConcept)
|
||||||
|
|
||||||
qualifiers = ('concept',)
|
qualifiers = ('concept',)
|
||||||
|
factory = Concept
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def typeProvider(self):
|
def typeProvider(self):
|
||||||
return self.context.conceptType
|
return self.context.conceptType
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def defaultContainer(self):
|
||||||
|
return self.root.getConceptManager()
|
||||||
|
|
||||||
|
|
||||||
class ConceptTypeInfo(ConceptType):
|
class ConceptTypeInfo(ConceptType):
|
||||||
|
|
||||||
|
@ -95,8 +94,9 @@ class ResourceType(LoopsType):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def token(self):
|
def token(self):
|
||||||
cn = self.className
|
return '.'.join((self.factory.__module__, self.className))
|
||||||
return '/'.join(('.loops/resources', cn.lower(),))
|
#cn = self.className
|
||||||
|
#return '/'.join(('.loops/resources', cn.lower(),))
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def tokenForSearch(self):
|
def tokenForSearch(self):
|
||||||
|
@ -104,19 +104,23 @@ class ResourceType(LoopsType):
|
||||||
return ':'.join(('loops:resource', cn.lower(),))
|
return ':'.join(('loops:resource', cn.lower(),))
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def className(self):
|
def defaultContainer(self):
|
||||||
return self.context.__class__.__name__
|
return self.root.getResourceManager()
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def factory(self):
|
||||||
|
return self.context.__class__
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def className(self):
|
||||||
|
return self.factory.__name__
|
||||||
|
|
||||||
|
|
||||||
class ResourceTypeInfo(ResourceType):
|
class ResourceTypeInfo(ResourceType):
|
||||||
|
|
||||||
def __init__(self, cls):
|
def __init__(self, context, factory):
|
||||||
self.cls = cls
|
self.context = context
|
||||||
|
self.factory = factory
|
||||||
@Lazy
|
|
||||||
def className(self):
|
|
||||||
return self.cls.__name__
|
|
||||||
|
|
||||||
|
|
||||||
class LoopsTypeManager(TypeManager):
|
class LoopsTypeManager(TypeManager):
|
||||||
|
@ -126,6 +130,11 @@ class LoopsTypeManager(TypeManager):
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
self.context = context.getLoopsRoot()
|
self.context = context.getLoopsRoot()
|
||||||
|
|
||||||
|
def getType(self, token):
|
||||||
|
if token.startswith('.loops'):
|
||||||
|
return ConceptTypeInfo(self.context.loopsTraverse(token))
|
||||||
|
return ResourceTypeInfo(self.context, resolve(token))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def types(self):
|
def types(self):
|
||||||
return self.conceptTypes() + self.resourceTypes()
|
return self.conceptTypes() + self.resourceTypes()
|
||||||
|
@ -150,4 +159,5 @@ class LoopsTypeManager(TypeManager):
|
||||||
return tuple([ConceptTypeInfo(c) for c in result])
|
return tuple([ConceptTypeInfo(c) for c in result])
|
||||||
|
|
||||||
def resourceTypes(self):
|
def resourceTypes(self):
|
||||||
return tuple([ResourceTypeInfo(cls) for cls in (Document, MediaAsset)])
|
return tuple([ResourceTypeInfo(self.context, cls)
|
||||||
|
for cls in (Document, MediaAsset)])
|
||||||
|
|
Loading…
Add table
Reference in a new issue