[Zope3-checkins] SVN: Zope3/branches/jhauser-filefieldwidget/src/zope/ Strat implementing Schema widget for storing Mime instance via

Roger Ineichen roger at projekt01.ch
Fri Jan 21 21:40:04 EST 2005


Log message for revision 28913:
  Strat implementing Schema widget for storing Mime instance via 
  the IMime interface on the IFile contents attribute.
  The Schema field can handle the Mime instance like a subwidget
  with the fields of IMime.
  
  TODO: refactoring on File and Mime class. We have to store the 
  Mime instance we get from the Schema widget on the File.
  Now we only have access to the Mime.data in the File.

Changed:
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/TODO.txt
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/configure.zcml
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/ftests.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/configure.zcml
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/file.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/interfaces.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/__init__.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/configure.zcml
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/filewidgets.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/schemawidgets.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/tests/test_mimewidget.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/schema/__init__.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_bootstrapfields.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_field.py
  U   Zope3/branches/jhauser-filefieldwidget/src/zope/schema/interfaces.py

-=-
Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/TODO.txt
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/TODO.txt	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/TODO.txt	2005-01-22 02:40:04 UTC (rev 28913)
@@ -6,7 +6,7 @@
 
 - Implement Mime widgets
 
-- Add new widget tests
+- Add new widget tests for MimeDataWidget, MimeDataEncodingWidget and MimeTypeWidget
 
 - Refactor IImage, I didn't look at it till now, but the test runs well. ;-)
 

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/configure.zcml	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/configure.zcml	2005-01-22 02:40:04 UTC (rev 28913)
@@ -11,11 +11,36 @@
       permission="zope.Public"
       />
 
-<!-- Old style text-based files -->
+<!-- new style files -->
+
+  <browser:addMenuItem
+      class="zope.app.file.interfaces.IFile"
+      title="- File"
+      description="A content type File"
+      permission="zope.ManageContent"
+      view="addFile.html"
+      />
+
+  <browser:addform
+      name="addFile.html"
+      label="Add a content type File"
+      schema="zope.app.file.interfaces.IFile"
+      fields="contents"
+      content_factory="zope.app.file.File"
+      permission="zope.ManageContent"
+      />
+
+  <browser:menuItem
+      menu="zmi_views" title="Text Edit"
+      for="zope.app.file.interfaces.IFile"
+      action="fileedit.html"
+      filter="python:context.contents.contentType.startswith('text/')"
+      permission="zope.ManageContent" />
+
   <browser:editform
-      name="BBB_edit.html"
+      name="fileedit.html"
       schema="zope.app.file.interfaces.IFile"
-      label="Change a file"
+      label="Change a text file"
       permission="zope.ManageContent" 
       >
 
@@ -25,7 +50,17 @@
 
   </browser:editform>
 
+  <browser:editform
+      name="fileupload.html"
+      menu="zmi_views" title="Upload"
+      for="zope.app.file.interfaces.IFile"
+      schema="zope.app.file.interfaces.IFile"
+      fields="contents"
+      permission="zope.ManageContent"
+      />
 
+<!-- BBB: old style files -->
+
   <browser:menuItem
       menu="zmi_views" title="Edit"
       for="zope.app.file.interfaces.IFile"
@@ -33,23 +68,21 @@
       filter="python:context.contentType.startswith('text/')"
       permission="zope.ManageContent" />
 
-
-
-<!-- upload for new style files -->
-
   <browser:editform
-      name="upload.html"
-      menu="zmi_views" title="Upload"
-      for="zope.app.file.interfaces.IFile"
+      name="edit.html"
       schema="zope.app.file.interfaces.IFile"
-      fields="contents"
-      permission="zope.ManageContent"
-      />
+      label="Change a file"
+      permission="zope.ManageContent" 
+      >
 
-<!-- BBB: upload for old style files -->
+    <widget
+        field="data"
+        class="zope.app.form.browser.BytesAreaWidget" />
 
+  </browser:editform>
+
   <browser:page
-      name="BBB_upload.html"
+      name="upload.html"
       menu="zmi_views" title="BBB Upload"
       for="zope.app.file.interfaces.IFile"
       template="file_upload.pt"

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/ftests.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/ftests.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/browser/ftests.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -65,7 +65,7 @@
     def testEditForm(self):
         self.addFile()
         response = self.publish(
-            '/file/@@BBB_edit.html',
+            '/file/@@edit.html',
             basic='mgr:mgrpw')
         self.assertEqual(response.getStatus(), 200)
         body = response.getBody()
