[Checkins] SVN: z3c.blobfile/trunk/src/z3c/blobfile/file.py -
delegate blob optimizations to IConsumables
Grégoire Weber
zope.org at incept.ch
Sun Nov 11 09:26:44 EST 2007
Log message for revision 81755:
- delegate blob optimizations to IConsumables
Changed:
U z3c.blobfile/trunk/src/z3c/blobfile/file.py
-=-
Modified: z3c.blobfile/trunk/src/z3c/blobfile/file.py
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/file.py 2007-11-11 13:43:49 UTC (rev 81754)
+++ z3c.blobfile/trunk/src/z3c/blobfile/file.py 2007-11-11 14:26:44 UTC (rev 81755)
@@ -20,12 +20,15 @@
from persistent import Persistent
import transaction
from zope.interface import implements
+from zope.component import getUtilitiesFor
import zope.app.publication.interfaces
-from zope.app.file import interfaces
+import zope.app.file.interfaces
from zope.app.file.file import FileChunk
from ZODB.blob import Blob
+import interfaces
+
# set the size of the chunks
MAXCHUNKSIZE = 1 << 16
@@ -113,13 +116,14 @@
Last, but not least, verify the interface:
>>> from zope.interface.verify import verifyClass
- >>> interfaces.IFile.implementedBy(File)
+ >>> zope.app.file.interfaces.IFile.implementedBy(File)
True
- >>> verifyClass(interfaces.IFile, File)
+ >>> verifyClass(zope.app.file.interfaces.IFile, File)
True
"""
- implements(zope.app.publication.interfaces.IFileContent, interfaces.IFile)
+ implements(zope.app.publication.interfaces.IFileContent,
+ zope.app.file.interfaces.IFile)
size = 0
@@ -134,7 +138,25 @@
return self._data.open(mode)
def _setData(self, data):
- # Handle case when data is a string
+ # Check first if there is a supplier that may deduce a file name
+ # from the data passed. In such case `consumeFile` from ZODB's
+ # blob support may be used which is very efficient.
+ consumables = [(c[0], c[1](data))
+ for c in getUtilitiesFor(interfaces.IConsumable)]
+ consumables = [(n, fn) for n, fn in consumable if fn is not None]
+
+ # if more than one supplier may return a consumable file name
+ # there is no chance to deduce which to use.
+ if len(consumables) > 1:
+ names = "', '".join([n for n in consumables[0]])
+ raise AmbiguousConsumables("%s `IConsumables` (registered "
+ "under '%s') supplied a file name. Please deregister "
+ "all except one of them." % (len(consumables), names))
+ elif len(consumables) == 1:
+ self._data.consumeFile(consumables[0][1])
+ return
+
+ # Handle case when data is a string but not a consumable
if isinstance(data, unicode):
data = data.encode('UTF-8')
@@ -147,7 +169,6 @@
raise TypeError('Cannot set None data on a file.')
# Handle case when data is already a FileChunk
-
if isinstance(data, FileChunk):
fp = self._data.open('w')
chunk = data
More information about the Checkins
mailing list