[Checkins] SVN: zope.file/trunk/src/zope/file/ - reduce boilerplate

Fred L. Drake, Jr. fdrake at gmail.com
Mon Oct 2 18:24:10 EDT 2006


Log message for revision 70504:
  - reduce boilerplate
  - add a view that does not include a Content-Disposition response header
  

Changed:
  U   zope.file/trunk/src/zope/file/configure.zcml
  U   zope.file/trunk/src/zope/file/download.py
  U   zope.file/trunk/src/zope/file/download.txt

-=-
Modified: zope.file/trunk/src/zope/file/configure.zcml
===================================================================
--- zope.file/trunk/src/zope/file/configure.zcml	2006-10-02 21:22:11 UTC (rev 70503)
+++ zope.file/trunk/src/zope/file/configure.zcml	2006-10-02 22:24:04 UTC (rev 70504)
@@ -70,6 +70,13 @@
 
   <browser:view
       for=".interfaces.IFile"
+      name="display"
+      class=".download.Display"
+      permission="zope.View"
+      />
+
+  <browser:view
+      for=".interfaces.IFile"
       menu="zmi_views" title="Upload"
       name="edit.html"
       class=".upload.Reupload"

Modified: zope.file/trunk/src/zope/file/download.py
===================================================================
--- zope.file/trunk/src/zope/file/download.py	2006-10-02 21:22:11 UTC (rev 70503)
+++ zope.file/trunk/src/zope/file/download.py	2006-10-02 22:24:04 UTC (rev 70504)
@@ -20,47 +20,28 @@
 import zope.interface
 import zope.mimetype.interfaces
 import zope.publisher.interfaces.browser
+import zope.publisher.browser
 import zope.publisher.http
 
 
-class Download(object):
+class Download(zope.publisher.browser.BrowserView):
 
-    zope.interface.implements(
-        zope.publisher.interfaces.browser.IBrowserView,
-        zope.publisher.interfaces.browser.IBrowserPublisher)
-
-    def __init__(self, context, request):
-        self.__parent__ = context
-        self.context = context
-        self.request = request
-
     def __call__(self):
-        result = DownloadResult(self.context)
-        return result
+        return DownloadResult(self.context, contentDisposition="attachment")
 
-    def browserDefault(self, request):
-        return self, ()
 
+class Inline(zope.publisher.browser.BrowserView):
 
-class Inline(object):
+    def __call__(self):
+        return DownloadResult(self.context, contentDisposition="inline")
 
-    zope.interface.implements(
-        zope.publisher.interfaces.browser.IBrowserView,
-        zope.publisher.interfaces.browser.IBrowserPublisher)
 
-    def __init__(self, context, request):
-        self.__parent__ = context
-        self.context = context
-        self.request = request
+class Display(zope.publisher.browser.BrowserView):
 
     def __call__(self):
-        result = DownloadResult(self.context,contentDisposition="inline")
-        return result
+        return DownloadResult(self.context)
 
-    def browserDefault(self, request):
-        return self, ()
 
-
 class DownloadResult(object):
     """Result object for a download request."""
 
@@ -68,7 +49,7 @@
         zope.publisher.http.IResult)
 
     def __init__(self, context, contentType=None, downloadName=None,
-                 contentDisposition="attachment"):
+                 contentDisposition=None):
         if not contentType:
             cti = zope.mimetype.interfaces.IContentInfo(context, None)
             if cti is not None:
@@ -77,11 +58,12 @@
         self.headers = ("Content-Type", contentType),
 
         downloadName = downloadName or context.__name__
-        if downloadName:
-            contentDisposition += (
-                '; filename="%s"' % downloadName.encode("utf-8")
-                )
-        self.headers += ("Content-Disposition", contentDisposition),
+        if contentDisposition:
+            if downloadName:
+                contentDisposition += (
+                    '; filename="%s"' % downloadName.encode("utf-8")
+                    )
+            self.headers += ("Content-Disposition", contentDisposition),
 
         # This ensures that what's left has no connection to the
         # application/database; ZODB BLOBs will provide a equivalent

