diff --git a/README.txt b/README.txt index a269591..3420b81 100755 --- a/README.txt +++ b/README.txt @@ -19,13 +19,12 @@ Let's start with creating a few example concepts, putting them in a top-level loops container and a concept manager: >>> from loops import Loops - >>> loops = Loops() >>> site['loops'] = Loops() - >>> loops = site['loops'] + >>> loopsRoot = site['loops'] >>> from loops.concept import ConceptManager, Concept - >>> loops['concepts'] = ConceptManager() - >>> concepts = loops['concepts'] + >>> loopsRoot['concepts'] = ConceptManager() + >>> concepts = loopsRoot['concepts'] >>> cc1 = Concept() >>> concepts['cc1'] = cc1 >>> cc1.title @@ -78,8 +77,8 @@ Resources and what they have to do with Concepts We first need a resource manager: >>> from loops.resource import ResourceManager, Document - >>> loops['resources'] = ResourceManager() - >>> resources = loops['resources'] + >>> loopsRoot['resources'] = ResourceManager() + >>> resources = loopsRoot['resources'] A common type of resource is a document: @@ -90,10 +89,35 @@ A common type of resource is a document: >>> doc1.data u'' >>> doc1.contentType - u'text/xml' + '' Another one is a media asset: + >>> from loops.resource import MediaAsset + >>> img = MediaAsset(u'A png Image') + +For testing we use some simple files from the tests directory: + + >>> from loops import tests + >>> import os + >>> path = os.path.join(*tests.__path__) + >>> img.data = open(os.path.join(path, 'test_icon.png')).read() + >>> img.getSize() + 381 + >>> img.getImageSize() + (16, 16) + >>> img.contentType + 'image/png' + + >>> pdf = MediaAsset(u'A pdf File') + >>> pdf.data = open(os.path.join(path, 'test.pdf')).read() + >>> pdf.getSize() + 25862 + >>> pdf.getImageSize() + (-1, -1) + >>> pdf.contentType + 'application/pdf' + We can associate a resource with a concept by assigning it to the concept: >>> cc1.assignResource(doc1) @@ -129,8 +153,8 @@ We first need a view manager: >>> nodeChecker = NamesChecker(('body',)) >>> defineChecker(Node, nodeChecker) - >>> loops['views'] = ViewManager() - >>> views = loops['views'] + >>> loopsRoot['views'] = ViewManager() + >>> views = loopsRoot['views'] The view space is typically built up with nodes; a node may be a top-level menu that may contain other nodes as menu or content items: @@ -290,7 +314,6 @@ instance to another. >>> data[3]['name'] u'm112' - >>> import os >>> dumpname = os.path.dirname(__file__) + '/test.tmp' >>> exporter.filename = dumpname >>> exporter.dumpData() diff --git a/configure.zcml b/configure.zcml index f136103..7403b9c 100644 --- a/configure.zcml +++ b/configure.zcml @@ -152,6 +152,12 @@ + + - - diff --git a/interfaces.py b/interfaces.py index 60e8a13..3191d02 100644 --- a/interfaces.py +++ b/interfaces.py @@ -108,14 +108,23 @@ class IResource(Interface): title = schema.TextLine( title=_(u'Title'), - description=_(u'Title of the document'), + description=_(u'Title of the resource'), + default=u'', + missing_value=u'', required=False) - contentType = schema.TextLine( + contentType = schema.BytesLine( title=_(u'Content Type'), - description=_(u'Content type (format) of the body field, ' - 'default is "text/xml"'), - default=_(u'text/xml'), + description=_(u'Content type (format) of the data field'), + default='', + missing_value='', + required=False) + + data = schema.Bytes( + title=_(u'Data'), + description=_(u'Resource raw data'), + default='', + missing_value='', required=False) def getClients(relationships=None): @@ -131,6 +140,8 @@ class IDocument(IResource): data = schema.Text( title=_(u'Data'), description=_(u'Raw body data of the document'), + default=u'', + missing_value=u'', required=False) @@ -141,7 +152,9 @@ class IMediaAsset(IResource, IBaseAsset): data = schema.Bytes( title=_(u'Data'), - description=_(u'Media asset raw data'), + description=_(u'Media asset file'), + default='', + missing_value='', required=False) diff --git a/resource.py b/resource.py index 72ddede..8e5afaa 100644 --- a/resource.py +++ b/resource.py @@ -44,16 +44,11 @@ class Resource(Contained, Persistent): def setTitle(self, title): self._title = title title = property(getTitle, setTitle) - _contentType = u'text/xml' + _contentType = '' 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] @@ -61,11 +56,18 @@ class Resource(Contained, Persistent): def __init__(self, title=u''): self.title = title + _size = 0 + class Document(Resource): implements(IDocument) + _data = u'' + def setData(self, data): self._data = data + def getData(self): return self._data + data = property(getData, setData) + class MediaAsset(Resource, BaseMediaAsset): @@ -75,6 +77,17 @@ class MediaAsset(Resource, BaseMediaAsset): super(MediaAsset, self).__init__() self.title = title + def _setData(self, data): + super(MediaAsset, self)._setData(data) + if not self.contentType: + self.guessContentType(data) + + data = property(BaseMediaAsset._getData, _setData) + + def guessContentType(self, data): + if data.startswith('%PDF'): + self.contentType = 'application/pdf' + class ResourceManager(BTreeContainer): diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..4bc90fb --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,4 @@ +""" +$Id$ +""" + diff --git a/tests/test.pdf b/tests/test.pdf new file mode 100644 index 0000000..b440416 Binary files /dev/null and b/tests/test.pdf differ diff --git a/tests/test_icon.png b/tests/test_icon.png new file mode 100644 index 0000000..4b84c9e Binary files /dev/null and b/tests/test_icon.png differ diff --git a/tests.py b/tests/test_loops.py similarity index 85% rename from tests.py rename to tests/test_loops.py index 784165b..503ec23 100755 --- a/tests.py +++ b/tests/test_loops.py @@ -8,11 +8,11 @@ from zope.interface import implements from zope.app import zapi from zope.app.intid.interfaces import IIntIds -from interfaces import ILoops +from loops.interfaces import ILoops from loops import Loops -from interfaces import IConcept, IConceptManager -from interfaces import IDocument, IMediaAsset, IResourceManager -from interfaces import INode, IViewManager +from loops.interfaces import IConcept, IConceptManager +from loops.interfaces import IDocument, IMediaAsset, IResourceManager +from loops.interfaces import INode, IViewManager from loops.concept import Concept, ConceptManager from loops.resource import Document, MediaAsset, ResourceManager from loops.view import Node, ViewManager @@ -43,7 +43,7 @@ def test_suite(): flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS return unittest.TestSuite(( unittest.makeSuite(Test), - DocFileSuite('README.txt', optionflags=flags), + DocFileSuite('../README.txt', optionflags=flags), )) if __name__ == '__main__': diff --git a/view.py b/view.py index 3551dde..6014819 100644 --- a/view.py +++ b/view.py @@ -159,15 +159,3 @@ class NodeTraverser(ItemTraverser): 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) -