Added basic support for media assets; use '.loops' as traversal anchor to the loops root object for referencing resources

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1019 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-01-19 18:02:29 +00:00
parent a7a06201c0
commit 921bbcf92d
7 changed files with 179 additions and 59 deletions

View file

@ -26,14 +26,14 @@ top-level loops container and a concept manager:
>>> from loops.concept import ConceptManager, Concept
>>> loops['concepts'] = ConceptManager()
>>> concepts = loops['concepts']
>>> zope = Concept()
>>> concepts['zope'] = zope
>>> zope.title
>>> cc1 = Concept()
>>> concepts['cc1'] = cc1
>>> cc1.title
u''
>>> zope3 = Concept(u'Zope 3')
>>> concepts['zope3'] = zope3
>>> zope3.title
>>> cc2 = Concept(u'Zope 3')
>>> concepts['cc2'] = cc2
>>> cc2.title
u'Zope 3'
Now we want to relate the second concept to the first one.
@ -48,25 +48,25 @@ testing we use a simple dummy implementation.
Now we can assign the concept c2 to c1 (using the standard ConceptRelation):
>>> zope.assignConcept(zope3)
>>> cc1.assignConcept(cc2)
We can now ask our concepts for their related concepts:
>>> sc1 = zope.getSubConcepts()
>>> sc1 = cc1.getSubConcepts()
>>> len(sc1)
1
>>> zope3 in sc1
>>> cc2 in sc1
True
>>> len(zope.getParentConcepts())
>>> len(cc1.getParentConcepts())
0
>>> pc2 = zope3.getParentConcepts()
>>> pc2 = cc2.getParentConcepts()
>>> len(pc2)
1
>>> zope in pc2
>>> cc1 in pc2
True
>>> len(zope3.getSubConcepts())
>>> len(cc2.getSubConcepts())
0
TODO: Work with views...
@ -81,31 +81,33 @@ We first need a resource manager:
>>> loops['resources'] = ResourceManager()
>>> resources = loops['resources']
A common type of resource is a Document:
A common type of resource is a document:
>>> zope_info = Document(u'Zope Info')
>>> resources['zope_info'] = zope_info
>>> zope_info.title
>>> doc1 = Document(u'Zope Info')
>>> resources['doc1'] = doc1
>>> doc1.title
u'Zope Info'
>>> zope_info.body
>>> doc1.data
u''
>>> zope_info.format
>>> doc1.contentType
u'text/xml'
Another one is a media asset:
We can associate a resource with a concept by assigning it to the concept:
>>> zope.assignResource(zope_info)
>>> res = zope.getResources()
>>> cc1.assignResource(doc1)
>>> res = cc1.getResources()
>>> list(res)
[<loops.resource.Document ...>]
The resource also provides access to the associated concepts (or views, see
below) via the getClients() method:
>>> conc = zope_info.getClients()
>>> conc = doc1.getClients()
>>> len(conc)
1
>>> conc[0] is zope
>>> conc[0] is cc1
True
@ -200,14 +202,14 @@ Targets
We can associate a node with a concept or directly with a resource via the
view class's target attribute:
>>> m111.target = zope_info
>>> m111.target is zope_info
>>> m111.target = cc1
>>> m111.target is cc1
True
>>> m111.target = zope_info
>>> m111.target is zope_info
>>> m111.target = cc1
>>> m111.target is cc1
True
>>> m111.target = zope3
>>> m111.target is zope3
>>> m111.target = cc2
>>> m111.target is cc2
True
Node views

View file

@ -159,7 +159,7 @@
label="Add Document"
name="AddLoopsDocument.html"
schema="loops.interfaces.IDocument"
fields="title body format"
fields="title data contentType"
content_factory="loops.resource.Document"
permission="zope.ManageContent"
/>
@ -176,12 +176,41 @@
label="Edit Document"
name="edit.html"
schema="loops.interfaces.IDocument"
fields="title body format"
fields="title data contentType"
for="loops.interfaces.IDocument"
permission="zope.ManageContent"
menu="zmi_views" title="Edit"
/>
<!-- media asset -->
<addform
label="Add Media Asset"
name="AddLoopsMediaAsset.html"
schema="loops.interfaces.IMediaAsset"
fields="title data contentType"
content_factory="loops.resource.MediaAsset"
permission="zope.ManageContent"
/>
<addMenuItem
class="loops.resource.MediaAsset"
title="Media Asset"
description="A media asset is a binary file, image, video or audio file"
permission="zope.ManageContent"
view="AddLoopsMediaAsset.html"
/>
<editform
label="Edit Media Asset"
name="edit.html"
schema="loops.interfaces.IMediaAsset"
fields="title data contentType"
for="loops.interfaces.IMediaAsset"
permission="zope.ManageContent"
menu="zmi_views" title="Edit"
/>
<!-- view manager -->
<addform

