provide attributes and resources via XML-RPC

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1647 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-03-17 16:16:04 +00:00
parent 70810bdb6d
commit 685ac858b0
6 changed files with 95 additions and 19 deletions

View file

@ -70,4 +70,3 @@ class Loops(Folder):
prefix = loopsPrefix + '/' prefix = loopsPrefix + '/'
if uri.startswith(prefix): if uri.startswith(prefix):
return traverse(self, uri[len(prefix):]) return traverse(self, uri[len(prefix):])

View file

@ -122,6 +122,9 @@ class Concept(Contained, Persistent):
self.assignParent(concept, typePred) self.assignParent(concept, typePred)
conceptType = property(getConceptType, setConceptType) conceptType = property(getConceptType, setConceptType)
def getType(self):
return self.conceptType
def getLoopsRoot(self): def getLoopsRoot(self):
return zapi.getParent(self).getLoopsRoot() return zapi.getParent(self).getLoopsRoot()

View file

@ -90,6 +90,10 @@ class IConcept(ILoopsObject, IPotentialTarget):
source="loops.conceptTypeSource", source="loops.conceptTypeSource",
required=False) required=False)
def getType():
""" Return a concept that provides the object's type.
"""
def getChildren(predicates=None): def getChildren(predicates=None):
""" Return a sequence of concepts related to self as child concepts, """ Return a sequence of concepts related to self as child concepts,
optionally restricted to the predicates given. optionally restricted to the predicates given.
@ -223,6 +227,11 @@ class IBaseResource(ILoopsObject):
source="loops.resourceTypeSource", source="loops.resourceTypeSource",
required=False) required=False)
def getType():
""" Return a concept that provides the object's type, i.e. the
resourceType attribute.
"""
data = schema.Bytes( data = schema.Bytes(
title=_(u'Data'), title=_(u'Data'),
description=_(u'Resource raw data'), description=_(u'Resource raw data'),

View file

@ -117,6 +117,9 @@ class Resource(Image, Contained):
self.assignConcept(concept, typePred) self.assignConcept(concept, typePred)
resourceType = property(getResourceType, setResourceType) resourceType = property(getResourceType, setResourceType)
def getType(self):
return self.resourceType
def _setData(self, data): def _setData(self, data):
dataFile = StringIO(data) # let File tear it into pieces dataFile = StringIO(data) # let File tear it into pieces
super(Resource, self)._setData(dataFile) super(Resource, self)._setData(dataFile)

View file

@ -12,6 +12,7 @@ Let's do some basic set up
>>> from zope import component, interface >>> from zope import component, interface
>>> from zope.publisher.browser import TestRequest >>> from zope.publisher.browser import TestRequest
>>> from loops.concept import Concept >>> from loops.concept import Concept
>>> from loops.resource import Resource
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
@ -23,7 +24,8 @@ ZCML setup):
>>> intIds = IntIdsStub() >>> intIds = IntIdsStub()
>>> component.provideUtility(intIds) >>> component.provideUtility(intIds)
>>> from loops.type import ConceptType, TypeConcept >>> from loops.type import LoopsType, ConceptType, TypeConcept
>>> component.provideAdapter(LoopsType)
>>> component.provideAdapter(ConceptType) >>> component.provideAdapter(ConceptType)
>>> component.provideAdapter(TypeConcept) >>> component.provideAdapter(TypeConcept)
@ -31,28 +33,30 @@ ZCML setup):
>>> loopsRoot = site['loops'] = Loops() >>> loopsRoot = site['loops'] = Loops()
>>> from loops.setup import SetupManager >>> from loops.setup import SetupManager
>>> from loops.organize.setup import SetupManager as OrganizeSetupManager
>>> component.provideAdapter(OrganizeSetupManager, name='organize')
>>> setup = SetupManager(loopsRoot) >>> setup = SetupManager(loopsRoot)
>>> concepts, resources, views = setup.setup() >>> concepts, resources, views = setup.setup()
Let's look what setup has provided us with: Let's look what setup has provided us with:
>>> sorted(concepts) >>> sorted(concepts)
[u'domain', u'file', u'hasType', u'note', u'predicate', u'query', [u'domain', u'file', u'hasType', u'note', u'person', u'predicate', u'query',
u'standard', u'textdocument', u'type'] u'standard', u'textdocument', u'type']
Now let's add a few more concepts: Now let's add a few more concepts:
>>> topic = concepts[u'topic'] = Concept(u'Topic') >>> topic = concepts[u'topic'] = Concept(u'Topic')
>>> intIds.register(topic) >>> intIds.register(topic)
8 9
>>> zope = concepts[u'zope'] = Concept(u'Zope') >>> zope = concepts[u'zope'] = Concept(u'Zope')
>>> zope.conceptType = topic >>> zope.conceptType = topic
>>> intIds.register(zope) >>> intIds.register(zope)
9 10
>>> zope3 = concepts[u'zope3'] = Concept(u'Zope 3') >>> zope3 = concepts[u'zope3'] = Concept(u'Zope 3')
>>> zope3.conceptType = topic >>> zope3.conceptType = topic
>>> intIds.register(zope3) >>> intIds.register(zope3)
10 11
Navigation typically starts at a start object, which by default ist the Navigation typically starts at a start object, which by default ist the
domain concept (if present, otherwise the top-level type concept): domain concept (if present, otherwise the top-level type concept):
@ -61,7 +65,8 @@ domain concept (if present, otherwise the top-level type concept):
>>> xrf = LoopsMethods(loopsRoot, TestRequest()) >>> xrf = LoopsMethods(loopsRoot, TestRequest())
>>> startObj = xrf.getStartObject() >>> startObj = xrf.getStartObject()
>>> sorted(startObj.keys()) >>> sorted(startObj.keys())
['children', 'id', 'name', 'parents', 'title', 'type'] ['children', 'description', 'id', 'name', 'options', 'parents', 'resources',
'title', 'type', 'typeInterface', 'viewName']
>>> startObj['id'], startObj['name'], startObj['title'], startObj['type'] >>> startObj['id'], startObj['name'], startObj['title'], startObj['type']
('1', u'domain', u'Domain', '0') ('1', u'domain', u'Domain', '0')
@ -80,7 +85,7 @@ There are a few standard objects we can retrieve directly:
In addition we can get a list of all types and all predicates available: In addition we can get a list of all types and all predicates available:
>>> sorted(t['name'] for t in xrf.getConceptTypes()) >>> sorted(t['name'] for t in xrf.getConceptTypes())
[u'domain', u'file', u'predicate', u'query', u'textdocument', u'type'] [u'domain', u'file', u'person', u'predicate', u'query', u'textdocument', u'type']
>>> sorted(t['name'] for t in xrf.getPredicates()) >>> sorted(t['name'] for t in xrf.getPredicates())
[u'hasType', u'standard'] [u'hasType', u'standard']
@ -101,7 +106,7 @@ 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'domain', u'file', u'predicate', u'query', u'textdocument', u'type'] [u'domain', u'file', u'person', u'predicate', u'query', u'textdocument', u'type']
>>> pa = defaultPred['parents'] >>> pa = defaultPred['parents']
>>> len(pa) >>> len(pa)
@ -119,7 +124,7 @@ 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'domain', u'file', u'predicate', u'query', u'textdocument', u'type'] [u'domain', u'file', u'person', u'predicate', u'query', u'textdocument', u'type']
>>> pa = xrf.getParents('6') >>> pa = xrf.getParents('6')
>>> len(pa) >>> len(pa)
@ -129,6 +134,34 @@ We can also retrieve children and parents explicitely:
>>> sorted(p['name'] for p in pa[0]['objects']) >>> sorted(p['name'] for p in pa[0]['objects'])
[u'predicate'] [u'predicate']
Resources
---------
>>> from loops.resource import TextDocumentAdapter
>>> from loops.interfaces import IResource, ITextDocument
>>> component.provideAdapter(TextDocumentAdapter, (IResource,), ITextDocument)
>>> zope3Id = xrf.getObjectByName('zope3')['id']
>>> td01 = resources['td01'] = Resource(u'Doc1')
>>> td01.resourceType = concepts['textdocument']
>>> zope3.assignResource(td01)
>>> obj = xrf.getObjectById(zope3Id)
>>> obj['resources'][0]['objects'][0]['title']
u'Doc1'
Attributes
----------
>>> from loops.organize.party import Person
>>> from loops.organize.interfaces import IPerson
>>> component.provideAdapter(Person, provides=IPerson)
>>> p01 = concepts['p01'] = Concept(u'John Smith')
>>> p01.conceptType = concepts['person']
>>> john = xrf.getObjectByName('p01')
>>> #john
Updating the concept map Updating the concept map
------------------------ ------------------------
@ -142,7 +175,13 @@ 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')
{'title': u'Zope 2', 'type': '8', 'id': '12', 'name': u'zope2'} {'description': u'', 'title': u'Zope 2', 'type': '9', 'id': '15',
'name': u'zope2'}
Changing the attributes of a concept
------------------------------------
Not implemented yet.
Fin de partie Fin de partie