Modified: zope.file/trunk/src/zope/file/download.txt
===================================================================
--- zope.file/trunk/src/zope/file/download.txt	2006-10-02 21:22:11 UTC (rev 70503)
+++ zope.file/trunk/src/zope/file/download.txt	2006-10-02 22:24:04 UTC (rev 70504)
@@ -27,7 +27,7 @@
 Now, let's create a download result for this file::
 
   >>> from zope.file.download import DownloadResult
-  >>> result = DownloadResult(f)
+  >>> result = DownloadResult(f, contentDisposition='attachment')
 
 Since there's no suggested download filename on the file, the
 Content-Disposition header doesn't specify one, but does indicate that
@@ -47,7 +47,7 @@
 by default::
 
   >>> f.mimeType = "text/plain"
-  >>> result = DownloadResult(f)
+  >>> result = DownloadResult(f, contentDisposition='attachment')
   >>> sorted(result.headers)
   [('Content-Disposition', 'attachment'),
    ('Content-Length', '0'),
@@ -56,7 +56,8 @@
 Alternatively, a content type can be specified to the result
 constructor::
 
-  >>> result = DownloadResult(f, contentType="text/xml")
+  >>> result = DownloadResult(f, contentType="text/xml",
+  ...                         contentDisposition='attachment')
   >>> sorted(result.headers)
   [('Content-Disposition', 'attachment'),
    ('Content-Length', '0'),
@@ -65,7 +66,7 @@
 The filename provided to the browser can be controlled similarly.  If
 the content object provides one, it will be used by default::
 
-  >>> result = DownloadResult(f)
+  >>> result = DownloadResult(f, contentDisposition='attachment')
   >>> sorted(result.headers)
   [('Content-Disposition', 'attachment'),
    ('Content-Length', '0'),
@@ -74,14 +75,15 @@
 Providing an alternate name to the result constructor overrides the
 download name from the file::
 
-  >>> result = DownloadResult(f, downloadName="foo.txt")
+  >>> result = DownloadResult(f, downloadName="foo.txt",
+  ...                         contentDisposition='attachment')
   >>> sorted(result.headers)
   [('Content-Disposition', 'attachment; filename="foo.txt"'),
    ('Content-Length', '0'),
    ('Content-Type', 'text/plain')]
 
 The default Content-Disposition header can be overridden by providing
-an argument to the DownloadResult constructor:
+an argument to the DownloadResult constructor::
 
   >>> result = DownloadResult(f, contentDisposition="inline")
   >>> sorted(result.headers)
@@ -89,7 +91,15 @@
    ('Content-Length', '0'),
    ('Content-Type', 'text/plain')]
 
+If the `contentDisposition` argument is not provided, none will be
+included in the headers::
 
+  >>> result = DownloadResult(f)
+  >>> sorted(result.headers)
+  [('Content-Length', '0'),
+   ('Content-Type', 'text/plain')]
+
+
 Body
 ----
 
@@ -165,10 +175,14 @@
 
 
 The Inline View
------------------
+---------------
 
 In addition, it is sometimes useful to view the data inline instead of
-downloading it. A basic inline view is provided for this use case.
+downloading it.  A basic inline view is provided for this use case.
+Note that browsers may decide not to display the image when this view
+is used and there is not page that it's being loaded into: if this
+view is being referenced directly via the URL, the browser may show
+nothing.
 
   >>> print http("""
   ... GET /abcdefg/@@inline HTTP/1.1
@@ -180,3 +194,21 @@
   Content-Type: text/plain
   <BLANKLINE>
   some text
+
+
+The Default Display View
+------------------------
+
+This view is similar to the download and inline views, but no content
+disposition is specified at all.  This lets the browser's default
+handling of the data in the current context to be applied.
+
+  >>> print http("""
+  ... GET /abcdefg/@@display HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... """, handle_errors=False)
+  HTTP/1.1 200 Ok
+  Content-Length: 9
+  Content-Type: text/plain
+  <BLANKLINE>
+  some text



More information about the Checkins mailing list