[Zope-CVS] CVS: Packages/Moztop/moztopsupport/dav - copy.py:1.1 move.py:1.1 configure.zcml:1.7 mkcol.py:1.2 propfind.py:1.8 views.py:1.4
Sidnei da Silva
sidnei@x3ng.com.br
Sat, 29 Mar 2003 12:10:25 -0500
Update of /cvs-repository/Packages/Moztop/moztopsupport/dav
In directory cvs.zope.org:/tmp/cvs-serv26151/moztopsupport/dav
Modified Files:
configure.zcml mkcol.py propfind.py views.py
Added Files:
copy.py move.py
Log Message:
Adding working propfind with depth, except allprop. MKCOL is working. TRACE and placeholder classes for MOVE and COPY
=== Added File Packages/Moztop/moztopsupport/dav/copy.py ===
##############################################################################
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
##############################################################################
"""DAV method COPY
$Id: copy.py,v 1.1 2003/03/29 17:09:54 sidnei Exp $
"""
__metaclass__ = type
from zope.app.interfaces.file import IWriteDirectory
from zope.app.interfaces.file import IDirectoryFactory
from zope.app.interfaces.container import IZopeWriteContainer
from zope.app.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent
from zope.component import queryAdapter, getAdapter
class COPY:
"""COPY handler
"""
def __init__(self, context, request):
self.context = context
self.request = request
def COPY(self):
request = self.request
destination = request.getHeader('destination', '')
request.response.setStatus(403)
return ''
=== Added File Packages/Moztop/moztopsupport/dav/move.py ===
##############################################################################
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
##############################################################################
"""DAV method MOVE
$Id: move.py,v 1.1 2003/03/29 17:09:54 sidnei Exp $
"""
__metaclass__ = type
from zope.app.interfaces.file import IWriteDirectory
from zope.app.interfaces.file import IDirectoryFactory
from zope.app.interfaces.container import IZopeWriteContainer
from zope.app.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent
from zope.component import queryAdapter, getAdapter
class MOVE:
"""MOVE handler
"""
def __init__(self, context, request):
self.context = context
self.request = request
def MOVE(self):
request = self.request
destination = request.getHeader('destination', '')
request.response.setStatus(403)
return ''
=== Packages/Moztop/moztopsupport/dav/configure.zcml 1.6 => 1.7 ===
--- Packages/Moztop/moztopsupport/dav/configure.zcml:1.6 Tue Mar 25 16:16:00 2003
+++ Packages/Moztop/moztopsupport/dav/configure.zcml Sat Mar 29 12:09:54 2003
@@ -4,8 +4,16 @@
name="PROPFIND"
type="zope.publisher.interfaces.http.IHTTPPresentation"
factory=".propfind.PROPFIND"
- permission="zope.Public"
- allowed_attributes="PROPFIND"
+ permission="zope.ManageContent"
+ allowed_attributes="PROPFIND setDepth getDepth"
+ />
+
+ <view for="zope.app.interfaces.http.INullResource"
+ name="MKCOL"
+ type="zope.publisher.interfaces.http.IHTTPPresentation"
+ factory=".mkcol.NullResource"
+ permission="zope.ManageContent"
+ allowed_attributes="MKCOL"
/>
<view for="*"
@@ -16,6 +24,22 @@
allowed_attributes="MKCOL"
/>
+ <view for="*"
+ name="MOVE"
+ type="zope.publisher.interfaces.http.IHTTPPresentation"
+ factory=".move.MOVE"
+ permission="zope.ManageContent"
+ allowed_attributes="MOVE"
+ />
+
+ <view for="*"
+ name="COPY"
+ type="zope.publisher.interfaces.http.IHTTPPresentation"
+ factory=".copy.COPY"
+ permission="zope.ManageContent"
+ allowed_attributes="COPY"
+ />
+
<view
for="zope.app.interfaces.content.zpt.IZPTPage"
type="zope.publisher.interfaces.http.IHTTPPresentation"
@@ -29,7 +53,7 @@
name="DAVdisplayname"
type="zope.publisher.interfaces.http.IHTTPPresentation"
factory=".views.DAVDisplayName"
- permission="zope.Public"
+ permission="zope.ManageContent"
/>
<view
@@ -37,7 +61,7 @@
name="DAVcreationdate"
type="zope.publisher.interfaces.http.IHTTPPresentation"
factory=".views.DAVCreationDate"
- permission="zope.Public"
+ permission="zope.ManageContent"
/>
<view
@@ -45,7 +69,31 @@
name="DAVresourcetype"
type="zope.publisher.interfaces.http.IHTTPPresentation"
factory=".views.DAVResourceType"
- permission="zope.Public"
+ permission="zope.ManageContent"
+ />
+
+ <view
+ for="*"
+ name="DAVexecutable"
+ type="zope.publisher.interfaces.http.IHTTPPresentation"
+ factory=".views.DAVExecutable"
+ permission="zope.ManageContent"
+ />
+
+ <view
+ for="*"
+ name="DAVgetcontentlength"
+ type="zope.publisher.interfaces.http.IHTTPPresentation"
+ factory=".views.DAVContentLength"
+ permission="zope.ManageContent"
+ />
+
+ <view
+ for="*"
+ name="DAVgetlastmodified"
+ type="zope.publisher.interfaces.http.IHTTPPresentation"
+ factory=".views.DAVLastModified"
+ permission="zope.ManageContent"
/>
</zopeConfigure>
=== Packages/Moztop/moztopsupport/dav/mkcol.py 1.1 => 1.2 ===
--- Packages/Moztop/moztopsupport/dav/mkcol.py:1.1 Tue Mar 25 16:16:27 2003
+++ Packages/Moztop/moztopsupport/dav/mkcol.py Sat Mar 29 12:09:54 2003
@@ -15,8 +15,15 @@
"""
__metaclass__ = type
-class MKCOL:
- """MKCOL handler for all Collections
+from zope.app.interfaces.file import IWriteDirectory
+from zope.app.interfaces.file import IDirectoryFactory
+from zope.app.interfaces.container import IZopeWriteContainer
+from zope.app.event import publish
+from zope.app.event.objectevent import ObjectCreatedEvent
+from zope.component import queryAdapter, getAdapter
+
+class NullResource:
+ """MKCOL handler for creating collections
"""
def __init__(self, context, request):
@@ -24,5 +31,35 @@
self.request = request
def MKCOL(self):
+ request = self.request
+ container = self.context.container
+ name = self.context.name
+
+ dir = queryAdapter(container, IWriteDirectory, None)
+ if dir is None:
+ request.response.setStatus(403)
+ return ''
+
+ dir = getAdapter(dir, IZopeWriteContainer)
+
+ factory = getAdapter(container, IDirectoryFactory)
+ newdir = factory(name)
+ publish(self.context, ObjectCreatedEvent(newdir))
+ dir.setObject(name, newdir)
+
+ request.response.setStatus(201)
return ''
+class MKCOL:
+ """MKCOL handler for existing objects
+ """
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def MKCOL(self):
+ # 405 (Method Not Allowed) - MKCOL can only be executed on a
+ # deleted/non-existent resource.
+ self.request.response.setStatus(405)
+ return ''
=== Packages/Moztop/moztopsupport/dav/propfind.py 1.7 => 1.8 ===
--- Packages/Moztop/moztopsupport/dav/propfind.py:1.7 Tue Mar 25 16:16:00 2003
+++ Packages/Moztop/moztopsupport/dav/propfind.py Sat Mar 29 12:09:54 2003
@@ -17,8 +17,10 @@
from xml.dom import minidom
from zope.component import getAdapter, getView, queryView
+from zope.proxy.context import ContextWrapper
from zope.proxy.introspection import removeAllProxies
from zope.schema import getFieldNamesInOrder
+from zope.app.interfaces.container import IReadContainer
from moztopsupport.dav.interfaces import IDAVSource, IDAVSchema
@@ -31,113 +33,137 @@
def __init__(self, context, request):
self.context = context
self.request = request
- self._depth = 'infinity'
+ self.setDepth(request.getHeader('depth', 'infinity'))
+ self.content_type = request.getHeader('content-type', '')
def getDepth(self):
return self._depth
def setDepth(self, depth):
- self._depth = depth
+ self._depth = depth.lower()
def PROPFIND(self):
request = self.request
- content_type = request.getHeader('content-type', '')
- hostname = request.getHeader('hostname', '')
+ context = self.context
+ resource_url = str(getView(context, 'absolute_url', request))
+ default_ns = 'DAV:'
data = request.bodyFile
+ data.seek(0)
response = ''
body = ''
- if content_type.lower() not in ['text/xml', 'application/xml']:
+ if self.content_type.lower() not in ['text/xml', 'application/xml']:
request.response.setStatus(400)
return body
-
- depth = request.getHeader('depth', 'infinity')
- if depth.lower() not in ['0', '1', 'infinity']:
+ if self.getDepth() not in ['0', '1', 'infinity']:
request.response.setStatus(400)
return body
- self.setDepth(depth)
-
xmldoc = minidom.parse(data)
+ response = minidom.Document()
+ ms = response.createElementNS(default_ns, 'D:multistatus')
+ ms.setAttributeNS(default_ns, 'xmlns:D', 'DAV:')
+ response.appendChild(ms)
+ re = response.createElementNS(default_ns, 'D:response')
+ ms.appendChild(re)
+ href = response.createElementNS(default_ns, 'D:href')
+ re.appendChild(href)
+ r_url = response.createTextNode(resource_url)
+ href.appendChild(r_url)
- propname = xmldoc.getElementsByTagNameNS('DAV:', 'propname')
+ propname = xmldoc.getElementsByTagNameNS(default_ns, 'propname')
if propname:
- props = self._buildProps(_avail_props)
- ok = self._buildOk(props)
- body = self._buildBody(ok)
- request.response.setStatus(207)
- request.response.setBody(body)
- return body
+ pstat = response.createElementNS(default_ns, 'D:propstat')
+ re.appendChild(pstat)
+ prop = response.createElementNS(default_ns, 'D:prop')
+ pstat.appendChild(prop)
+ for p in _avail_props:
+ el = response.createElementNS(default_ns, 'D:%s' % p )
+ prop.appendChild(el)
+ status = response.createElementNS(default_ns, 'D:status')
+ pstat.appendChild(status)
+ text = response.createTextNode('HTTP/1.1 200 OK')
+ status.appendChild(text)
- source = xmldoc.getElementsByTagNameNS('DAV:', 'prop')
+ source = xmldoc.getElementsByTagNameNS(default_ns, 'prop')
if not source:
# allprop
- return ''
+ #return ''
+ pass
- source = source[0]
- childs = [e for e in source.childNodes
- if e.nodeType == e.ELEMENT_NODE]
- not_avail = []
- for node in childs:
- localname = node.localName
- view = queryView(self.context, 'DAV%s' % localname, self.request, None)
- if view is None:
- not_avail.append(localname)
- else:
- view = removeAllProxies(view)
- response += str(view)
-
- if response:
- response = self._buildOk(response)
-
- if not_avail:
- response += self._buildNotAvail(not_avail)
-
- body = self._buildBody(response)
+ if source:
+ source = source[0]
+ childs = [e for e in source.childNodes
+ if e.nodeType == e.ELEMENT_NODE]
+ not_avail = []
+ avail = {}
+ props_ns = {}
+ for node in childs:
+ localname = node.localName
+ props_ns[localname] = node.namespaceURI
+ view = queryView(self.context, 'DAV%s' % localname, self.request, None)
+ if view is None:
+ not_avail.append(localname)
+ else:
+ view = removeAllProxies(view)
+ avail[localname] = str(view)
+
+ if avail:
+ pstat = response.createElementNS(default_ns, 'D:propstat')
+ re.appendChild(pstat)
+ prop = response.createElementNS(default_ns, 'D:prop')
+ pstat.appendChild(prop)
+ status = response.createElementNS(default_ns, 'D:status')
+ pstat.appendChild(status)
+ text = response.createTextNode('HTTP/1.1 200 OK')
+ status.appendChild(text)
+ for p in avail.keys():
+ ns = props_ns.get(p, None)
+ if ns is not None:
+ el = response.createElementNS(ns, '%s' % p )
+ el.setAttribute('xmlns', ns)
+ else:
+ el = response.createElementNS(default_ns, 'D:%s' % p )
+ prop.appendChild(el)
+ try:
+ value = minidom.parseString(avail[p]).documentElement
+ except:
+ value = response.createTextNode(avail[p])
+ el.appendChild(value)
+
+ if not_avail:
+ pstat = response.createElementNS(default_ns, 'D:propstat')
+ re.appendChild(pstat)
+ prop = response.createElementNS(default_ns, 'D:prop')
+ pstat.appendChild(prop)
+ status = response.createElementNS(default_ns, 'D:status')
+ pstat.appendChild(status)
+ text = response.createTextNode('HTTP/1.1 403 Forbidden')
+ status.appendChild(text)
+ for p in not_avail:
+ el = response.createElementNS(default_ns, 'D:%s' % p )
+ prop.appendChild(el)
+
+ depth = self.getDepth()
+ if depth == '1':
+ subdepth = '0'
+ if depth == 'infinity':
+ subdepth = 'infinity'
+ if depth != '0':
+ if IReadContainer.isImplementedBy(context):
+ for id, obj in context.items():
+ wrapped = ContextWrapper(obj, self.context, name=id)
+ pfind = queryView(wrapped, 'PROPFIND', request, None)
+ if pfind is not None:
+ pfind.setDepth(subdepth)
+ value = pfind.PROPFIND()
+ parsed = minidom.parseString(value)
+ responses = parsed.getElementsByTagNameNS(default_ns, 'response')
+ for r in responses:
+ ms.appendChild(r)
+
+ body = response.toxml('utf-8')
request.response.setBody(body)
-
request.response.setStatus(207)
return body
-
- def _buildBody(self, response):
- resource_url = str(getView(self.context, 'absolute_url', self.request))
- return self._xml % ({'resource_url':resource_url,
- 'response':response})
-
- _xml = '''<?xml version="1.0" encoding="utf-8" ?>
- <D:multistatus xmlns:D="DAV:">
- <D:response>
- <D:href>%(resource_url)s</D:href>
- %(response)s
- </D:response>
- </D:multistatus>
- '''
-
- def _buildProps(self, props):
- result = ''
- for p in props:
- result += '<D:%s />' % p
- return result
-
- def _buildOk(self, response):
- return self._ok_xml % {'response':response}
-
- _ok_xml = '''<D:propstat>
- <D:prop>%(response)s</D:prop>
- <D:status>HTTP/1.1 200 OK</D:status>
- </D:propstat>'''
-
- def _buildNotAvail(self, props):
- props = self._buildProps(props)
- return self._not_avail_xml % {'props':props}
-
- _not_avail_xml = '''<D:propstat>
- <D:prop>
- %(props)s
- </D:prop>
- <D:status>HTTP/1.1 403 Forbidden</D:status>
- <D:responsedescription> The user does not have access to this resource.
- </D:responsedescription>
- </D:propstat>
- '''
=== Packages/Moztop/moztopsupport/dav/views.py 1.3 => 1.4 ===
--- Packages/Moztop/moztopsupport/dav/views.py:1.3 Mon Mar 24 17:23:04 2003
+++ Packages/Moztop/moztopsupport/dav/views.py Sat Mar 29 12:09:54 2003
@@ -1,7 +1,11 @@
+from xml.dom import minidom
from zope.component import getView, getAdapter, queryAdapter
from zope.app.interfaces.traversing import IObjectName
from zope.app.interfaces.dublincore import IDCTimes
from zope.app.interfaces.container import IReadContainer
+from zope.app.interfaces.file import IReadFile
+from zope.app.interfaces.file import IReadDirectory
+from zope.app.interfaces.size import ISized
from zope.publisher.browser import BrowserView
from moztopsupport.dav.interfaces import IDAVSource, IDAVDisplayName, IDAVCreationDate
@@ -13,66 +17,92 @@
def __str__(self):
resource_url = str(getView(self.context, 'absolute_url', self.request))
source_url = '%s/getSource' % resource_url
- return self._xml % {'resource_url':resource_url,
- 'source_url':source_url}
+ xml = minidom.Document()
+ link = xml.createElementNS('DAV:', 'D:link')
+ xml.appendChild(link)
+ src = xml.createElementNS('DAV:', 'D:src')
+ link.appendChild(src)
+ r_url = xml.createTextNode(resource_url)
+ src.appendChild(r_url)
+ dst = xml.createElementNS('DAV:', 'D:dst')
+ link.appendChild(dst)
+ s_url = xml.createTextNode(source_url)
+ dst.appendChild(s_url)
+ return xml.documentElement.toxml()
__call__ = __str__
- _xml = '''
- <D:source>
- <D:link>
- <D:src>%(resource_url)s</D:src>
- <D:dst>%(source_url)s</D:dst>
- </D:link>
- </D:source>
- '''
-
class DAVDisplayName(BrowserView):
__implements__ = IDAVDisplayName
def __str__(self):
value = getAdapter(self.context, IObjectName)()
- return self._xml % {'value':value}
+ xml = minidom.Document()
+ text = xml.createTextNode(value)
+ return text.toxml()
__call__ = __str__
- _xml = '''
- <D:displayname>
- %(value)s
- </D:displayname>
- '''
-
class DAVCreationDate(BrowserView):
__implements__ = IDAVCreationDate
def __str__(self):
value = getAdapter(self.context, IDCTimes).created
- return self._xml % {'value':value}
+ if value is None:
+ return ''
+ value = value.strftime('%Y-%m-%d %TZ')
+ xml = minidom.Document()
+ text = xml.createTextNode(value)
+ return text.toxml()
__call__ = __str__
- _xml = '''
- <D:creationdate>
- %(value)s
- </D:creationdate>
- '''
-
class DAVResourceType(BrowserView):
def __str__(self):
value = queryAdapter(self.context, IReadContainer)
+ xml = minidom.Document()
if value is not None:
- value = '<D:collection />'
- else:
- value = ''
- return self._xml % {'value':value}
+ node = xml.createElementNS('DAV:', 'D:collection')
+ xml.appendChild(node)
+ doc = xml.documentElement
+ if doc is None:
+ return ''
+ return doc.toxml()
+
+ __call__ = __str__
+
+class DAVContentLength(BrowserView):
+
+ def __str__(self):
+ value = getAdapter(self.context, ISized).sizeForDisplay()
+ value = str(value)
+ xml = minidom.Document()
+ text = xml.createTextNode(value)
+ return text.toxml()
+
__call__ = __str__
- _xml = '''
- <D:resourcetype>
- %(value)s
- </D:resourcetype>
- '''
+class DAVLastModified(BrowserView):
+
+ def __str__(self):
+ value = getAdapter(self.context, IDCTimes).modified
+ if value is None:
+ return ''
+ value = value.strftime('%a, %d %b %Y %H:%M:%S GMT')
+ xml = minidom.Document()
+ text = xml.createTextNode(value)
+ return text.toxml()
+
+ __call__ = __str__
+
+
+class DAVExecutable(BrowserView):
+
+ def __str__(self):
+ return ''
+
+ __call__ = __str__