[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