[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/file/mimefield.py Instead of reimplementing File let's depend on it. We can build another FileContent object, which uses the schema field.

Janko Hauser jhauser at zscout.de
Sun Jan 16 07:24:14 EST 2005


Log message for revision 28846:
  Instead of reimplementing File let's depend on it. We can build another FileContent object, which uses the schema field.
  

Changed:
  U   Zope3/trunk/src/zope/app/file/mimefield.py

-=-
Modified: Zope3/trunk/src/zope/app/file/mimefield.py
===================================================================
--- Zope3/trunk/src/zope/app/file/mimefield.py	2005-01-15 22:59:33 UTC (rev 28845)
+++ Zope3/trunk/src/zope/app/file/mimefield.py	2005-01-16 12:24:14 UTC (rev 28846)
@@ -21,27 +21,22 @@
 from transaction import get_transaction
 from zope.interface import implements
 
-from zope.schema.interfaces import IField,IBytesLine
+from zope.schema.interfaces import IBytesLine
 from zope.schema._bootstrapfields import Field
-from zope.schema._bootstrapfields import TextLine, Int
+from zope.schema._bootstrapfields import TextLine
 
-from zope.publisher.browser import FileUpload
-from zope.app.file.file import FileChunk
 from interfaces import IFile
 
-# set the size of the chunks
-MAXCHUNKSIZE = 1 << 16
-
 #
 # The basic schema interface
 #
-class IMime(IField, IBytesLine):
+class IMime(IBytesLine):
     u"""Fields which hold data characterized by a mime type.
 
     The data is stored memory effecient.
     """
 
-    mimetype = TextLine(title=_(u"Mime type"),
+    contentType = TextLine(title=_(u"Mime type"),
                         description=_(u"The mime type of the stored data")
                         required=False,
                         default=u"application/octet-stream"
@@ -59,7 +54,7 @@
 
     
  # The field implementation                       
-class FileData(BytesLine):
+class FileData(BytesLine, File):
     """A field implementation for uploaded files. 
 
     Let's test the constructor:
@@ -151,42 +146,17 @@
 
     implements(IFileData, IFile)
 
-    # reimplementing the old file class, which stores data in a chunked
-    # data structure. As we inherit from BytesLine we are an 'Attribute'.
     def __init__(self, data='', contentType=''):
         self.data = data
-        # do we need to support self.contentType for IFile?
-        self.mimeType = contentType
+        # instead of mimeType we use contentType as it is mandated by IFile
+        self.contentType = contentType
+        self.filename = self._extractFilename(data)
 
-    def _getData(self):
-        if isinstance(self._data, FileChunk):
-            return str(self._data)
-        else:
-            return self._data
+    def _setdata(self, data):
+        File._setdata(data)
+        self.filename = self._extractFilename(data)
 
-    def _setData(self, data):
-        # Handle case when data is a string
-        if isinstance(data, unicode):
-            data = data.encode('UTF-8')
-
-        if isinstance(data, str):
-            self._data, self._size = FileChunk(data), len(data)
-            return
-
-        # Handle case when data is None
-        if data is None:
-            raise TypeError('Cannot set None data on a file.')
-
-        # Handle case when data is already a FileChunk
-        if isinstance(data, FileChunk):
-            size = len(data)
-            self._data, self._size = data, size
-            return
-
-        # Handle case when data is a file object.
-        seek = data.seek
-        read = data.read
-
+    def _extractFilename(self, data):
         # if it is a fileupload object
         if hasattr(data,'filename'):
             fid = data.filename
@@ -195,71 +165,7 @@
                         fid.rfind('\\'),
                         fid.rfind(':')
                               )+1:]
-            self.filename = fid
+            return fid
         else:
-            self.filename = ''
-        
-        seek(0, 2)
-        size = end = data.tell()
+            return ''
 
-        if size <= 2*MAXCHUNKSIZE:
-            seek(0)
-            if size < MAXCHUNKSIZE:
-                self._data, self._size = read(size), size
-                return
-            self._data, self._size = FileChunk(read(size)), size
-            return
-
-        # Make sure we have an _p_jar, even if we are a new object, by
-        # doing a sub-transaction commit.
-        get_transaction().commit(1)
-
-        jar = self._p_jar
-
-        if jar is None:
-            # Ugh
-            seek(0)
-            self._data, self._size = FileChunk(read(size)), size
-            return
-
-        # Now we're going to build a linked list from back
-        # to front to minimize the number of database updates
-        # and to allow us to get things out of memory as soon as
-        # possible.
-        next = None
-        while end > 0:
-            pos = end - MAXCHUNKSIZE
-            if pos < MAXCHUNKSIZE:
-                pos = 0 # we always want at least MAXCHUNKSIZE bytes
-            seek(pos)
-            data = FileChunk(read(end - pos))
-
-            # Woooop Woooop Woooop! This is a trick.
-            # We stuff the data directly into our jar to reduce the
-            # number of updates necessary.
-            jar.add(data)
-
-            # This is needed and has side benefit of getting
-            # the thing registered:
-            data.next = next
-
-            # Now make it get saved in a sub-transaction!
-            get_transaction().commit(1)
-
-            # Now make it a ghost to free the memory.  We
-            # don't need it anymore!
-            data._p_changed = None
-
-            next = data
-            end = pos
-
-        self._data, self._size = next, size
-        return
-
-    def getSize(self):
-        '''See `IFile`'''
-        return self._size
-
-    # See IFile.
-    data = property(_getData, _setData)
-    



More information about the Zope3-Checkins mailing list