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)
-