View file

@ -31,6 +31,7 @@ from zope.traversing.api import getName
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from cybertools.typology.interfaces import IType
from loops.concept import Concept from loops.concept import Concept
from loops.util import getUidForObject, getObjectForUid, toUnicode from loops.util import getUidForObject, getObjectForUid, toUnicode
@ -90,11 +91,19 @@ class LoopsMethods(MethodPublisher):
rels = obj.getParentRelations(preds or None, parent) rels = obj.getParentRelations(preds or None, parent)
return formatRelations(rels, useSecond=False) return formatRelations(rels, useSecond=False)
def getResources(self, id, predicates=[], resource=''):
obj = getObjectForUid(id)
preds = [getObjectForUid(p) for p in predicates]
resource = resource and getObjectForUid(child) or None
rels = obj.getResourceRelations(preds or None, resource)
return formatRelations(rels)
def getObjectWithChildren(self, obj): def getObjectWithChildren(self, obj):
mapping = objectAsDict(obj) mapping = objectAsDict(obj)
mapping['children'] = formatRelations(obj.getChildRelations()) mapping['children'] = formatRelations(obj.getChildRelations())
mapping['parents'] = formatRelations( mapping['parents'] = formatRelations(
obj.getParentRelations(), useSecond=False) obj.getParentRelations(), useSecond=False)
mapping['resources'] = formatRelations(obj.getResourceRelations())
return mapping return mapping
def assignChild(self, objId, predicateId, childId): def assignChild(self, objId, predicateId, childId):
@ -122,8 +131,22 @@ class LoopsMethods(MethodPublisher):
def objectAsDict(obj): def objectAsDict(obj):
mapping = {'id': getUidForObject(obj), 'name': getName(obj), 'title': obj.title, objType = IType(obj)
'type': getUidForObject(obj.conceptType)} mapping = {'id': getUidForObject(obj), 'name': getName(obj),
'title': obj.title, 'description': obj.description,
'type': getUidForObject(objType.typeProvider)}
ti = objType.typeInterface
if ti is not None:
adapter = ti(obj)
for attr in (list(adapter._adapterAttributes) + list(ti)):
if attr not in ('__parent__', 'context', 'id', 'name',
'title', 'description', 'type'):
value = getattr(adapter, attr)
# TODO: better selection and conversion
if value is None or type(value) in (str, unicode):
mapping[attr] = value or u''
elif type(value) is list:
mapping[attr] = ' | '.join(value)
return mapping return mapping
def formatRelations(rels, useSecond=True): def formatRelations(rels, useSecond=True):