[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/file/ file an image views now set the Last-Modified header and handle If-Modified-Since if the context is adaptable to IZopeDublinCore. This adds a dependency to zope.dublincore.

Bernd Dorn bernd.dorn at fhv.at
Fri Apr 28 07:01:55 EDT 2006


Log message for revision 67711:
  file an  image views now set the Last-Modified header and handle If-Modified-Since if the context is adaptable to IZopeDublinCore. This adds a dependency to zope.dublincore.
          
  
  

Changed:
  U   Zope3/trunk/src/zope/app/file/DEPENDENCIES.cfg
  U   Zope3/trunk/src/zope/app/file/browser/file.py
  U   Zope3/trunk/src/zope/app/file/browser/file.txt
  U   Zope3/trunk/src/zope/app/file/browser/image.py

-=-
Modified: Zope3/trunk/src/zope/app/file/DEPENDENCIES.cfg
===================================================================
--- Zope3/trunk/src/zope/app/file/DEPENDENCIES.cfg	2006-04-28 10:45:24 UTC (rev 67710)
+++ Zope3/trunk/src/zope/app/file/DEPENDENCIES.cfg	2006-04-28 11:01:55 UTC (rev 67711)
@@ -7,3 +7,4 @@
 zope.publisher
 zope.schema
 zope.testing
+zope.dublincore

Modified: Zope3/trunk/src/zope/app/file/browser/file.py
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/file.py	2006-04-28 10:45:24 UTC (rev 67710)
+++ Zope3/trunk/src/zope/app/file/browser/file.py	2006-04-28 11:01:55 UTC (rev 67711)
@@ -15,8 +15,6 @@
 
 $Id$
 """
-from datetime import datetime
-
 import zope.event
 from zope import lifecycleevent
 from zope.contenttype import guess_content_type
@@ -27,21 +25,101 @@
 from zope.app.file.file import File
 from zope.app.file.interfaces import IFile
 from zope.app.i18n import ZopeMessageFactory as _
+from zope.dublincore.interfaces import IZopeDublinCore
+import zope.datetime 
 
+import time
+from datetime import datetime
+
 __docformat__ = 'restructuredtext'
 
-
 class FileView(object):
 
     def show(self):
-        """Call the File"""
-        request = self.request
-        if request is not None:
-            request.response.setHeader('Content-Type',
-                                       self.context.contentType)
-            request.response.setHeader('Content-Length',
-                                       self.context.getSize())
 
+        """Sets various headers if the request is present and returns the
+        data of the file. If the "If-Modified-Since" header is set and
+        the context implements IZopeDublinCore, data is only returned if
+        the modification date of the context is new than the date in the
+        "If-Modified-Since" header
+        >>> from zope.publisher.browser import BrowserView, TestRequest
+        >>> class FileTestView(FileView, BrowserView): pass
+        >>> import pytz
+        >>> class MyFile(object):
+        ...     contentType='text/plain'
+        ...     data="data of file"
+        ...     modified = datetime(2006,1,1,tzinfo=pytz.utc)
+        ...     def getSize(self):
+        ...         return len(self.data)
+
+        >>> aFile = MyFile()
+        >>> request = TestRequest()
+        >>> view = FileTestView(aFile,request)
+        >>> view.show()
+        'data of file'
+        >>> request.response.getHeader('Content-Type')
+        'text/plain'
+        >>> request.response.getHeader('Content-Length')
+        '12'
+
+        If the file is adaptable to IZopeDublinCore the
+        "Last-Modified" header is also set.
+        
+        >>> request.response.getHeader('Last-Modified') is None
+        True
+
+        For the test we just declare that our file provides
+        IZopeDublinCore
+        >>> from zope.interface import directlyProvides
+        >>> directlyProvides(aFile,IZopeDublinCore)
+        >>> request = TestRequest()
+        >>> view = FileTestView(aFile,request)
+        >>> view.show()
+        'data of file'
+        >>> datetime.fromtimestamp(zope.datetime.time(
+        ...     request.response.getHeader('Last-Modified')))
+        datetime.datetime(2006, 1, 1, 0, 0)
+
+        If the "If-Modified-Since" header is set and is newer a 304
+        status is returned and the value is empty.
+        
+        >>> modified = datetime.now()
+        >>> modHeader = zope.datetime.rfc1123_date(time.mktime(modified.timetuple()))
+        >>> request = TestRequest(IF_MODIFIED_SINCE=modHeader)
+        
+        >>> view = FileTestView(aFile,request)
+        >>> view.show()
+        ''
+        >>> request.response.getStatus()
+        304
+        
+        """
+
+        if self.request is not None:
+            self.request.response.setHeader('Content-Type',
+                                            self.context.contentType)
+            self.request.response.setHeader('Content-Length',
+                                            self.context.getSize())
+        try:
+            modified = IZopeDublinCore(self.context).modified
+        except TypeError:
+            modified=None
+        if modified is None or not isinstance(modified,datetime):
+            return self.context.data
+        
+        header= self.request.getHeader('If-Modified-Since', None)
+        lmt = long(time.mktime(modified.timetuple()))
+        if header is not None:
+            header = header.split(';')[0]
+            try:    mod_since=long(zope.datetime.time(header))
+            except: mod_since=None
+            if mod_since is not None:
+                if lmt <= mod_since:
+                    self.request.response.setStatus(304)
+                    return ''
+        self.request.response.setHeader('Last-Modified',
+                                        zope.datetime.rfc1123_date(lmt))
+
         return self.context.data
 
 

Modified: Zope3/trunk/src/zope/app/file/browser/file.txt
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/file.txt	2006-04-28 10:45:24 UTC (rev 67710)
+++ Zope3/trunk/src/zope/app/file/browser/file.txt	2006-04-28 11:01:55 UTC (rev 67711)
@@ -172,6 +172,7 @@
   HTTP/1.1 200 Ok
   Content-Length: 0
   Content-Type: text/plain
+  Last-Modified: ...
   <BLANKLINE>
 
 Since it is a text file, we can edit it directly in a web form.
@@ -269,6 +270,7 @@
   HTTP/1.1 200 Ok
   Content-Length: ...
   Content-Type: text/plain
+  Last-Modified: ...  
   <BLANKLINE>
   This is a sample text file.
   <BLANKLINE>
@@ -344,6 +346,7 @@
   HTTP/1.1 200 Ok
   Content-Length: ...
   Content-Type: text/plain; charset=UTF-8
+  Last-Modified: ...
   <BLANKLINE>
   This is a sample text file.
   <BLANKLINE>
@@ -417,6 +420,7 @@
   HTTP/1.1 200 Ok
   Content-Length: ...
   Content-Type: text/plain; charset=ISO-8859-1
+  Last-Modified: ...
   <BLANKLINE>
   This is a sample text file.
   <BLANKLINE>

Modified: Zope3/trunk/src/zope/app/file/browser/image.py
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/image.py	2006-04-28 10:45:24 UTC (rev 67710)
+++ Zope3/trunk/src/zope/app/file/browser/image.py	2006-04-28 11:01:55 UTC (rev 67711)
@@ -19,14 +19,12 @@
 
 from zope.size.interfaces import ISized
 from zope.app import zapi
+from zope.app.file.browser.file import FileView
+class ImageData(FileView):
 
-class ImageData(object):
-
     def __call__(self):
         image = self.context
-        if self.request is not None:
-            self.request.response.setHeader('content-type', image.contentType)
-        return image.data
+        return self.show()
 
     def tag(self, height=None, width=None, alt=None,
             scale=0, xscale=0, yscale=0, css_class=None, **args):



More information about the Zope3-Checkins mailing list