[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/dav/ Fixed the
rendering of the resourcetype, getcontentlength and getcontenttype
Michael Kerrin
michael.kerrin at openapp.biz
Wed May 18 12:43:13 EDT 2005
Log message for revision 30384:
Fixed the rendering of the resourcetype, getcontentlength and getcontenttype
DAV properties. WebDAV is now working with konqueror and cadaver with this fix.
Changed:
U Zope3/trunk/src/zope/app/dav/adapter.py
U Zope3/trunk/src/zope/app/dav/configure.zcml
U Zope3/trunk/src/zope/app/dav/interfaces.py
U Zope3/trunk/src/zope/app/dav/tests/test_adapter.py
U Zope3/trunk/src/zope/app/dav/tests/test_propfind.py
U Zope3/trunk/src/zope/app/dav/tests/unitfixtures.py
U Zope3/trunk/src/zope/app/dav/widget.py
-=-
Modified: Zope3/trunk/src/zope/app/dav/adapter.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/adapter.py 2005-05-18 15:21:11 UTC (rev 30383)
+++ Zope3/trunk/src/zope/app/dav/adapter.py 2005-05-18 16:43:12 UTC (rev 30384)
@@ -27,6 +27,7 @@
from zope.app.dublincore.interfaces import IDCTimes
from zope.app.filerepresentation.interfaces import IReadDirectory
from zope.app.size.interfaces import ISized
+from zope.app.file.interfaces import IFile
class DAVSchemaAdapter(object):
"""An adapter for all content objects that provides the basic DAV
@@ -63,7 +64,10 @@
sized = ISized(self.context, None)
if sized is None:
return ''
- return str(translate(sized.sizeForDisplay()))
+ units, size = sized.sizeForSorting()
+ if units == 'byte':
+ return str(size)
+ return ''
getcontentlength = property(getcontentlength)
def getlastmodified(self):
@@ -76,3 +80,10 @@
def executable(self):
return ''
executable = property(executable)
+
+ def getcontenttype(self):
+ file = IFile(self.context, None)
+ if file is not None:
+ return file.contentType
+ return ''
+ getcontenttype = property(getcontenttype)
Modified: Zope3/trunk/src/zope/app/dav/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/dav/configure.zcml 2005-05-18 15:21:11 UTC (rev 30383)
+++ Zope3/trunk/src/zope/app/dav/configure.zcml 2005-05-18 16:43:12 UTC (rev 30384)
@@ -64,6 +64,14 @@
<view
type="zope.publisher.interfaces.http.IHTTPRequest"
+ for=".interfaces.IXMLText"
+ provides="zope.app.dav.interfaces.IDAVWidget"
+ factory="zope.app.dav.widget.XMLDAVWidget"
+ permission="zope.Public"
+ />
+
+ <view
+ type="zope.publisher.interfaces.http.IHTTPRequest"
for="zope.schema.interfaces.IBytes"
provides="zope.app.dav.interfaces.IDAVWidget"
factory="zope.app.dav.widget.TextDAVWidget"
Modified: Zope3/trunk/src/zope/app/dav/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/interfaces.py 2005-05-18 15:21:11 UTC (rev 30383)
+++ Zope3/trunk/src/zope/app/dav/interfaces.py 2005-05-18 16:43:12 UTC (rev 30384)
@@ -17,11 +17,20 @@
"""
__docformat__ = 'restructuredtext'
-from zope.interface import Interface
+from zope.interface import Interface, implements
from zope.schema import Text
+from zope.schema.interfaces import IText
from zope.app.form.interfaces import IInputWidget
+class IXMLText(IText):
+ """A Text field that can optionally contain has its value a
+ minidom DOM Node.
+ """
+class XMLText(Text):
+ implements(IXMLText)
+
+
class IDAVNamespace(Interface):
"""Represents a namespace available in WebDAV XML documents.
@@ -152,15 +161,15 @@
class IDAV1Schema(IGETDependentDAVSchema):
"""DAV properties required for Level 1 compliance"""
- resourcetype = Text(title=u'''Specifies the nature of the resource''',
+ resourcetype = XMLText(title=u'''Specifies the nature of the resource''',
- description=u'''\
+ description=u'''\
The resourcetype property MUST be
defined on all DAV compliant
resources. The default value is
empty.''',
- readonly=True)
+ readonly=True)
class IDAV2Schema(IDAV1Schema):
@@ -211,15 +220,16 @@
def __call__():
"""Render the widget.
- Optionally, this method could return a minidom DOM Node as the value;
- this node will then be inersted into the resulting DAV XML response.
- Use a DocumentFragment if you want to include multiple nodes.
+ This method should not contain a minidom DOM Node as its value; if its
+ value is a minidom DOM Node then its value will be normalized to a
+ string.
+
+ If a value should be a minidom DOM Node then use the XMLDAVWidget for
+ inserting its value into the DAV XML response.
"""
def setRenderedValue(value):
"""Set the DAV value for the property
-
- value can be a DOM Element node representing the value.
"""
@@ -230,3 +240,13 @@
class ISequenceDAVWidget(IDAVWidget):
"""A DAV widget for sequences."""
+
+class IXMLDAVWidget(IDAVWidget):
+ """A DAV widget for rendering XML values.
+
+ This widget should be used if you want to insert any minidom DOM Nodes
+ into the DAV XML response.
+
+ It it receives something other then a minidom DOM Node has its value then
+ it just renders has an empty string.
+ """
Modified: Zope3/trunk/src/zope/app/dav/tests/test_adapter.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/tests/test_adapter.py 2005-05-18 15:21:11 UTC (rev 30383)
+++ Zope3/trunk/src/zope/app/dav/tests/test_adapter.py 2005-05-18 16:43:12 UTC (rev 30384)
@@ -50,7 +50,7 @@
self.context = context
def sizeForSorting(self):
- return None
+ return None, None
def sizeForDisplay(self):
msg = _(u"${num} robot unit")
@@ -121,7 +121,7 @@
>>> ztapi.provideAdapter(IRobot, ISized, RobotSize)
>>> dav.getcontentlength
- '1 robot unit'
+ ''
And if robots were directories:
Modified: Zope3/trunk/src/zope/app/dav/tests/test_propfind.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/tests/test_propfind.py 2005-05-18 15:21:11 UTC (rev 30383)
+++ Zope3/trunk/src/zope/app/dav/tests/test_propfind.py 2005-05-18 16:43:12 UTC (rev 30384)
@@ -20,7 +20,7 @@
from unittest import TestCase, TestSuite, main, makeSuite
from datetime import datetime
-from zope.interface import Interface, directlyProvides
+from zope.interface import Interface, directlyProvides, implements
from zope.publisher.interfaces.http import IHTTPRequest
from zope.pagetemplate.tests.util import normalize_xml
@@ -39,12 +39,18 @@
from zope.app.dublincore.annotatableadapter import ZDCAnnotatableAdapter
from zope.app.annotation.interfaces import IAnnotatable, IAnnotations
from zope.app.annotation.attribute import AttributeAnnotations
+from zope.app.size.interfaces import ISized
+from zope.app.file.interfaces import IFile
from zope.app.dav import propfind
from zope.app.dav.interfaces import IDAVSchema
from zope.app.dav.interfaces import IDAVNamespace
from zope.app.dav.interfaces import IDAVWidget
-from zope.app.dav.widget import TextDAVWidget, SequenceDAVWidget
+from zope.app.dav.interfaces import IXMLDAVWidget
+from zope.app.dav.interfaces import IXMLText
+from zope.app.dav.widget import TextDAVWidget, SequenceDAVWidget, \
+ XMLDAVWidget
+from zope.app.dav.interfaces import IXMLText
from zope.app.dav.opaquenamespaces import DAVOpaqueNamespacesAdapter
from zope.app.dav.opaquenamespaces import IDAVOpaqueNamespaces
from zope.app.dav.adapter import DAVSchemaAdapter
@@ -81,6 +87,18 @@
request = TestRequest(StringIO(body), StringIO(), _environ)
return request
+class FileSized(object):
+ implements(ISized)
+
+ def __init__(self, context):
+ self.context = context
+
+ def sizeForSorting(self):
+ return 'byte', len(self.context.data)
+
+ def sizeForDisplay(self):
+ return 'big'
+
class TestPlacefulPROPFIND(PlacefulSetup, TestCase):
def setUp(self):
@@ -104,6 +122,7 @@
ztapi.browserViewProviding(ITextLine, TextDAVWidget, IDAVWidget)
ztapi.browserViewProviding(IDatetime, TextDAVWidget, IDAVWidget)
ztapi.browserViewProviding(ISequence, SequenceDAVWidget, IDAVWidget)
+ ztapi.browserViewProviding(IXMLText, XMLDAVWidget, IXMLDAVWidget)
ztapi.provideAdapter(IAnnotatable, IAnnotations, AttributeAnnotations)
ztapi.provideAdapter(IAnnotatable, IZopeDublinCore,
ZDCAnnotatableAdapter)
@@ -111,6 +130,7 @@
DAVOpaqueNamespacesAdapter)
ztapi.provideAdapter(None, IDAVSchema,
DAVSchemaAdapter)
+ ztapi.provideAdapter(IFile, ISized, FileSized)
sm = zapi.getGlobalSiteManager()
directlyProvides(IDAVSchema, IDAVNamespace)
sm.provideUtility(IDAVNamespace, IDAVSchema, 'DAV:')
@@ -251,6 +271,61 @@
s2 = normalize_xml(expect)
self.assertEqual(s1, s2)
+ def test_resourcetype(self):
+ file = self.file
+ folder = traverse(self.rootFolder, 'folder')
+ req = '''<prop>
+ <resourcetype/>
+ </prop>
+ '''
+ expect_file = '''<prop>
+ <resourcetype></resourcetype>
+ </prop>
+ '''
+ expect_folder = '''<prop>
+ <resourcetype><collection/></resourcetype>
+ </prop>
+ '''
+ self._checkPropfind(file, req, expect_file)
+ self._checkPropfind(folder, req, expect_folder)
+
+ def test_getcontentlength(self):
+ file = self.file
+ folder = traverse(self.rootFolder, 'folder')
+ req = '''<prop>
+ <getcontentlength/>
+ </prop>
+ '''
+ expected_file = '''<prop>
+ <getcontentlength>%d</getcontentlength>
+ </prop>
+ ''' % len(file.data)
+ expected_folder = '''<prop>
+ <getcontentlength></getcontentlength>
+ </prop>
+ '''
+ self._checkPropfind(file, req, expected_file)
+ self._checkPropfind(folder, req, expected_folder)
+
+ def test_getcontenttype(self):
+ root = self.rootFolder
+ file = self.file
+ folder = traverse(root, 'folder')
+ req = '''<prop>
+ <getcontenttype/>
+ </prop>
+ '''
+ expected_file = '''<prop>
+ <getcontenttype>text/plain</getcontenttype>
+ </prop>
+ '''
+ expected_folder = '''<prop>
+ <getcontenttype></getcontenttype>
+ </prop>
+ '''
+ self._checkPropfind(file, req, expected_file)
+ self._checkPropfind(folder, req, expected_folder)
+
def test_davpropdctitle(self):
root = self.rootFolder
zpt = traverse(root, 'zpt')
Modified: Zope3/trunk/src/zope/app/dav/tests/unitfixtures.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/tests/unitfixtures.py 2005-05-18 15:21:11 UTC (rev 30383)
+++ Zope3/trunk/src/zope/app/dav/tests/unitfixtures.py 2005-05-18 16:43:12 UTC (rev 30384)
@@ -21,14 +21,16 @@
from zope.interface import implements
from zope.app.filerepresentation.interfaces import IWriteFile
+from zope.app.filerepresentation.interfaces import IReadDirectory
from zope.app.container.interfaces import IReadContainer
from zope.app.annotation.interfaces import IAnnotatable
+from zope.app.file.interfaces import IFile
import zope.app.location
class Folder(zope.app.location.Location, Persistent):
- implements(IReadContainer)
+ implements(IReadContainer, IReadDirectory)
def __init__(self, name, level=0, parent=None):
self.name = self.__name__ = name
@@ -48,13 +50,14 @@
class File(zope.app.location.Location, Persistent):
- implements(IWriteFile)
+ implements(IWriteFile, IFile)
def __init__(self, name, content_type, data, parent=None):
self.name = self.__name__ = name
self.content_type = content_type
self.data = data
self.__parent__ = parent
+ self.contentType = content_type
def write(self, data):
self.data = data
Modified: Zope3/trunk/src/zope/app/dav/widget.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/widget.py 2005-05-18 15:21:11 UTC (rev 30383)
+++ Zope3/trunk/src/zope/app/dav/widget.py 2005-05-18 16:43:12 UTC (rev 30384)
@@ -22,6 +22,7 @@
from zope.app.dav.interfaces import IDAVWidget
from zope.app.dav.interfaces import ITextDAVWidget
from zope.app.dav.interfaces import ISequenceDAVWidget
+from zope.app.dav.interfaces import IXMLDAVWidget
from zope.app.form import InputWidget
from zope.interface import implements
@@ -66,3 +67,21 @@
def getInputValue(self):
return [v.strip() for v in self._data.split(',')]
+
+class XMLDAVWidget(DAVWidget):
+
+ implements(IXMLDAVWidget)
+
+ def getInputValue(self):
+ return self._data
+
+ def __str__(self):
+ raise ValueError, "xmldavwidget is not a string."
+
+ def __call__(self):
+ return self._data
+
+ def setRenderedValue(self, value):
+ if not isinstance(value, minidom.Node):
+ value = ''
+ self._data = value
More information about the Zope3-Checkins
mailing list