[Checkins] SVN: z3c.davapp.zopefile/trunk/s Since WebDAV requires a
default view defined on an object define a default
Michael Kerrin
michael.kerrin at openapp.ie
Thu Feb 14 14:14:06 EST 2008
Log message for revision 83840:
Since WebDAV requires a default view defined on an object define a default
view for zope.file content objects that is integrated with z3c.conditionalviews.
Changed:
U z3c.davapp.zopefile/trunk/setup.py
U z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/__init__.py
U z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/configure.zcml
A z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.txt
A z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.zcml
U z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/ftesting.zcml
U z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.txt
A z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.zcml
U z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/tests.py
-=-
Modified: z3c.davapp.zopefile/trunk/setup.py
===================================================================
--- z3c.davapp.zopefile/trunk/setup.py 2008-02-14 16:55:47 UTC (rev 83839)
+++ z3c.davapp.zopefile/trunk/setup.py 2008-02-14 19:14:04 UTC (rev 83840)
@@ -23,6 +23,7 @@
namespace_packages = ["z3c", "z3c.davapp"],
install_requires = ["setuptools",
"z3c.dav",
+ "z3c.conditionalviews",
"zope.file",
],
extras_require = dict(test = ["cElementTree"]),
Modified: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/__init__.py
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/__init__.py 2008-02-14 16:55:47 UTC (rev 83839)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/__init__.py 2008-02-14 19:14:04 UTC (rev 83840)
@@ -1,10 +1,11 @@
import zope.interface
import zope.component
+import zope.file.download
import zope.file.interfaces
+import z3c.conditionalviews
import z3c.dav.coreproperties
-
class FileDAVSchema(object):
"""
>>> from zope.file.file import File
@@ -42,3 +43,15 @@
@property
def getcontenttype(self):
return self.context.mimeType
+
+###############################################################################
+#
+# Define default view of the file object.
+#
+###############################################################################
+
+class Display(zope.file.download.Display):
+
+ @z3c.conditionalviews.ConditionalView
+ def __call__(self):
+ return super(Display, self).__call__()
Modified: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/configure.zcml
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/configure.zcml 2008-02-14 16:55:47 UTC (rev 83839)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/configure.zcml 2008-02-14 19:14:04 UTC (rev 83840)
@@ -1,41 +1,7 @@
-<configure xmlns="http://namespaces.zope.org/zope"
- xmlns:browser="http://namespaces.zope.org/browser">
+<configure>
- <adapter
- for="zope.file.interfaces.IFile
- zope.publisher.interfaces.http.IHTTPRequest"
- factory="z3c.dav.adapters.DAVDublinCore"
- />
+ <include package="z3c.davapp.zopefile" file="properties.zcml" />
- <adapter
- for="zope.file.interfaces.IFile"
- factory="z3c.dav.adapters.OpaqueProperties"
- trusted="1"
- />
+ <include package="z3c.davapp.zopefile" file="defaultview.zcml" />
- <adapter
- for="zope.file.interfaces.IFile
- zope.publisher.interfaces.http.IHTTPRequest"
- provides="z3c.dav.coreproperties.IDAVGetcontenttype"
- factory=".FileDAVSchema"
- />
-
- <adapter
- for="zope.file.interfaces.IFile
- zope.publisher.interfaces.http.IHTTPRequest"
- provides="z3c.dav.coreproperties.IDAVGetcontentlength"
- factory=".FileDAVSchema"
- />
-
- <!--
- Default view
- -->
- <browser:view
- for="zope.file.interfaces.IFile"
- name="index.html"
- class="zope.file.download.Display"
- permission="zope.View"
- layer="zope.publisher.interfaces.browser.IBrowserRequest"
- />
-
</configure>
Added: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.txt
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.txt (rev 0)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.txt 2008-02-14 19:14:04 UTC (rev 83840)
@@ -0,0 +1,86 @@
+=================
+Default file view
+=================
+
+The default view for the content object needs to be setup in order for WebDAV
+clients to be able to get the data for the DAV compliant resource. For example
+if we have a file called `testfile.txt' in the root folder then the URL
+`http://localhost/testfile.txt' should return the contents of the file. By
+convention the default view is called `index.html' but if this is not
+the case then you will have to re-configure the view to have your default
+view name.
+
+Setup
+-----
+
+ >>> import zope.event
+ >>> import zope.datetime
+ >>> from zope.dublincore.interfaces import IZopeDublinCore
+ >>> from zope.lifecycleevent import ObjectCreatedEvent
+ >>> from zope.file.file import File
+
+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 `modified' and `created' dates.
+
+ >>> zope.event.notify(ObjectCreatedEvent(f))
+
+ >>> getRootFolder()['testfile.txt'] = f
+
+GET
+===
+
+We need to be logged in access the `testfile.txt' resource. I think this is an
+issue with the current permissions defined in `zope.file'.
+
+ >>> resp = http("""
+ ... GET /testfile.txt HTTP/1.1
+ ... """, handle_errors = True)
+ >>> resp.getStatus()
+ 401
+
+Log in as the site manager so that we can get the contents.
+
+ >>> resp = http("""
+ ... GET /testfile.txt HTTP/1.1
+ ... Authorization: Basic mgr:mgrpw
+ ... """)
+ >>> resp.getStatus()
+ 200
+ >>> resp.getHeader('content-type')
+ 'text/plain'
+ >>> resp.getHeader('content-length')
+ '55'
+ >>> print resp.getBody()
+ xxxxxxxxxx
+ xxxxxxxxxx
+ xxxxxxxxxx
+ xxxxxxxxxx
+ xxxxxxxxxx
+
+Since we have define the view I have integrated it with the
+`z3c.conditionalviews' module which can validate most of the HTTP conditional
+requests.
+
+ >>> lmd = resp.getHeader('Last-modified')
+ >>> lmd is not None
+ True
+ >>> lmd_value = long(zope.datetime.time(lmd))
+
+ >>> resp = http("""
+ ... GET /testfile.txt HTTP/1.1
+ ... If-Modified-Since: %s
+ ... Authorization: Basic mgr:mgrpw
+ ... """ % zope.datetime.rfc1123_date(lmd_value + 60))
+ >>> resp.getStatus()
+ 304
+
+PUT
+===
+
+???
Property changes on: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.zcml
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.zcml (rev 0)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/defaultview.zcml 2008-02-14 19:14:04 UTC (rev 83840)
@@ -0,0 +1,28 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser">
+
+ <!--
+ `index.html' is usually the default file name.
+
+ `zope.file' doesn't define a default view of a file object so we will
+ define it here. WebDAV requires that the default view be defined. Note
+ that this declaration can be easily overriden since the adapter is
+ registered against `zope.publisher.interfaces.browser.IBrowserRequest'
+ components.
+ -->
+ <browser:view
+ for="zope.file.interfaces.IFile"
+ name="index.html"
+ class=".Display"
+ permission="zope.View"
+ layer="zope.publisher.interfaces.browser.IBrowserRequest"
+ />
+
+ <adapter
+ for="zope.file.interfaces.IFile
+ zope.publisher.interfaces.browser.IBrowserRequest
+ .Display"
+ factory="z3c.conditionalviews.adapters.LastModificationDate"
+ />
+
+</configure>
Modified: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/ftesting.zcml
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/ftesting.zcml 2008-02-14 16:55:47 UTC (rev 83839)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/ftesting.zcml 2008-02-14 19:14:04 UTC (rev 83840)
@@ -2,6 +2,8 @@
<include package="z3c.dav" file="ftesting.zcml" />
+ <include package="z3c.conditionalviews" />
+
<include package="zope.mimetype" file="meta.zcml"/>
<include package="zope.mimetype"/>
<include package="zope.file" />
Modified: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.txt
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.txt 2008-02-14 16:55:47 UTC (rev 83839)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.txt 2008-02-14 19:14:04 UTC (rev 83840)
@@ -3,6 +3,8 @@
============================
>>> import z3c.etree
+ >>> import zope.event
+ >>> from zope.lifecycleevent import ObjectCreatedEvent
>>> from zope.file.file import File
>>> etree = z3c.etree.getEngine()
@@ -14,35 +16,12 @@
>>> 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
-GET
-===
-The default view for the content object needs to be setup in order for WebDAV
-clients to be able to get the data for the DAV compliant resource.
-
- >>> resp = http("""
- ... GET /testfile.txt HTTP/1.1
- ... """, handle_errors = False)
- >>> resp.getStatus()
- 200
- >>> resp.getHeader('content-type')
- 'text/plain'
- >>> resp.getHeader('content-length')
- '55'
- >>> print resp.getBody()
- xxxxxxxxxx
- xxxxxxxxxx
- xxxxxxxxxx
- xxxxxxxxxx
- xxxxxxxxxx
-
-PUT
-===
-
-???
-
PROPFIND
========
@@ -67,15 +46,15 @@
... PROPFIND /testfile.txt HTTP/1.1
... """, handle_errors = False)
- >>> print resp.getBody() #doctest:+XMLDATA
+ >>> print resp.getBody() #doctest:+XMLDATA,+ELLIPSIS
<multistatus xmlns="DAV:">
<response>
<href>http://localhost/testfile.txt</href>
<propstat>
<prop>
- <creationdate />
+ <creationdate>...</creationdate>
<displayname />
- <getlastmodified />
+ <getlastmodified>...</getlastmodified>
<getcontenttype>text/plain</getcontenttype>
<getcontentlength>55</getcontentlength>
<resourcetype />
@@ -210,6 +189,7 @@
</response>
</multistatus>
+
Opaque properties
=================
Added: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.zcml
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.zcml (rev 0)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/properties.zcml 2008-02-14 19:14:04 UTC (rev 83840)
@@ -0,0 +1,29 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+ <adapter
+ for="zope.file.interfaces.IFile
+ zope.publisher.interfaces.http.IHTTPRequest"
+ factory="z3c.dav.adapters.DAVDublinCore"
+ />
+
+ <adapter
+ for="zope.file.interfaces.IFile"
+ factory="z3c.dav.adapters.OpaqueProperties"
+ trusted="1"
+ />
+
+ <adapter
+ for="zope.file.interfaces.IFile
+ zope.publisher.interfaces.http.IHTTPRequest"
+ provides="z3c.dav.coreproperties.IDAVGetcontenttype"
+ factory=".FileDAVSchema"
+ />
+
+ <adapter
+ for="zope.file.interfaces.IFile
+ zope.publisher.interfaces.http.IHTTPRequest"
+ provides="z3c.dav.coreproperties.IDAVGetcontentlength"
+ factory=".FileDAVSchema"
+ />
+
+</configure>
Modified: z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/tests.py
===================================================================
--- z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/tests.py 2008-02-14 16:55:47 UTC (rev 83839)
+++ z3c.davapp.zopefile/trunk/src/z3c/davapp/zopefile/tests.py 2008-02-14 19:14:04 UTC (rev 83840)
@@ -20,8 +20,17 @@
checker = z3c.etree.testing.xmlOutputChecker,
optionflags = doctest.REPORT_NDIFF | doctest.NORMALIZE_WHITESPACE)
properties.layer = ZopeFileDAVLayer
+
+ defaultview = zope.file.testing.FunctionalBlobDocFileSuite(
+ "defaultview.txt",
+ setUp = z3c.dav.testing.functionalSetUp,
+ tearDown = z3c.dav.testing.functionalTearDown,
+ checker = z3c.etree.testing.xmlOutputChecker,
+ optionflags = doctest.REPORT_NDIFF | doctest.NORMALIZE_WHITESPACE)
+ defaultview.layer = ZopeFileDAVLayer
return unittest.TestSuite((
doctest.DocTestSuite("z3c.davapp.zopefile"),
properties,
+ defaultview,
))
More information about the Checkins
mailing list