@@ -78,7 +78,7 @@
     def testEdit(self):
         self.addFile()
         response = self.publish(
-            '/file/@@BBB_edit.html',
+            '/file/@@edit.html',
             form={'field.data': u'<h1>A File</h1>',
                   'field.contentType': u'text/plain',
                   'UPDATE_SUBMIT': u'Edit'},
@@ -97,11 +97,11 @@
     def testUploadForm(self):
         self.addFile()
         response = self.publish(
-            '/file/@@BBB_upload.html',
+            '/file/@@fileupload.html',
             basic='mgr:mgrpw')
         self.assertEqual(response.getStatus(), 200)
         body = response.getBody()
-        self.assert_('Upload a file' in body)
+        self.assert_('Encoding Type' in body)
         self.assert_('Content Type' in body)
         self.assert_('Data' in body)
         self.failIf(escape(self.content) in body)
@@ -110,20 +110,21 @@
     def testUpload(self):
         self.addFile()
         response = self.publish(
-            '/file/@@BBB_upload.html',
-            form={'field.data': StringIO('<h1>A file</h1>'),
+            '/file/@@fileupload.html',
+            form={'field.contents': StringIO('<h1>A file</h1>'),
                   'field.contentType': u'text/plain',
+                  'field.encoding': u'UTF-8',
                   'UPDATE_SUBMIT': u'Change'},
             basic='mgr:mgrpw')
         self.assertEqual(response.getStatus(), 200)
         body = response.getBody()
-        self.assert_('Upload a file' in body)
+        self.assert_('Encoding Type' in body)
         self.assert_('Content Type' in body)
         self.assert_('Data' in body)
         self.failIf(escape(u'<h1>A File</h1>') in body)
         root = self.getRootFolder()
         file = root['file']
-        self.assertEqual(file.data, '<h1>A file</h1>')
+        self.assertEqual(file.contents, '<h1>A file</h1>')
         self.assertEqual(file.contentType, 'text/plain')
         
     def testIndex(self):

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/configure.zcml	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/configure.zcml	2005-01-22 02:40:04 UTC (rev 28913)
@@ -35,6 +35,26 @@
        />
   </content>
 
+  <content class=".file.ReadFileStorage">
+
+    <require
+        permission="zope.View"
+        interface=".interfaces.IReadFileAccess"
+        />
+
+  </content>
+
+  <content class=".file.WriteFileStorage">
+
+    <require
+        permission="zope.ManageContent"
+        interface=".interfaces.IWriteFileAccess"
+        />
+
+  </content>
+
+
+
   <!-- handle the mime field value as content -->
   <content class=".file.Mime">
 
@@ -44,6 +64,11 @@
         description="Mime field Value" />
 
     <require
+        permission="zope.View"
+        interface="zope.app.file.interfaces.IMime"
+        />
+
+    <require
         permission="zope.ManageContent"
         set_schema="zope.app.file.interfaces.IMime"
         />

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/file.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/file.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/file.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -21,10 +21,16 @@
 from transaction import get_transaction
 
 from zope.interface import implements
+from zope.schema.fieldproperty import FieldProperty
 from zope.publisher.browser import FileUpload
+from zope.security.proxy import removeSecurityProxy
 
 from zope.app.file.interfaces import IMime, IFile, IFileStorage, IFileContent
 
+# TODO: remove it, just for testing
+from zope.proxy import isProxy
+
+
 # set the size of the chunks
 MAXCHUNKSIZE = 1 << 16
 
@@ -124,9 +130,9 @@
     Last, but not least, verify the interface:
 
     >>> from zope.interface.verify import verifyClass
-    >>> IMime.implementedBy(Mime)
+    >>> IFileStorage.implementedBy(FileStorage)
     True
-    >>> verifyClass(IMime, Mime)
+    >>> verifyClass(IFileStorage, FileStorage)
     True
     """
 
@@ -379,7 +385,8 @@
 
     def _getData(self):
         # TODO: shold we read via the open() method, not really? ri
-        return self._data.read()
+        file = self._data.read()
+        return file
 
     def _setData(self, data):
         # TODO: shold we write via the open() method, not really? ri
@@ -506,41 +513,50 @@
     implements(IFile, IMime, IFileContent)
     
     def __init__(self, data='', contentType=''):
-        self.contents = Mime()
-        self.contents.data = data
+        self._contents = Mime()
+        self.open(mode='w').write(data)
+        # BBB: map it to the right contentType
         self.contentType = contentType
 
-    # old compatibility methods
+    # TODO: Fix the widgets for to store the data
+    # now we get a Mime instance form the widget, but _get/_setContents 
+    # points to _contents.data
+    # We have to change this, that we can set on the contents attribute 
+    # directly a Mime instance.
+    # But how should we access the file data? Only with the open method?
+    # This whould break everything... hm, perhaps we can use the data property 
+    # for BBB and a access directly to the file data.
     def _getContents(self):
-        return self.contents.data
+        return removeSecurityProxy(self._contents.data)
 
     def _setContents(self, data):
-        self.contents.data = data
+        self._contents.data = removeSecurityProxy(data)
 
     def open(self, mode='r'):
         """return a file-like object for reading or updating the file value.
         """
         if mode == 'r':
-            return self.contents.open(mode='r')
+            return self._contents.open(mode='r')
         if mode == 'w':
-            return self.contents.open(mode='w')
+            return self._contents.open(mode='w')
         else:
             pass
             # TODO: raise wrong file open attribute error
 
     def getSize(self):
-        return self.contents.getSize()
+        return self._contents.getSize()
     
     # See IFile.
-    content = property(_getContents, _setContents)
+    contents = property(_getContents, _setContents)
+    #contents = FieldProperty(IFile['contents'])
     
     # BBB: remove it after removing BBB
     # old compatibility methods
     def _getData(self):
-        return self.contents.data
+        return self._contents
 
     def _setData(self, data):
-        self.contents.data = data
+        self._contents = data
 
     data = property(_getContents, _setContents)
 

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/interfaces.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/interfaces.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/file/interfaces.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -18,7 +18,7 @@
 __docformat__ = 'restructuredtext'
 
 from zope.schema import Bytes
-from zope.schema import Mime, MimeData, MimeDataEncoding, MimeType
+from zope.schema import MimeData, MimeDataEncoding, MimeType
 from zope.schema import Schema
 from zope.interface import Interface
 from zope.app.i18n import ZopeMessageIDFactory as _
@@ -61,7 +61,7 @@
     # TODO: remove the line below
     #encoding = BytesLine(
     encoding = MimeDataEncoding(
-        title = _(u'Encoding type'),
+        title = _(u'Encoding Type'),
         description=_(u'The encoding of the data if it is text.'),
         default='',
         required=False,
@@ -88,7 +88,26 @@
         """
 
 
+class IReadFileAccess(Interface):
+    """File read interface."""
+
+    def read():
+        """Write access on file."""
+
+    def size():
+        """Size of the file."""
+
+
+class IWriteFileAccess(Interface):
+    """File write interface."""
+
+    def write():
+        """Write access on file."""
+
+
+
 class IFile(Interface):
+    """File interface."""
 
     contents = Schema(IMime, "zope.app.file.Mime",
         title = _(u'The file data'),
@@ -99,7 +118,7 @@
         required=False,
         )
     
-    # deprectiated field
+    # BBB: remove deprectiated field
     data = Bytes(
         title=_(u'Data'),
         description=_(u'The actual content of the object.'),

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/__init__.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/__init__.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -34,7 +34,6 @@
 
 # Widgets for file-based fields
 from zope.app.form.browser.filewidgets import FileWidget
-from zope.app.form.browser.filewidgets import MimeWidget
 from zope.app.form.browser.filewidgets import MimeDataWidget
 from zope.app.form.browser.filewidgets import MimeDataEncodingWidget
 from zope.app.form.browser.filewidgets import MimeTypeWidget

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/configure.zcml	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/configure.zcml	2005-01-22 02:40:04 UTC (rev 28913)
@@ -138,20 +138,16 @@
 
   <view
       type="zope.publisher.interfaces.browser.IBrowserRequest"
-      for="zope.schema.interfaces.IMime"
-      provides="zope.app.form.interfaces.IInputWidget"
-      factory=".MimeWidget"
-      permission="zope.Public"
-      />
-
-  <view
-      type="zope.publisher.interfaces.browser.IBrowserRequest"
       for="zope.schema.interfaces.ISchema"
       provides="zope.app.form.interfaces.IInputWidget"
       factory=".SchemaWidget"
       permission="zope.Public"
       />
 
+<!-- TODO:
+     The IMime field Mime is replace by ISchema field called Schema
+     find a way where we can register special widgets for Schema fields.
+     Perhaps we have to use subdirective in editforms <widget>
   <view
       type="zope.publisher.interfaces.browser.IBrowserRequest"
       for="zope.schema.interfaces.IMime"
@@ -159,7 +155,7 @@
       factory=".MimeDisplayWidget"
       permission="zope.Public"
       />
-
+-->
   <view
       type="zope.publisher.interfaces.browser.IBrowserRequest"
       for="zope.schema.interfaces.IMimeData"

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/filewidgets.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/filewidgets.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/filewidgets.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -26,155 +26,12 @@
 from zope.app.form.browser.widget import BrowserWidget
 from zope.app.form.browser.textwidgets import BytesWidget
 from zope.app.form.browser.widget import DisplayWidget
-from zope.app.form.browser.textwidgets import escape
+from zope.app.form.browser.textwidgets import TextWidget, escape
+from zope.app.form.browser.schemawidgets import SchemaWidget
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
 
 
-# dependency
-from zope.app.file.file import Mime
-
-# used from ObjectWidget
-from zope.schema import getFieldNamesInOrder
-from zope.app.form.utility import setUpEditWidgets, applyWidgetsChanges
-
-
-
-
-class MimeWidgetView:
-
-    template = ViewPageTemplateFile('mimewidget.pt')
-    
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-        
-    def __call__(self):
-        return self.template()
-
-
-class MimeWidget(BrowserWidget, InputWidget):
-    """MimeWidget renders the subwidgets for the interface IMime.
-    
-    The widget also extracts the filename and the fileupload to the session. 
-    The subwidgets MimeDataWidget and MimeTypeWidget will access this 
-    information for storing the fileupload and the mime-type.
-    
-    For more information about widgets which render subwidgets see the 
-    ObjectWidget implementation in 
-    'zope.app.form.browser.objectwidget.ObjectWidget'.
-    """
-
-    implements(IInputWidget)
-    
-    _object = None      # the object value (from setRenderedValue & request)
-    _request_parsed = False
-
-    def __init__(self, context, request, **kw):
-        super(MimeWidget, self).__init__(context, request)
-        
-        # define view that renders the widget
-        self.view = MimeWidgetView(self, request)
-
-        # factory used to create content that this widget (field)
-        # represents
-        self.factory = Mime
-
-        # handle foo_widget specs being passed in
-        self.names = getFieldNamesInOrder(self.context.schema)
-        for k, v in kw.items():
-            if k.endswith('_widget'):
-                setattr(self, k, v)
-
-        # set up my subwidgets
-        self._setUpEditWidgets()
-
-    def setPrefix(self, prefix):
-        super(ObjectWidget, self).setPrefix(prefix)
-        self._setUpEditWidgets()
-
-    def _setUpEditWidgets(self):
-        # subwidgets need a new name
-        setUpEditWidgets(self, self.context.schema, source=self.context,
-                         prefix=self.name, names=self.names, 
-                         context=self.context)
-
-    def __call__(self):
-        return self.view()
-        
-    def legendTitle(self):
-        return self.context.title or self.context.__name__
-
-    def getSubWidget(self, name):
-        return getattr(self, '%s_widget' % name)
-            
-    def subwidgets(self):
-        return [self.getSubWidget(name) for name in self.names]
-
-    def hidden(self):
-        """Render the list as hidden fields."""
-        result = []
-        for name in self.names:
-            result.append(getSubwidget(name).hidden())
-        return "".join(result)
-
-    def getInputValue(self):
-        """Return converted and validated widget data.
-
-        The value for this field will be represented as an `ObjectStorage`
-        instance which holds the subfield values as attributes. It will
-        need to be converted by higher-level code into some more useful
-        object (note that the default EditView calls `applyChanges`, which
-        does this).
-        """
-        content = self.factory()
-        for name in self.names:
-            setattr(content, name, self.getSubWidget(name).getInputValue())
-        return content
-
-    def applyChanges(self, content):
-        field = self.context
-
-        # create our new object value
-        value = field.query(content, None)
-        if value is None:
-            # TODO: ObjectCreatedEvent here would be nice
-            value = self.factory()
-
-        # apply sub changes, see if there *are* any changes
-        # TODO: ObjectModifiedEvent here would be nice
-        changes = applyWidgetsChanges(self, field.schema, target=value,
-                                      names=self.names)
-
-        # if there's changes, then store the new value on the content
-        if changes:
-            field.set(content, value)
-
-        return changes
-
-    def hasInput(self):
-        """Is there input data for the field
-
-        Return ``True`` if there is data and ``False`` otherwise.
-        """
-        for name in self.names:
-            if self.getSubWidget(name).hasInput():
-                return True
-        return False
-
-    def setRenderedValue(self, value):
-        """Set the default data for the widget.
-
-        The given value should be used even if the user has entered
-        data.
-        """
-        # re-call setupwidgets with the content
-        self._setUpEditWidgets()
-        for name in self.names:
-            self.getSubWidget(name).setRenderedValue(getattr(value, name, None))
-            
-
-
-class MimeDataWidget(SimpleInputWidget):
+class MimeDataWidget(TextWidget):
     """MimeDataWidget extracts the fileupload information from the session.
     
     The session is initiated from the MimeWidget and contains the fileupload.
@@ -219,13 +76,22 @@
         except AttributeError, e:
             raise ConversionError('Form input is not a file object', e)
         else:
-            # if the FileUpload instance has no filename set, there is
-            # no upload.
-            if getattr(input, 'filename', ''):
-                return input
+            seek(0)
+            data = read()
+            if data or getattr(input, 'filename', ''):
+                return data
             else:
                 return self.context.missing_value
 
+#    def applyChanges(self, content):
+#        field = self.context
+#        value = self.getInputValue()
+#        if field.query(content, self) != value:
+#            field.set(content, value)
+#            return True
+#        else:
+#            return False
+
     def applyChanges(self, content):
         field = self.context
         value = self.getInputValue()
@@ -260,6 +126,10 @@
     pass
 
 
+# TODO: I replaced the Mime field (IMime) with generic field Schem (ISchema)
+# we have to find a way where we can registrer this widget for IDisplay
+# Perhaps we can use the IMime interface which is used in the Schema field
+# See zope.app.file.interfaces.IFile.contents 
 class MimeDisplayWidget(DisplayWidget):
     """Mime data display widget."""
     # There need to be probably some widget options to determine how

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/schemawidgets.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/schemawidgets.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/schemawidgets.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -28,7 +28,10 @@
 from zope.app.form.utility import setUpEditWidgets, applyWidgetsChanges
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
 
+# TODO: remove it 
+from zope.proxy import isProxy
 
+
 class SchemaWidgetView:
 
     template = ViewPageTemplateFile('schemawidget.pt')
@@ -45,13 +48,10 @@
     """A widget over an Interface that contains Fields."""
 
     implements(IInputWidget)
-    
-    _object = None      # the object value (from setRenderedValue & request)
-    _request_parsed = False
 
     def __init__(self, context, request, **kw):
         super(SchemaWidget, self).__init__(context, request)
-        
+
         # define view that renders the widget
         self.view = SchemaWidgetView(self, request)
 

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/tests/test_mimewidget.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/tests/test_mimewidget.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/form/browser/tests/test_mimewidget.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -13,29 +13,29 @@
 ##############################################################################
 """File Widget tests
 
-$Id:$
+$Id$
 """
 import unittest, doctest
 
 from StringIO import StringIO
 from zope.app.form.interfaces import IInputWidget
-from zope.app.form.browser import MimeWidget
+from zope.app.form.browser import MimeDataWidget
 
 from zope.app.form.browser.tests.test_browserwidget import SimpleInputWidgetTest
 
 from zope.interface.verify import verifyClass
 
-class MimeWidgetTest(SimpleInputWidgetTest):
+class MimeDataWidgetTest(SimpleInputWidgetTest):
     """Documents and tests the mime widget.
     
-        >>> verifyClass(IInputWidget, MimeWidget)
+        >>> verifyClass(IInputWidget, MimeDataWidget)
         True
     """
 
-    _WidgetFactory = MimeWidget
+    _WidgetFactory = MimeDataWidget
 
     def setUp(self):
-        super(MimeWidgetTest, self).setUp()
+        super(MimeDataWidgetTest, self).setUp()
         file = StringIO('Foo Value')
         file.filename = 'test.txt'
         self._widget.request.form['field.foo'] = file
@@ -65,7 +65,7 @@
 
 def test_suite():
     return unittest.TestSuite((
-        unittest.makeSuite(MimeWidgetTest),
+        unittest.makeSuite(MimeDataWidgetTest),
         doctest.DocTestSuite(),
         ))
 

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/schema/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/schema/__init__.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/schema/__init__.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -18,7 +18,7 @@
 from zope.schema._field import Field, Container, Iterable, Orderable
 from zope.schema._field import MinMaxLen, Choice
 from zope.schema._field import Bytes, ASCII, BytesLine
-from zope.schema._field import Mime, MimeData, MimeDataEncoding, MimeType
+from zope.schema._field import MimeData, MimeDataEncoding, MimeType
 from zope.schema._field import Text, TextLine, Bool, Int, Float
 from zope.schema._field import Tuple, List, Set
 from zope.schema._field import Password, Dict, Datetime, Date, SourceText

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_bootstrapfields.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_bootstrapfields.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_bootstrapfields.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -361,115 +361,3 @@
         v = int(str)
         self.validate(v)
         return v
-
-
-class MimeData(Field):
-    """Field holding a byte string (in an efficient data structure).
-
-    The type of the data is described by it's mime type.
-    """
-
-    def set(self, obj, value):
-        """
-        Do a two phase save, first create an empty file-like object, make it
-        persistent, than read the data into it in chunks, to reduce memory
-        consumption.
-
-        'value' is a file-like, most often an FileUpload() object.
-        """
-        if self.readonly:
-            raise TypeError("Can't set values on read-only fields "
-                            "(name=%s, class=%s.%s)"
-                            % (self.__name__,
-                               obj.__class__.__module__,
-                               obj.__class__.__name__))
-        # now create an empty file object and store it at the persistent object
-        setattr(obj, self.__name__, MimeData())
-        file = getattr(obj, self.__name__)
-        # now do the upload in chunks
-        file.data = value
-        # save additional information 
-        file.filename = self._extractFilename(value)
-        small_body = file.read(64)
-        file.seek(0) # XXX needed?
-        file.contentType = guess_content_type(name=file.filename, body=small_body)
-
-    def _validate(self, value):
-        # just test that there is a read method, more is not needed.
-        if getattr(value, 'read',''):
-            return
-        super(Bytes, self)._validate(value)
-
-    def _validate(self, value):
-        if self._type is not None and not isinstance(value, self._type):
-            raise WrongType(value, self._type)
-
-        if not self.constraint(value):
-            raise ConstraintNotSatisfied(value)
-
-    def _extractFilename(self, data):
-        # if it is a fileupload object
-        if hasattr(data,'filename'):
-            fid = data.filename
-            # sometimes the full pathname is included
-            fid=fid[max(fid.rfind('/'),
-                        fid.rfind('\\'), # escaped backslash
-                        fid.rfind(':'))+1:]
-            return fid
-        else:
-            return ''
-
-
-# TODO: add encodng vocabulary for selecting possible mime-types
-class MimeDataEncoding(Field):
-    """Field containing the encoding used for text-based files."""
-    implements(IFromUnicode)
-
-    _type = str
-
-    def fromUnicode(self, u):
-        """
-        >>> b = Bytes(constraint=lambda v: 'x' in v)
-
-        >>> b.fromUnicode(u" foo x.y.z bat")
-        ' foo x.y.z bat'
-        >>> b.fromUnicode(u" foo y.z bat")
-        Traceback (most recent call last):
-        ...
-        ConstraintNotSatisfied:  foo y.z bat
-
-        """
-        v = str(u)
-        self.validate(v)
-        return v
-
-    def constraint(self, value):
-        return '\n' not in value
-
-
-# TODO: perhaps add mime-type vocabulary for possible mime-types.
-# If so, we need also to list the mime-types from the python lib mimetypes
-class MimeType(Field):
-    """Field containing the mime-type for a file."""
-    implements(IFromUnicode)
-
-    _type = str
-
-    def fromUnicode(self, u):
-        """
-        >>> b = Bytes(constraint=lambda v: 'x' in v)
-
-        >>> b.fromUnicode(u" foo x.y.z bat")
-        ' foo x.y.z bat'
-        >>> b.fromUnicode(u" foo y.z bat")
-        Traceback (most recent call last):
-        ...
-        ConstraintNotSatisfied:  foo y.z bat
-
-        """
-        v = str(u)
-        self.validate(v)
-        return v
-
-    def constraint(self, value):
-        return '\n' not in value

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_field.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_field.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/schema/_field.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -29,7 +29,7 @@
 from zope.schema.interfaces import ISourceText
 from zope.schema.interfaces import IInterfaceField
 from zope.schema.interfaces import IBytes, IASCII, IBytesLine
-from zope.schema.interfaces import IMime, IMimeData, IMimeDataEncoding, IMimeType
+from zope.schema.interfaces import IMimeData, IMimeDataEncoding, IMimeType
 from zope.schema.interfaces import IBool, IInt, IFloat, IDatetime
 from zope.schema.interfaces import IChoice, ITuple, IList, ISet, IDict
 from zope.schema.interfaces import IPassword, IObject, IDate
@@ -45,10 +45,8 @@
 from zope.schema.interfaces import Unbound
 
 from zope.schema._bootstrapfields import Field, Container, Iterable, Orderable
-from zope.schema._bootstrapfields import MinMaxLen
 from zope.schema._bootstrapfields import Text, TextLine, Bool, Int, Password
 from zope.schema._bootstrapfields import MinMaxLen, ValidatedProperty
-from zope.schema._bootstrapfields import MimeData, MimeDataEncoding, MimeType
 from zope.schema.fieldproperty import FieldProperty
 from zope.schema.vocabulary import getVocabularyRegistry
 from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
@@ -69,9 +67,6 @@
 classImplements(Password, IPassword)
 classImplements(Bool, IBool)
 classImplements(Int, IInt)
-classImplements(MimeData, IMimeData)
-classImplements(MimeDataEncoding, IMimeDataEncoding)
-classImplements(MimeType, IMimeType)
 
 
 class SourceText(Text):
@@ -103,29 +98,6 @@
         return v
 
 
-class Mime(Field):
-    __doc__ = IMime.__doc__
-    implements(IMime)
-
-    # TODO: this is just a copy paste form Object field below
-    def __init__(self, **kw):
-            
-        self.schema = IMime
-        super(Mime, self).__init__(**kw)
-        
-    def _validate(self, value):
-        super(Mime, self)._validate(value)
-        
-        # schema has to be provided by value
-        if not self.schema.providedBy(value):
-            raise SchemaNotProvided
-            
-        # check the value against schema
-        errors = _validate_fields(self.schema, value)
-        if errors:
-            raise WrongContainedType(errors)
-
-
 class ASCII(Bytes):
     __doc__ = IASCII.__doc__
     implements(IASCII)
@@ -167,6 +139,159 @@
         return '\n' not in value
 
 
+class MimeData(Field):
+    """Field holding a byte string (in an efficient data structure).
+
+    The type of the data is described by it's mime type.
+    """
+
+    implements(IMimeData)
+
+    _type = None #prevent for validation in super class
+
+    def fromUnicode(self, u):
+        """
+        >>> b = Bytes(constraint=lambda v: 'x' in v)
+
+        >>> b.fromUnicode(u" foo x.y.z bat")
+        ' foo x.y.z bat'
+        >>> b.fromUnicode(u" foo y.z bat")
+        Traceback (most recent call last):
+        ...
+        ConstraintNotSatisfied:  foo y.z bat
+
+        """
+        v = str(u)
+        self.validate(v)
+        return v
+
+    def _validate(self, value):
+        """Test constraint."""
+        if getattr(value, 'read',''):
+            return True
+
+    def set(self, object, value):
+        if self.readonly:
+            raise TypeError("Can't set values on read-only fields "
+                            "(name=%s, class=%s.%s)"
+                            % (self.__name__,
+                               object.__class__.__module__,
+                               object.__class__.__name__))
+        setattr(object, self.__name__, value)
+
+# we shouldn't do that in a field, we normaly don't know other fieldnames
+# like contentType. That's the part of the MimeType field/widget
+
+#    def set(self, obj, value):
+#        """
+#        Do a two phase save, first create an empty file-like object, make it
+#        persistent, than read the data into it in chunks, to reduce memory
+#        consumption.
+#
+#        'value' is a file-like, most often an FileUpload() object.
+#        """
+#        print ""
+#        print "MimeData set"
+#        print "obj ", obj
+#        print "value ", value
+#        if self.readonly:
+#            raise TypeError("Can't set values on read-only fields "
+#                            "(name=%s, class=%s.%s)"
+#                            % (self.__name__,
+#                               obj.__class__.__module__,
+#                               obj.__class__.__name__))
+#        # now create an empty file object and store it at the persistent object
+#        setattr(obj, self.__name__, MimeData())
+#        file = getattr(obj, self.__name__)
+#        # now do the upload in chunks
+#        file.data = value
+#        # save additional information 
+#        file.filename = self._extractFilename(value)
+#        small_body = file.read(64)
+#        file.seek(0) # XXX needed?
+#        file.contentType = guess_content_type(name=file.filename, body=small_body)
+#
+#    def _validate(self, value):
+#        # just test that there is a read method, more is not needed.
+#        if getattr(value, 'read',''):
+#            return
+#        super(Bytes, self)._validate(value)
+#
+#    def _validate(self, value):
+#        if self._type is not None and not isinstance(value, self._type):
+#            raise WrongType(value, self._type)
+#
+#        if not self.constraint(value):
+#            raise ConstraintNotSatisfied(value)
+#
+#    def _extractFilename(self, data):
+#        # if it is a fileupload object
+#        if hasattr(data,'filename'):
+#            fid = data.filename
+#            # sometimes the full pathname is included
+#            fid=fid[max(fid.rfind('/'),
+#                        fid.rfind('\\'), # escaped backslash
+#                        fid.rfind(':'))+1:]
+#            return fid
+#        else:
+#            return ''
+
+
+# TODO: add encodng vocabulary for selecting possible mime-types
+class MimeDataEncoding(Field):
+    """Field containing the encoding used for text-based files."""
+    implements(IMimeDataEncoding, IFromUnicode)
+
+    _type = str
+
+    def fromUnicode(self, u):
+        """
+        >>> b = Bytes(constraint=lambda v: 'x' in v)
+
+        >>> b.fromUnicode(u" foo x.y.z bat")
+        ' foo x.y.z bat'
+        >>> b.fromUnicode(u" foo y.z bat")
+        Traceback (most recent call last):
+        ...
+        ConstraintNotSatisfied:  foo y.z bat
+
+        """
+        v = str(u)
+        self.validate(v)
+        return v
+
+    def constraint(self, value):
+        return '\n' not in value
+
+
+# TODO: perhaps add mime-type vocabulary for possible mime-types.
+# If so, we need also to list the mime-types from the python lib mimetypes
+class MimeType(Field):
+    """Field containing the mime-type for a file."""
+    implements(IMimeType, IFromUnicode)
+
+    _type = str
+
+    def fromUnicode(self, u):
+        """
+        >>> b = Bytes(constraint=lambda v: 'x' in v)
+
+        >>> b.fromUnicode(u" foo x.y.z bat")
+        ' foo x.y.z bat'
+        >>> b.fromUnicode(u" foo y.z bat")
+        Traceback (most recent call last):
+        ...
+        ConstraintNotSatisfied:  foo y.z bat
+
+        """
+        v = str(u)
+        self.validate(v)
+        return v
+
+    def constraint(self, value):
+        return '\n' not in value
+
+
 class Float(Orderable, Field):
     __doc__ = IFloat.__doc__
     implements(IFloat, IFromUnicode)
@@ -449,6 +574,7 @@
     __doc__ = ISchema.__doc__
     implements(ISchema)
 
+    _type = None
     schema = None
     factoryId = None
 
@@ -461,16 +587,9 @@
         super(Schema, self).__init__(**kw)
         
     def _validate(self, value):
-        super(Schema, self)._validate(value)
-        
         # schema has to be provided by value
         if not self.schema.providedBy(value):
             raise SchemaNotProvided
-            
-        # check the value against schema
-        errors = _validate_fields(self.schema, value)
-        if errors:
-            raise WrongContainedType(errors)
 
 
 class Dict(MinMaxLen, Iterable, Field):

Modified: Zope3/branches/jhauser-filefieldwidget/src/zope/schema/interfaces.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/schema/interfaces.py	2005-01-21 22:22:52 UTC (rev 28912)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/schema/interfaces.py	2005-01-22 02:40:04 UTC (rev 28913)
@@ -19,7 +19,6 @@
 from zope.interface import Interface, Attribute
 from zope.schema._bootstrapfields import Field, Text, TextLine, Bool, Int
 from zope.schema._bootstrapfields import Container, Iterable
-from zope.schema._bootstrapfields import MimeData, MimeDataEncoding, MimeType
 
 from zope.i18nmessageid import MessageIDFactory
 _ = MessageIDFactory("zope")
@@ -274,52 +273,6 @@
 
     The value might be constrained to be with length limits.
     """
-
-
-
-# TODO: perhaps we should use TextLine for prevent inheriting IMinMaxLen
-class IMimeData(IBytes):
-    u"""Field holding a byte string (in an efficient data structure).
-
-    The type of the data is described by it's mime type.
-    """
-
-# TODO: perhaps we should use TextLine for prevent inheriting IMinMaxLen
-class IMimeDataEncoding(IBytes):
-    u"""Field containing the encoding used for text-based files."""
-
-# TODO: perhaps we should use TextLine for prevent inheriting IMinMaxLen
-class IMimeType(IBytes):
-    u"""Field containing the mime-type for a file."""
-
-class IMime(IField):
-    u"""Field describing the subwidgets of IMime used in IFile."""
-
-    contentType = MimeType(
-        title = _(u'Content type'),
-        description=_(u'The content type identifies the type of data.'),
-        default='',
-        required=False,
-        missing_value=''
-        )
-
-    encoding = MimeDataEncoding(
-        title = _(u'Encoding type'),
-        description=_(u'The encoding of the data if it is text.'),
-        default='',
-        required=False,
-        missing_value=''
-        )
-
-    data = MimeData (
-        title=_(u'Data'),
-        description=_(u'The actual content of the file.'),
-        default='',
-        missing_value='',
-        required=False,
-        )
-
-
     
 class IASCII(IBytes):
     u"""Field containing a 7-bit ASCII string. No characters > DEL
@@ -486,6 +439,21 @@
         required=False,
         default=None)
 
+# TODO: perhaps we should use TextLine for prevent inheriting IMinMaxLen
+class IMimeData(IBytes):
+    u"""Field holding a byte string (in an efficient data structure).
+
+    The type of the data is described by it's mime type.
+    """
+
+# TODO: perhaps we should use TextLine for prevent inheriting IMinMaxLen
+class IMimeDataEncoding(IBytes):
+    u"""Field containing the encoding used for text-based files."""
+
+# TODO: perhaps we should use TextLine for prevent inheriting IMinMaxLen
+class IMimeType(IBytes):
+    u"""Field containing the mime-type for a file."""
+
 class IDict(IMinMaxLen, IIterable, IContainer):
     u"""Field containing a conventional dict.
 



More information about the Zope3-Checkins mailing list