[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/file/browser/
Improve UI for file uploads.
Fred L. Drake, Jr.
fdrake at gmail.com
Mon Aug 16 20:03:35 EDT 2004
Log message for revision 27160:
Improve UI for file uploads.
- Use the name of the file being uploaded as the default name of the
object to create if not specified (only when creating a new file).
(Something similar could be done for Image if anyone has the time.)
- Determine the MIME type from the file name if not provided.
These changes require that we not use the default schema-based add and
edit forms.
Changed:
U Zope3/trunk/src/zope/app/file/browser/configure.zcml
U Zope3/trunk/src/zope/app/file/browser/file.py
A Zope3/trunk/src/zope/app/file/browser/file_add.pt
A Zope3/trunk/src/zope/app/file/browser/file_upload.pt
A Zope3/trunk/src/zope/app/file/browser/tests/test_file.py
-=-
Modified: Zope3/trunk/src/zope/app/file/browser/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/configure.zcml 2004-08-17 00:01:22 UTC (rev 27159)
+++ Zope3/trunk/src/zope/app/file/browser/configure.zcml 2004-08-17 00:03:35 UTC (rev 27160)
@@ -33,12 +33,12 @@
filter="python:context.contentType.startswith('text/')"
permission="zope.ManageContent" />
-
- <browser:editform
+ <browser:page
name="upload.html"
menu="zmi_views" title="Upload"
- schema="zope.app.file.interfaces.IFile"
- label="Upload a file"
+ for="zope.app.file.interfaces.IFile"
+ template="file_upload.pt"
+ class=".file.FileUpload"
permission="zope.ManageContent"
/>
@@ -58,11 +58,11 @@
view="zope.app.file.File"
/>
- <browser:addform
- schema="zope.app.file.interfaces.IFile"
- label="Add a File"
- content_factory="zope.app.file.File"
+ <browser:page
name="zope.app.file.File"
+ for="zope.app.container.interfaces.IAdding"
+ template="file_add.pt"
+ class=".file.FileAdd"
permission="zope.ManageContent"
/>
Modified: Zope3/trunk/src/zope/app/file/browser/file.py
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/file.py 2004-08-17 00:01:22 UTC (rev 27159)
+++ Zope3/trunk/src/zope/app/file/browser/file.py 2004-08-17 00:03:35 UTC (rev 27160)
@@ -15,8 +15,16 @@
$Id$
"""
+
+from datetime import datetime
+
+from zope.app import content_types
+from zope.app.file.file import File
+from zope.app.i18n import ZopeMessageIDFactory as _
+
__docformat__ = 'restructuredtext'
+
class FileView(object):
def show(self):
@@ -29,3 +37,129 @@
self.context.getSize())
return self.context.data
+
+
+class FileUpdateView(object):
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def errors(self):
+ form = self.request.form
+ if "UPDATE_SUBMIT" in form:
+ filename = getattr(form["field.data"], "filename", None)
+ contenttype = form.get("field.contentType")
+ if filename:
+ if not contenttype:
+ contenttype = content_types.guess_content_type(filename)[0]
+ if not form.get("add_input_name"):
+ form["add_input_name"] = filename
+ return self.update_object(form["field.data"], contenttype)
+ return ''
+
+
+class FileAdd(FileUpdateView):
+ """View that adds a new File object based on a file upload.
+
+ >>> class FauxAdding(object):
+ ... def add(self, content):
+ ... self.content = content
+ ... def nextURL(self):
+ ... return 'next url'
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> import StringIO
+ >>> sio = StringIO.StringIO("some data")
+ >>> sio.filename = 'abc.txt'
+
+ Let's make sure we can use the uploaded file name if one isn't
+ specified by the user, and can use the content type when
+ specified.
+
+ >>> request = TestRequest(form={'field.data': sio,
+ ... 'field.contentType': 'text/foobar',
+ ... 'UPDATE_SUBMIT': 'Add'})
+ >>> adding = FauxAdding()
+ >>> view = FileAdd(adding, request)
+ >>> view.errors()
+ ''
+ >>> adding.content.contentType
+ 'text/foobar'
+ >>> adding.content.data
+ 'some data'
+ >>> request.form['add_input_name']
+ 'abc.txt'
+
+ Now let's guess the content type, but also use a provided file
+ name for adding the new content object:
+
+ >>> request = TestRequest(form={'field.data': sio,
+ ... 'field.contentType': '',
+ ... 'add_input_name': 'splat.txt',
+ ... 'UPDATE_SUBMIT': 'Add'})
+ >>> adding = FauxAdding()
+ >>> view = FileAdd(adding, request)
+ >>> view.errors()
+ ''
+ >>> adding.content.contentType
+ 'text/plain'
+ >>> request.form['add_input_name']
+ 'splat.txt'
+
+ """
+
+ def update_object(self, data, contenttype):
+ f = File(data, contenttype)
+ self.context.add(f)
+ self.request.response.redirect(self.context.nextURL())
+ return ''
+
+
+class FileUpload(FileUpdateView):
+ """View that updates an existing File object with a new upload.
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> import StringIO
+ >>> sio = StringIO.StringIO("some data")
+ >>> sio.filename = 'abc.txt'
+
+ Let's make sure we can use the uploaded file name if one isn't
+ specified by the user, and can use the content type when
+ specified.
+
+ >>> request = TestRequest(form={'field.data': sio,
+ ... 'field.contentType': 'text/foobar',
+ ... 'UPDATE_SUBMIT': 'Update'})
+ >>> file = File()
+ >>> view = FileUpload(file, request)
+ >>> view.errors()
+ u'Updated on ${date_time}'
+ >>> file.contentType
+ 'text/foobar'
+ >>> file.data
+ 'some data'
+
+ Now let's guess the content type, but also use a provided file
+ name for adding the new content object:
+
+ >>> request = TestRequest(form={'field.data': sio,
+ ... 'field.contentType': '',
+ ... 'add_input_name': 'splat.txt',
+ ... 'UPDATE_SUBMIT': 'Update'})
+ >>> file = File()
+ >>> view = FileUpload(file, request)
+ >>> view.errors()
+ u'Updated on ${date_time}'
+ >>> file.contentType
+ 'text/plain'
+ """
+
+ def update_object(self, data, contenttype):
+ self.context.contentType = contenttype
+ self.context.data = data
+ formatter = self.request.locale.dates.getFormatter(
+ 'dateTime', 'medium')
+ status = _("Updated on ${date_time}")
+ status.mapping = {'date_time': formatter.format(datetime.utcnow())}
+ return status
Added: Zope3/trunk/src/zope/app/file/browser/file_add.pt
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/file_add.pt 2004-08-17 00:01:22 UTC (rev 27159)
+++ Zope3/trunk/src/zope/app/file/browser/file_add.pt 2004-08-17 00:03:35 UTC (rev 27160)
@@ -0,0 +1,57 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+ <form action="." tal:attributes="action request/URL"
+ method="POST" enctype="multipart/form-data">
+
+ <h3>Add a File</h3>
+
+ <div tal:define="errors view/errors" tal:content="errors" />
+
+ <div class="row">
+ <div class="label">
+ <label for="field.contentType"
+ title="The content type identifies the type of data."
+ >Content Type</label>
+ </div>
+ <div class="field">
+ <input class="textType"
+ id="field.contentType"
+ name="field.contentType"
+ size="20"
+ type="text"
+ value="" /></div>
+ </div>
+
+ <div class="row">
+ <div class="label">
+ <label for="field.data"
+ title="The actual content of the object.">Data</label>
+ </div>
+ <div class="field">
+ <input class="fileType"
+ id="field.data"
+ name="field.data"
+ size="20"
+ type="file" /></div>
+ </div>
+
+ <div class="row">
+ <div class="controls"><hr />
+
+ <input type="submit" value="Refresh" />
+ <input type="submit" value="Add" name="UPDATE_SUBMIT" />
+
+ <b i18n:translate="">Object Name</b>
+ <input type="text" name="add_input_name" value="" />
+
+ </div>
+ </div>
+
+ </form>
+
+</div>
+</body>
+
+</html>
Property changes on: Zope3/trunk/src/zope/app/file/browser/file_add.pt
___________________________________________________________________
Name: svn:mime-type
+ text/xml
Name: svn:eol-style
+ native
Added: Zope3/trunk/src/zope/app/file/browser/file_upload.pt
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/file_upload.pt 2004-08-17 00:01:22 UTC (rev 27159)
+++ Zope3/trunk/src/zope/app/file/browser/file_upload.pt 2004-08-17 00:03:35 UTC (rev 27160)
@@ -0,0 +1,59 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+ <form action="." tal:attributes="action request/URL"
+ method="POST" enctype="multipart/form-data">
+
+ <h3>Upload a file</h3>
+
+ <div tal:define="errors view/errors" tal:content="errors" />
+
+ <div class="row">
+ <div class="label">
+ <label for="field.contentType"
+ title="The content type identifies the type of data."
+ >Content Type</label>
+ </div>
+ <div class="field">
+ <input class="textType"
+ id="field.contentType"
+ name="field.contentType"
+ size="20"
+ type="text"
+ value="" />
+ <tal:span i18n:translate="" tal:condition="context/contentType"
+ >(currently
+ <span i18n:name="content-type"
+ tal:replace="context/contentType"/>)</tal:span>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="label">
+ <label for="field.data"
+ title="The actual content of the object.">Data</label>
+ </div>
+ <div class="field">
+ <input class="fileType"
+ id="field.data"
+ name="field.data"
+ size="20"
+ type="file" /></div>
+ </div>
+
+ <div class="row">
+ <div class="controls"><hr />
+
+ <input type="submit" value="Refresh" />
+ <input type="submit" value="Update" name="UPDATE_SUBMIT" />
+
+ </div>
+ </div>
+
+ </form>
+
+</div>
+</body>
+
+</html>
Property changes on: Zope3/trunk/src/zope/app/file/browser/file_upload.pt
___________________________________________________________________
Name: svn:mime-type
+ text/xml
Name: svn:eol-style
+ native
Added: Zope3/trunk/src/zope/app/file/browser/tests/test_file.py
===================================================================
--- Zope3/trunk/src/zope/app/file/browser/tests/test_file.py 2004-08-17 00:01:22 UTC (rev 27159)
+++ Zope3/trunk/src/zope/app/file/browser/tests/test_file.py 2004-08-17 00:03:35 UTC (rev 27160)
@@ -0,0 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+"""Tests for zope.app.file.browser.file.
+
+$Id$
+"""
+import unittest
+
+from zope.testing import doctest
+
+
+def test_suite():
+ return doctest.DocTestSuite("zope.app.file.browser.file")
+
+if __name__ == "__main__":
+ unittest.main(defaultTest="test_suite")
Property changes on: Zope3/trunk/src/zope/app/file/browser/tests/test_file.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:eol-style
+ native
More information about the Zope3-Checkins
mailing list