Define the WebDAV data model for the File and Image objects from the `zope.file' module.
Project description
============================
zope.file webdav integration
============================
>>> import z3c.etree
>>> import zope.event
>>> from zope.lifecycleevent import ObjectCreatedEvent
>>> from zope.file.file import File
>>> etree = z3c.etree.getEngine()
Create a content object called `textfile.txt` in the root folder.
>>> f = File('text/plain', {'charset': 'ascii'})
>>> fp = f.open('w')
>>> fp.write('%s\n' %('x' * 10) * 5)
>>> fp.close()
Emit the `CreateObjectEvent' to generate lastmodified and created dates.
>>> zope.event.notify(ObjectCreatedEvent(f))
>>> getRootFolder()['testfile.txt'] = f
PROPFIND
========
Query the WebDAV data model for the file object. The following properties
currently make up the data model for zope.file:
+ {DAV:}creationdate
+ {DAV:}displayname
+ {DAV:}getcontentlength
+ {DAV:}getcontenttype
+ {DAV:}getlastmodified
+ {DAV:}resourcetype
Query all properties on our test file.
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... """, handle_errors = False)
>>> print resp.getBody() #doctest:+XMLDATA,+ELLIPSIS
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<creationdate>...</creationdate>
<displayname />
<getlastmodified>...</getlastmodified>
<getcontenttype>text/plain</getcontenttype>
<getcontentlength>55</getcontentlength>
<resourcetype />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
The `{DAV:}getetag` and `{DAV:}getcontentlanguage` properties are not defined
(yet) on a file object.
>>> resp.getMSProperty('http://localhost/testfile.txt', '{DAV:}getetag')
Traceback (most recent call last):
...
KeyError: "'{DAV:}getetag' property not found for resource http://localhost/testfile.txt (200)"
>>> resp.getMSProperty(
... 'http://localhost/testfile.txt', '{DAV:}getcontentlanguage')
Traceback (most recent call last):
...
KeyError: "'{DAV:}getcontentlanguage' property not found for resource http://localhost/testfile.txt (200)"
PROPPATCH
=========
We need to be logged in to update a property.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <displayname>Test title</displayname>
... </prop>
... </set>
... </propertyupdate>"""
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Content-Type: application/xml
... Content-Length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
401
Now update the title of the file.
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-Type: application/xml
... Content-Length: %d
...
... %s""" %(len(reqbody), reqbody), handle_errors = False)
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<displayname />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Retrieve the displayname property using PROPFIND and notice the difference.
>>> reqbody = """<propfind xmlns="DAV:">
... <prop>
... <displayname />
... </prop>
... </propfind>
... """
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... Content-type: application/xml
... Content-Length: %d
...
... %s""" %(len(reqbody), reqbody), handle_errors = False)
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<displayname>Test title</displayname>
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
The `{DAV:}getcontentlength` property is a live property, and as such we
cannot modify it.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <getcontentlength>24</getcontentlength>
... </prop>
... </set>
... </propertyupdate>"""
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<getcontentlength />
</prop>
<status>HTTP/1.1 403 Forbidden</status>
</propstat>
</response>
</multistatus>
Opaque properties
=================
Set two dead properties on our resource.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <E:prop1 xmlns:E="examplens:">PROPERTY 1</E:prop1>
... <E:prop2 xmlns:E="examplens:">PROPERTY 2</E:prop2>
... </prop>
... </set>
... </propertyupdate>
... """
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody), handle_errors = True)
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<ns1:prop1 xmlns:ns1="examplens:" />
<ns1:prop2 xmlns:ns1="examplens:" />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Query these new properties.
>>> reqbody = """<propfind xmlns="DAV:">
... <prop xmlns:E="examplens:" >
... <E:prop1 />
... <E:prop2 />
... </prop>
... </propfind>
... """
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<E:prop1 xmlns:E="examplens:">PROPERTY 1</E:prop1>
<E:prop2 xmlns:E="examplens:">PROPERTY 2</E:prop2>
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Update the first property and remove the second.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <E:prop1 xmlns:E="examplens:">Only opaque property</E:prop1>
... </prop>
... </set>
... <remove>
... <prop>
... <E:prop2 xmlns:E="examplens:" />
... </prop>
... </remove>
... </propertyupdate>"""
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<E:prop1 xmlns:E="examplens:" />
<E:prop2 xmlns:E="examplens:" />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Now check that the opaque properties were updated successfully.
>>> reqbody = """<propfind xmlns="DAV:">
... <prop xmlns:E="examplens:" >
... <E:prop1 />
... <E:prop2 />
... </prop>
... </propfind>
... """
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<ns1:prop1 xmlns:ns1="examplens:">Only opaque property</ns1:prop1>
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
<propstat>
<prop>
<ns1:prop2 xmlns:ns1="examplens:" />
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>
==============================
Changes in z3c.davapp.zopefile
==============================
zope.file webdav integration
============================
>>> import z3c.etree
>>> import zope.event
>>> from zope.lifecycleevent import ObjectCreatedEvent
>>> from zope.file.file import File
>>> etree = z3c.etree.getEngine()
Create a content object called `textfile.txt` in the root folder.
>>> f = File('text/plain', {'charset': 'ascii'})
>>> fp = f.open('w')
>>> fp.write('%s\n' %('x' * 10) * 5)
>>> fp.close()
Emit the `CreateObjectEvent' to generate lastmodified and created dates.
>>> zope.event.notify(ObjectCreatedEvent(f))
>>> getRootFolder()['testfile.txt'] = f
PROPFIND
========
Query the WebDAV data model for the file object. The following properties
currently make up the data model for zope.file:
+ {DAV:}creationdate
+ {DAV:}displayname
+ {DAV:}getcontentlength
+ {DAV:}getcontenttype
+ {DAV:}getlastmodified
+ {DAV:}resourcetype
Query all properties on our test file.
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... """, handle_errors = False)
>>> print resp.getBody() #doctest:+XMLDATA,+ELLIPSIS
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<creationdate>...</creationdate>
<displayname />
<getlastmodified>...</getlastmodified>
<getcontenttype>text/plain</getcontenttype>
<getcontentlength>55</getcontentlength>
<resourcetype />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
The `{DAV:}getetag` and `{DAV:}getcontentlanguage` properties are not defined
(yet) on a file object.
>>> resp.getMSProperty('http://localhost/testfile.txt', '{DAV:}getetag')
Traceback (most recent call last):
...
KeyError: "'{DAV:}getetag' property not found for resource http://localhost/testfile.txt (200)"
>>> resp.getMSProperty(
... 'http://localhost/testfile.txt', '{DAV:}getcontentlanguage')
Traceback (most recent call last):
...
KeyError: "'{DAV:}getcontentlanguage' property not found for resource http://localhost/testfile.txt (200)"
PROPPATCH
=========
We need to be logged in to update a property.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <displayname>Test title</displayname>
... </prop>
... </set>
... </propertyupdate>"""
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Content-Type: application/xml
... Content-Length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
401
Now update the title of the file.
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-Type: application/xml
... Content-Length: %d
...
... %s""" %(len(reqbody), reqbody), handle_errors = False)
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<displayname />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Retrieve the displayname property using PROPFIND and notice the difference.
>>> reqbody = """<propfind xmlns="DAV:">
... <prop>
... <displayname />
... </prop>
... </propfind>
... """
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... Content-type: application/xml
... Content-Length: %d
...
... %s""" %(len(reqbody), reqbody), handle_errors = False)
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<displayname>Test title</displayname>
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
The `{DAV:}getcontentlength` property is a live property, and as such we
cannot modify it.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <getcontentlength>24</getcontentlength>
... </prop>
... </set>
... </propertyupdate>"""
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<getcontentlength />
</prop>
<status>HTTP/1.1 403 Forbidden</status>
</propstat>
</response>
</multistatus>
Opaque properties
=================
Set two dead properties on our resource.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <E:prop1 xmlns:E="examplens:">PROPERTY 1</E:prop1>
... <E:prop2 xmlns:E="examplens:">PROPERTY 2</E:prop2>
... </prop>
... </set>
... </propertyupdate>
... """
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody), handle_errors = True)
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<ns1:prop1 xmlns:ns1="examplens:" />
<ns1:prop2 xmlns:ns1="examplens:" />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Query these new properties.
>>> reqbody = """<propfind xmlns="DAV:">
... <prop xmlns:E="examplens:" >
... <E:prop1 />
... <E:prop2 />
... </prop>
... </propfind>
... """
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<E:prop1 xmlns:E="examplens:">PROPERTY 1</E:prop1>
<E:prop2 xmlns:E="examplens:">PROPERTY 2</E:prop2>
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Update the first property and remove the second.
>>> reqbody = """<propertyupdate xmlns="DAV:">
... <set>
... <prop>
... <E:prop1 xmlns:E="examplens:">Only opaque property</E:prop1>
... </prop>
... </set>
... <remove>
... <prop>
... <E:prop2 xmlns:E="examplens:" />
... </prop>
... </remove>
... </propertyupdate>"""
>>> resp = webdav("""
... PROPPATCH /testfile.txt HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<E:prop1 xmlns:E="examplens:" />
<E:prop2 xmlns:E="examplens:" />
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
</response>
</multistatus>
Now check that the opaque properties were updated successfully.
>>> reqbody = """<propfind xmlns="DAV:">
... <prop xmlns:E="examplens:" >
... <E:prop1 />
... <E:prop2 />
... </prop>
... </propfind>
... """
>>> resp = webdav("""
... PROPFIND /testfile.txt HTTP/1.1
... Content-type: application/xml
... Content-length: %d
...
... %s""" %(len(reqbody), reqbody))
>>> resp.getStatus()
207
>>> resp.getHeader('content-type')
'application/xml'
>>> print resp.getBody() #doctest:+XMLDATA
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
<ns1:prop1 xmlns:ns1="examplens:">Only opaque property</ns1:prop1>
</prop>
<status>HTTP/1.1 200 Ok</status>
</propstat>
<propstat>
<prop>
<ns1:prop2 xmlns:ns1="examplens:" />
</prop>
<status>HTTP/1.1 404 Not Found</status>
</propstat>
</response>
</multistatus>
==============================
Changes in z3c.davapp.zopefile
==============================
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Close
Hashes for z3c.davapp.zopefile-1.0b1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 194c583b263b03dbe733ecf60b7768ac9e4826d541039e0adce91db905cc18bf |
|
MD5 | 36a6ddd749a38ebc78b88307933fd68c |
|
BLAKE2b-256 | 46416caa70acc10d4811922a7ba1c72d90b4fe58c51964ba6cd577ea2fc5f74f |