View file

@ -129,6 +129,29 @@
</content>
<interface
interface=".interfaces.IMediaAsset"
type="zope.app.content.interfaces.IContentType" />
<content class=".resource.MediaAsset">
<implements
interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
<factory
id="loops.MediaAsset"
description="Media Asset" />
<require
permission="zope.View"
interface=".interfaces.IMediaAsset" />
<require
permission="zope.ManageContent"
set_schema=".interfaces.IMediaAsset" />
</content>
<!-- view manager and view -->
<interface interface=".interfaces.IViewManager"
@ -188,6 +211,17 @@
<adapter factory="loops.external.NodesImporter" />
<!-- traversal adapter -->
<view factory="loops.view.NodeTraverser"
for="loops.interfaces.INode"
type="zope.publisher.interfaces.http.IHTTPRequest"
provides="zope.publisher.interfaces.IPublishTraverse"
allowed_interface="zope.publisher.interfaces.IPublishTraverse"
permission="zope.Public" />
<!--<adapter factory="loops.view.NodeTraversable" />-->
<!-- Register various browser related components, including all views -->
<include package=".browser" />

View file

@ -27,7 +27,7 @@ from zope.i18nmessageid import MessageFactory
from zope import schema
from zope.app.container.constraints import contains, containers
from zope.app.container.interfaces import IContainer, IOrderedContainer
from zope.app.file.interfaces import IFile as IBaseFile
from zope.app.file.interfaces import IImage as IBaseAsset
from zope.app.folder.interfaces import IFolder
_ = MessageFactory('loops')
@ -102,8 +102,8 @@ class IConceptManagerContained(Interface):
# resource interfaces
class IResource(Interface):
""" A resource is an atomic information element that is usually
available via a concept.
""" A resource is an atomic information element that is made
available via a view or a concept.
"""
title = schema.TextLine(
@ -111,6 +111,13 @@ class IResource(Interface):
description=_(u'Title of the document'),
required=False)
contentType = schema.TextLine(
title=_(u'Content Type'),
description=_(u'Content type (format) of the body field, '
'default is "text/xml"'),
default=_(u'text/xml'),
required=False)
def getClients(relationships=None):
""" Return a sequence of objects that are clients of the resource,
i.e. that have some relation with it.
@ -121,23 +128,22 @@ class IDocument(IResource):
""" A resource containing an editable body.
"""
body = schema.Text(
title=_(u'Body'),
description=_(u'Body of the document'),
required=False)
format = schema.TextLine(
title=_(u'Format'),
description=_(u'Format of the body field, default is "text/xml"'),
default=_(u'text/xml'),
data = schema.Text(
title=_(u'Data'),
description=_(u'Raw body data of the document'),
required=False)
class IFile(IResource, IBaseFile):
class IMediaAsset(IResource, IBaseAsset):
""" A resource containing a (typically binary) file-like content
or an image.
or an image.
"""
data = schema.Bytes(
title=_(u'Data'),
description=_(u'Media asset raw data'),
required=False)
class IResourceManager(IContainer):
""" A manager/container for resources.
@ -173,6 +179,10 @@ class IView(Interface):
class IBaseNode(IOrderedContainer):
""" Common abstract base class for different types of nodes
"""
def getLoopsRoot():
""" Return the loops root object.
"""
class INode(IView, IBaseNode):

View file

@ -25,11 +25,12 @@ $Id$
from zope.app import zapi
from zope.app.container.btree import BTreeContainer
from zope.app.container.contained import Contained
from zope.app.file.image import Image as BaseMediaAsset
from zope.interface import implements
from persistent import Persistent
from cybertools.relation.registry import getRelations
from interfaces import IResource, IDocument
from interfaces import IResource, IDocument, IMediaAsset
from interfaces import IResourceManager, IResourceManagerContained
from interfaces import ILoopsContained
@ -43,27 +44,36 @@ class Resource(Contained, Persistent):
def setTitle(self, title): self._title = title
title = property(getTitle, setTitle)
def __init__(self, title=u''):
self.title = title
_contentType = u'text/xml'
def setContentType(self, contentType): self._contentType = contentType
def getContentType(self): return self._contentType
contentType = property(getContentType, setContentType)
_data = u''
def setData(self, data): self._data = data
def getData(self): return self._data
data = property(getData, setData)
def getClients(self, relationships=None):
rels = getRelations(second=self, relationships=relationships)
return [r.first for r in rels]
def __init__(self, title=u''):
self.title = title
class Document(Resource):
implements(IDocument)
_body = u''
def setBody(self, body): self._body = body
def getBody(self): return self._body
body = property(getBody, setBody)
_format = u'text/xml'
def setFormat(self, format): self._format = format
def getFormat(self): return self._format
format = property(getFormat, setFormat)
class MediaAsset(Resource, BaseMediaAsset):
implements(IMediaAsset)
def __init__(self, title=u''):
super(MediaAsset, self).__init__()
self.title = title
class ResourceManager(BTreeContainer):

View file

@ -10,10 +10,11 @@ from zope.app.intid.interfaces import IIntIds
from interfaces import ILoops
from loops import Loops
from interfaces import IConcept, IConceptManager, IDocument, IResourceManager
from interfaces import IConcept, IConceptManager
from interfaces import IDocument, IMediaAsset, IResourceManager
from interfaces import INode, IViewManager
from loops.concept import Concept, ConceptManager
from loops.resource import Document, ResourceManager
from loops.resource import Document, MediaAsset, ResourceManager
from loops.view import Node, ViewManager
class Test(unittest.TestCase):
@ -28,6 +29,8 @@ class Test(unittest.TestCase):
self.assert_(IConceptManager.providedBy(ConceptManager()))
verifyClass(IDocument, Document)
self.assert_(IDocument.providedBy(Document()))
verifyClass(IMediaAsset, MediaAsset)
self.assert_(IMediaAsset.providedBy(MediaAsset()))
verifyClass(IResourceManager, ResourceManager)
self.assert_(IResourceManager.providedBy(ResourceManager()))
verifyClass(INode, Node)

32
view.py
View file

@ -26,6 +26,9 @@ from zope.app import zapi
from zope.app.container.btree import BTreeContainer
from zope.app.container.contained import Contained
from zope.app.container.ordered import OrderedContainer
from zope.app.container.traversal import ContainerTraverser, ItemTraverser
from zope.app.container.traversal import ContainerTraversable
from zope.component import adapts
from zope.interface import implements
from persistent import Persistent
from cybertools.relation import DyadicRelation
@ -95,6 +98,9 @@ class Node(View, OrderedContainer):
contentType = u'zope.source.rest'
def getLoopsRoot(self):
return zapi.getParent(self).getLoopsRoot()
def getParentNode(self, nodeTypes=None):
parent = zapi.getParent(self)
while INode.providedBy(parent):
@ -134,8 +140,34 @@ class ViewManager(OrderedContainer):
implements(IViewManager, ILoopsContained)
def getLoopsRoot(self):
return zapi.getParent(self)
class TargetRelation(DyadicRelation):
""" A relation between a view and another object.
"""
class NodeTraverser(ItemTraverser):
adapts(INode)
def publishTraverse(self, request, name):
print name
if name == '.loops':
return self.context.getLoopsRoot()
return super(NodeTraverser, self).publishTraverse(request, name)
# class NodeTraversable(ContainerTraversable):
#
# adapts(INode)
#
# def traverse(self, name, furtherPath):
# print name
# if str(name) == '.loops':
# print self._container.getLoopsRoot()
# return self._container.getLoopsRoot()
# return super(NodeTraversable, self).traverse(name, furtherPath)