more clean-up of resource types - old MediaAsset objects are now mapped to Resource objects with resourceType 'file'
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1291 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
e860cf5a07
commit
acc878a63d
6 changed files with 54 additions and 59 deletions
22
README.txt
22
README.txt
|
@ -8,7 +8,7 @@ The loops platform is built up of three parts:
|
||||||
|
|
||||||
(1) concepts: simple interconnected objects usually representing
|
(1) concepts: simple interconnected objects usually representing
|
||||||
meta-information
|
meta-information
|
||||||
(2) resources: (possibly large) atomic objects like documents and media assets
|
(2) resources: (possibly large) atomic objects like documents and files
|
||||||
(3) views: objects (usually hierarchically organized nodes) providing
|
(3) views: objects (usually hierarchically organized nodes) providing
|
||||||
access to and presenting concepts or resources
|
access to and presenting concepts or resources
|
||||||
|
|
||||||
|
@ -31,8 +31,7 @@ Let's start with creating a few example concepts, putting them in a
|
||||||
top-level loops container and a concept manager:
|
top-level loops container and a concept manager:
|
||||||
|
|
||||||
>>> from loops import Loops
|
>>> from loops import Loops
|
||||||
>>> site['loops'] = Loops()
|
>>> loopsRoot = site['loops'] = Loops()
|
||||||
>>> loopsRoot = site['loops']
|
|
||||||
|
|
||||||
>>> from loops.concept import ConceptManager, Concept
|
>>> from loops.concept import ConceptManager, Concept
|
||||||
>>> loopsRoot['concepts'] = ConceptManager()
|
>>> loopsRoot['concepts'] = ConceptManager()
|
||||||
|
@ -230,11 +229,11 @@ Index attributes adapter
|
||||||
Resources and what they have to do with Concepts
|
Resources and what they have to do with Concepts
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
>>> from loops.interfaces import IResource, IDocument, IMediaAsset
|
>>> from loops.interfaces import IResource, IDocument
|
||||||
|
|
||||||
We first need a resource manager:
|
We first need a resource manager:
|
||||||
|
|
||||||
>>> from loops.resource import ResourceManager
|
>>> from loops.resource import ResourceManager, Resource
|
||||||
>>> loopsRoot['resources'] = ResourceManager()
|
>>> loopsRoot['resources'] = ResourceManager()
|
||||||
>>> resources = loopsRoot['resources']
|
>>> resources = loopsRoot['resources']
|
||||||
|
|
||||||
|
@ -251,11 +250,11 @@ A common type of resource is a document:
|
||||||
>>> doc1.contentType
|
>>> doc1.contentType
|
||||||
u''
|
u''
|
||||||
|
|
||||||
Another one is a media asset:
|
We can also directly use Resource objects; these behave like files.
|
||||||
|
In fact, by using resource types we can explicitly assign a resource
|
||||||
|
the 'file' type, but we will use this feature later:
|
||||||
|
|
||||||
>>> from loops.interfaces import IMediaAsset
|
>>> img = Resource(u'A png Image')
|
||||||
>>> from loops.resource import MediaAsset
|
|
||||||
>>> img = MediaAsset(u'A png Image')
|
|
||||||
|
|
||||||
For testing we use some simple files from the tests directory:
|
For testing we use some simple files from the tests directory:
|
||||||
|
|
||||||
|
@ -270,7 +269,7 @@ For testing we use some simple files from the tests directory:
|
||||||
>>> img.contentType
|
>>> img.contentType
|
||||||
'image/png'
|
'image/png'
|
||||||
|
|
||||||
>>> pdf = MediaAsset(u'A pdf File')
|
>>> pdf = Resource(u'A pdf File')
|
||||||
>>> pdf.data = open(os.path.join(path, 'test.pdf')).read()
|
>>> pdf.data = open(os.path.join(path, 'test.pdf')).read()
|
||||||
>>> pdf.getSize()
|
>>> pdf.getSize()
|
||||||
25862
|
25862
|
||||||
|
@ -499,8 +498,7 @@ view; these views we have to provide as multi-adapters:
|
||||||
>>> sorted((t.token, t.title) for t in view.targetTypes())
|
>>> sorted((t.token, t.title) for t in view.targetTypes())
|
||||||
[('.loops/concepts/topic', u'Topic'), ('.loops/concepts/type', u'Type'),
|
[('.loops/concepts/topic', u'Topic'), ('.loops/concepts/type', u'Type'),
|
||||||
('.loops/concepts/unknown', u'Unknown Type'),
|
('.loops/concepts/unknown', u'Unknown Type'),
|
||||||
('loops.resource.Document', u'Document'),
|
('loops.resource.Document', u'Document')]
|
||||||
('loops.resource.MediaAsset', u'Media Asset')]
|
|
||||||
>>> view.update()
|
>>> view.update()
|
||||||
True
|
True
|
||||||
>>> sorted(resources.keys())
|
>>> sorted(resources.keys())
|
||||||
|
|
|
@ -188,7 +188,9 @@
|
||||||
|
|
||||||
<require
|
<require
|
||||||
permission="zope.View"
|
permission="zope.View"
|
||||||
interface=".interfaces.IBaseResource" />
|
interface=".interfaces.IBaseResource
|
||||||
|
zope.app.size.interfaces.ISized" />
|
||||||
|
|
||||||
|
|
||||||
<require
|
<require
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
|
@ -289,8 +291,8 @@
|
||||||
<adapter factory="loops.type.ConceptType" />
|
<adapter factory="loops.type.ConceptType" />
|
||||||
<adapter factory="loops.type.ResourceType"
|
<adapter factory="loops.type.ResourceType"
|
||||||
for="loops.interfaces.IDocument" />
|
for="loops.interfaces.IDocument" />
|
||||||
<adapter factory="loops.type.ResourceType"
|
<!--<adapter factory="loops.type.ResourceType"
|
||||||
for="loops.interfaces.IMediaAsset" />
|
for="loops.interfaces.IMediaAsset" />-->
|
||||||
<adapter factory="loops.type.LoopsTypeManager" />
|
<adapter factory="loops.type.LoopsTypeManager" />
|
||||||
|
|
||||||
<adapter factory="loops.type.TypeConcept" trusted="True" />
|
<adapter factory="loops.type.TypeConcept" trusted="True" />
|
||||||
|
|
57
helpers.txt
57
helpers.txt
|
@ -12,7 +12,7 @@ Let's first do some basic imports
|
||||||
|
|
||||||
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
||||||
>>> site = placefulSetUp(True)
|
>>> site = placefulSetUp(True)
|
||||||
|
|
||||||
>>> from zope import interface, component
|
>>> from zope import interface, component
|
||||||
>>> from zope.app import zapi
|
>>> from zope.app import zapi
|
||||||
>>> from zope.app.tests import ztapi
|
>>> from zope.app.tests import ztapi
|
||||||
|
@ -25,7 +25,7 @@ and provide a relation registry:
|
||||||
>>> from cybertools.relation.registry import DummyRelationRegistry
|
>>> from cybertools.relation.registry import DummyRelationRegistry
|
||||||
>>> from zope.app.testing import ztapi
|
>>> from zope.app.testing import ztapi
|
||||||
>>> ztapi.provideUtility(IRelationRegistry, DummyRelationRegistry())
|
>>> ztapi.provideUtility(IRelationRegistry, DummyRelationRegistry())
|
||||||
|
|
||||||
and care for some type adapter machinery:
|
and care for some type adapter machinery:
|
||||||
|
|
||||||
>>> from loops.interfaces import IConcept
|
>>> from loops.interfaces import IConcept
|
||||||
|
@ -35,7 +35,7 @@ and care for some type adapter machinery:
|
||||||
|
|
||||||
Now we can setup a simple loops site with its manager objects, using a
|
Now we can setup a simple loops site with its manager objects, using a
|
||||||
loops setup manager:
|
loops setup manager:
|
||||||
|
|
||||||
>>> from loops import Loops
|
>>> from loops import Loops
|
||||||
>>> loopsRoot = site['loops'] = Loops()
|
>>> loopsRoot = site['loops'] = Loops()
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ loops setup manager:
|
||||||
u'has Type'
|
u'has Type'
|
||||||
|
|
||||||
We also add some example concepts,
|
We also add some example concepts,
|
||||||
|
|
||||||
>>> from loops.concept import Concept
|
>>> from loops.concept import Concept
|
||||||
>>> cc1 = Concept(u'Zope')
|
>>> cc1 = Concept(u'Zope')
|
||||||
>>> concepts['cc1'] = cc1
|
>>> concepts['cc1'] = cc1
|
||||||
|
@ -59,21 +59,21 @@ We also add some example concepts,
|
||||||
u'Zope 3'
|
u'Zope 3'
|
||||||
|
|
||||||
resources,
|
resources,
|
||||||
|
|
||||||
>>> from loops.resource import Resource
|
>>> from loops.resource import Resource
|
||||||
>>> file1 = resources['file1'] = Resource(u'A file')
|
>>> file1 = resources['file1'] = Resource(u'A file')
|
||||||
>>> file1.resourceType = concepts['file']
|
>>> file1.resourceType = concepts['file']
|
||||||
|
|
||||||
(the use of Document and MediaAsset may get deprecated soon:)
|
(the use of Document may get deprecated soon:)
|
||||||
|
|
||||||
>>> from loops.resource import Document, MediaAsset
|
>>> from loops.resource import Document
|
||||||
>>> doc1 = Document(u'Zope Info')
|
>>> doc1 = Document(u'Zope Info')
|
||||||
>>> resources['doc1'] = doc1
|
>>> resources['doc1'] = doc1
|
||||||
>>> doc1.title
|
>>> doc1.title
|
||||||
u'Zope Info'
|
u'Zope Info'
|
||||||
|
|
||||||
>>> img1 = MediaAsset(u'An Image')
|
>>> img1 = resources['img1'] = Resource(u'An Image')
|
||||||
>>> resources['img1'] = img1
|
>>> img1.resourceType = concepts['file']
|
||||||
|
|
||||||
and nodes (in view space):
|
and nodes (in view space):
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ and nodes (in view space):
|
||||||
>>> m1 = Node(u'Home')
|
>>> m1 = Node(u'Home')
|
||||||
>>> views['m1'] = m1
|
>>> views['m1'] = m1
|
||||||
>>> m1.nodeType = 'menu'
|
>>> m1.nodeType = 'menu'
|
||||||
|
|
||||||
>>> m1p1 = Node(u'Page')
|
>>> m1p1 = Node(u'Page')
|
||||||
>>> m1['p1'] = m1p1
|
>>> m1['p1'] = m1p1
|
||||||
>>> m1p1.nodeType = 'page'
|
>>> m1p1.nodeType = 'page'
|
||||||
|
@ -160,7 +160,7 @@ lazy properties, one should always get a new adapter:
|
||||||
<class 'loops.concept.Concept'>
|
<class 'loops.concept.Concept'>
|
||||||
|
|
||||||
Now let's have a look at resources.
|
Now let's have a look at resources.
|
||||||
|
|
||||||
>>> from loops.interfaces import IResource
|
>>> from loops.interfaces import IResource
|
||||||
>>> from loops.type import LoopsType
|
>>> from loops.type import LoopsType
|
||||||
>>> component.provideAdapter(LoopsType, (IResource,), IType)
|
>>> component.provideAdapter(LoopsType, (IResource,), IType)
|
||||||
|
@ -177,12 +177,12 @@ Now let's have a look at resources.
|
||||||
<loops.resource.ResourceManager object ...>
|
<loops.resource.ResourceManager object ...>
|
||||||
>>> file1_type.factory
|
>>> file1_type.factory
|
||||||
<class 'loops.resource.Resource'>
|
<class 'loops.resource.Resource'>
|
||||||
|
|
||||||
(The use of Document and MediaAsset will be deprecated soon...)
|
|
||||||
|
|
||||||
>>> from loops.interfaces import IResource
|
(The use of Document will be deprecated soon...)
|
||||||
|
|
||||||
|
>>> from loops.interfaces import IResource, IDocument
|
||||||
>>> from loops.type import ResourceType
|
>>> from loops.type import ResourceType
|
||||||
>>> ztapi.provideAdapter(IResource, IType, ResourceType)
|
>>> ztapi.provideAdapter(IDocument, IType, ResourceType)
|
||||||
|
|
||||||
>>> doc1_type = IType(doc1)
|
>>> doc1_type = IType(doc1)
|
||||||
>>> doc1_type.title
|
>>> doc1_type.title
|
||||||
|
@ -197,10 +197,14 @@ Now let's have a look at resources.
|
||||||
<loops.resource.ResourceManager object ...>
|
<loops.resource.ResourceManager object ...>
|
||||||
>>> doc1_type.factory
|
>>> doc1_type.factory
|
||||||
<class 'loops.resource.Document'>
|
<class 'loops.resource.Document'>
|
||||||
|
|
||||||
>>> img1_type = IType(img1)
|
>>> img1_type = IType(img1)
|
||||||
|
>>> img1_type.token
|
||||||
|
'.loops/concepts/file'
|
||||||
|
>>> img1_type.tokenForSearch
|
||||||
|
'loops:resource:file'
|
||||||
>>> img1_type.title
|
>>> img1_type.title
|
||||||
u'Media Asset'
|
u'File'
|
||||||
|
|
||||||
Can we find out somehow which types are available? This is the time to look
|
Can we find out somehow which types are available? This is the time to look
|
||||||
for a type manager. This could be a utility; but in the loops package it
|
for a type manager. This could be a utility; but in the loops package it
|
||||||
|
@ -217,10 +221,10 @@ 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/file', '.loops/concepts/image', '.loops/concepts/predicate',
|
['.loops/concepts/file', '.loops/concepts/image', '.loops/concepts/predicate',
|
||||||
'.loops/concepts/textdocument', '.loops/concepts/topic',
|
'.loops/concepts/textdocument', '.loops/concepts/topic',
|
||||||
'.loops/concepts/type',
|
'.loops/concepts/type',
|
||||||
'loops.resource.Document', 'loops.resource.MediaAsset']
|
'loops.resource.Document']
|
||||||
|
|
||||||
>>> typeManager.getType('.loops/concepts/topic') == cc1_type
|
>>> typeManager.getType('.loops/concepts/topic') == cc1_type
|
||||||
True
|
True
|
||||||
|
@ -233,9 +237,8 @@ condition:
|
||||||
['.loops/concepts/predicate', '.loops/concepts/topic', '.loops/concepts/type']
|
['.loops/concepts/predicate', '.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/concepts/file', '.loops/concepts/image',
|
['.loops/concepts/file', '.loops/concepts/image',
|
||||||
'.loops/concepts/textdocument', 'loops.resource.Document',
|
'.loops/concepts/textdocument', 'loops.resource.Document']
|
||||||
'loops.resource.MediaAsset']
|
|
||||||
|
|
||||||
|
|
||||||
Type-based interfaces and adapters
|
Type-based interfaces and adapters
|
||||||
|
@ -264,7 +267,7 @@ i.e. the 'topic' concept, via an adapter:
|
||||||
... implements(ITopic)
|
... implements(ITopic)
|
||||||
... def __init__(self, context): pass
|
... def __init__(self, context): pass
|
||||||
>>> component.provideAdapter(Topic, (IConcept,), ITopic)
|
>>> component.provideAdapter(Topic, (IConcept,), ITopic)
|
||||||
|
|
||||||
>>> ITypeConcept(topic).typeInterface = ITopic
|
>>> ITypeConcept(topic).typeInterface = ITopic
|
||||||
>>> cc1.conceptType = topic
|
>>> cc1.conceptType = topic
|
||||||
|
|
||||||
|
@ -308,7 +311,7 @@ the concept...
|
||||||
|
|
||||||
...but only when the view exists, i.e. there is a class registered as a
|
...but only when the view exists, i.e. there is a class registered as a
|
||||||
view/multi-adapter with this name:
|
view/multi-adapter with this name:
|
||||||
|
|
||||||
>>> sq_view is sq_baseView
|
>>> sq_view is sq_baseView
|
||||||
True
|
True
|
||||||
|
|
||||||
|
@ -368,7 +371,7 @@ browser).
|
||||||
>>> from loops.browser.node import ViewPropertiesConfigurator
|
>>> from loops.browser.node import ViewPropertiesConfigurator
|
||||||
>>> component.provideAdapter(ViewPropertiesConfigurator, (INode,),
|
>>> component.provideAdapter(ViewPropertiesConfigurator, (INode,),
|
||||||
... IViewConfiguratorSchema)
|
... IViewConfiguratorSchema)
|
||||||
|
|
||||||
>>> pageConfigurator = IViewConfiguratorSchema(m1)
|
>>> pageConfigurator = IViewConfiguratorSchema(m1)
|
||||||
>>> pageConfigurator.skinName = 'SuperSkin'
|
>>> pageConfigurator.skinName = 'SuperSkin'
|
||||||
|
|
||||||
|
|
|
@ -305,21 +305,14 @@ class IDocument(IDocumentSchema, IResource):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class IMediaAssetSchema(IResourceSchema):
|
# media asset is probably obsolete - replaced by plain Resource with
|
||||||
|
# resourceType = file.
|
||||||
|
|
||||||
data = schema.Bytes(
|
class IMediaAssetView(IResourceSchema):
|
||||||
title=_(u'Data'),
|
|
||||||
description=_(u'Media asset file'),
|
|
||||||
default='',
|
|
||||||
missing_value='',
|
|
||||||
required=False)
|
|
||||||
|
|
||||||
|
|
||||||
class IMediaAssetView(IMediaAssetSchema):
|
|
||||||
""" Used for accessing a media asset via a node's target attribute"""
|
""" Used for accessing a media asset via a node's target attribute"""
|
||||||
|
|
||||||
|
|
||||||
class IMediaAsset(IMediaAssetSchema, IResource, IBaseAsset):
|
class IMediaAsset(IResourceSchema, IResource, IBaseAsset):
|
||||||
""" A resource containing a (typically binary) file-like content
|
""" A resource containing a (typically binary) file-like content
|
||||||
or an image.
|
or an image.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -46,7 +46,7 @@ from cybertools.typology.interfaces import ITypeManager
|
||||||
from interfaces import IBaseResource, IResource
|
from interfaces import IBaseResource, IResource
|
||||||
from interfaces import IFile
|
from interfaces import IFile
|
||||||
from interfaces import IDocument, IDocumentSchema, IDocumentView
|
from interfaces import IDocument, IDocumentSchema, IDocumentView
|
||||||
from interfaces import IMediaAsset, IMediaAssetSchema, IMediaAssetView
|
from interfaces import IMediaAsset, IMediaAssetView
|
||||||
from interfaces import IResourceManager, IResourceManagerContained
|
from interfaces import IResourceManager, IResourceManagerContained
|
||||||
from interfaces import ILoopsContained
|
from interfaces import ILoopsContained
|
||||||
from interfaces import IIndexAttributes
|
from interfaces import IIndexAttributes
|
||||||
|
@ -192,9 +192,6 @@ class FileAdapter(ResourceAdapterBase):
|
||||||
|
|
||||||
implements(IFile)
|
implements(IFile)
|
||||||
|
|
||||||
# TODO: provide specialized access to data attribute analog to zope.app.file;
|
|
||||||
# automatically set contentType...
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentWriteFileAdapter(object):
|
class DocumentWriteFileAdapter(object):
|
||||||
|
|
||||||
|
|
6
type.py
6
type.py
|
@ -133,7 +133,8 @@ class ResourceType(LoopsType):
|
||||||
|
|
||||||
#adapts(IResource)
|
#adapts(IResource)
|
||||||
|
|
||||||
typeTitles = {'MediaAsset': u'Media Asset'}
|
#typeTitles = {'MediaAsset': u'Media Asset'}
|
||||||
|
typeTitles = {}
|
||||||
|
|
||||||
typeInterface = None
|
typeInterface = None
|
||||||
qualifiers = ('resource',)
|
qualifiers = ('resource',)
|
||||||
|
@ -212,7 +213,8 @@ class LoopsTypeManager(TypeManager):
|
||||||
|
|
||||||
def resourceTypes(self):
|
def resourceTypes(self):
|
||||||
return tuple([ResourceTypeInfo(self.context, cls)
|
return tuple([ResourceTypeInfo(self.context, cls)
|
||||||
for cls in (Document, MediaAsset)])
|
for cls in (Document,)])
|
||||||
|
#for cls in (Document, MediaAsset)])
|
||||||
|
|
||||||
|
|
||||||
class TypeConcept(AdapterBase):
|
class TypeConcept(AdapterBase):
|
||||||
|
|
Loading…
Add table
Reference in a new issue