[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