[Checkins] SVN: zope.file/branches/ajung-blobs/src/zope/file/
integrated blob support
Andreas Jung
andreas at andreas-jung.com
Mon Feb 26 13:20:19 EST 2007
Log message for revision 72831:
integrated blob support
Changed:
U zope.file/branches/ajung-blobs/src/zope/file/configure.zcml
U zope.file/branches/ajung-blobs/src/zope/file/download.py
U zope.file/branches/ajung-blobs/src/zope/file/file.py
-=-
Modified: zope.file/branches/ajung-blobs/src/zope/file/configure.zcml
===================================================================
--- zope.file/branches/ajung-blobs/src/zope/file/configure.zcml 2007-02-26 18:09:37 UTC (rev 72830)
+++ zope.file/branches/ajung-blobs/src/zope/file/configure.zcml 2007-02-26 18:20:18 UTC (rev 72831)
@@ -14,6 +14,10 @@
permission="zope.ManageContent"
set_attributes="mimeType parameters"
/>
+ <require
+ permission="zope.ManageContent"
+ attributes="openDetached"
+ />
<implements
interface="
zope.annotation.interfaces.IAttributeAnnotatable
@@ -25,23 +29,14 @@
<adapter factory=".adapters.ReadFileAdapter" />
<adapter factory=".adapters.WriteFileAdapter" />
- <!-- set up permissions for the accessor objects -->
-
- <class class=".file.Reader">
+ <class class="ZODB.Blobs.Blob.BlobFile">
<require
permission="zope.View"
- interface=".interfaces.IFileReader"
+ attributes="read openDetached"
/>
- </class>
-
- <class class=".file.Writer">
<require
- permission="zope.View"
- attributes="mode"
- />
- <require
permission="zope.ManageContent"
- attributes="close flush write"
+ attributes="write close"
/>
</class>
Modified: zope.file/branches/ajung-blobs/src/zope/file/download.py
===================================================================
--- zope.file/branches/ajung-blobs/src/zope/file/download.py 2007-02-26 18:09:37 UTC (rev 72830)
+++ zope.file/branches/ajung-blobs/src/zope/file/download.py 2007-02-26 18:20:18 UTC (rev 72831)
@@ -21,6 +21,7 @@
import zope.mimetype.interfaces
import zope.publisher.browser
import zope.publisher.http
+from zope.proxy import removeAllProxies
class Download(zope.publisher.browser.BrowserView):
@@ -48,13 +49,7 @@
zope.publisher.http.IResult)
def getFile(self, context):
- # This ensures that what's left has no connection to the
- # application/database; ZODB BLOBs will provide a equivalent
- # feature once available.
- f = context.open('rb')
- res = cStringIO.StringIO(f.read())
- f.close()
- return res
+ return removeAllProxies(context.openDetached())
def __init__(self, context, contentType=None, downloadName=None,
contentDisposition=None, contentLength=None):
Modified: zope.file/branches/ajung-blobs/src/zope/file/file.py
===================================================================
--- zope.file/branches/ajung-blobs/src/zope/file/file.py 2007-02-26 18:09:37 UTC (rev 72830)
+++ zope.file/branches/ajung-blobs/src/zope/file/file.py 2007-02-26 18:20:18 UTC (rev 72831)
@@ -22,6 +22,7 @@
import zope.location.interfaces
import zope.file.interfaces
import zope.interface
+from ZODB.Blobs.Blob import Blob
class File(persistent.Persistent):
@@ -34,9 +35,6 @@
__parent__ = None
mimeType = None
- _data = ""
- size = 0
-
def __init__(self, mimeType=None, parameters=None):
self.mimeType = mimeType
if parameters is None:
@@ -44,132 +42,21 @@
else:
parameters = dict(parameters)
self.parameters = parameters
+ self._data = Blob()
def open(self, mode="r"):
- if mode in ("r", "rb"):
- return Reader(self, mode)
- if mode in ("w", "wb"):
- return Writer(self, mode)
- if mode in ("r+", "r+b", "rb+"):
- return ReaderPlus(self, mode)
- if mode in ("w+", "w+b", "wb+"):
- return WriterPlus(self, mode)
- raise ValueError("unsupported `mode` value")
+ return self._data.open(mode)
+ def openDetached(self):
+ return self._data.openDetached()
-class Accessor(object):
- """Base class for the reader and writer."""
- _closed = False
- _sio = None
+ @property
+ def size(self):
+ fp = self._data.open()
+ fp.seek(0, 2)
+ size = fp.tell()
+ fp.close()
+ return size
+
- # XXX Accessor objects need to have an __parent__ to support the
- # security machinery, but they aren't ILocation instances since
- # they aren't addressable via URL.
- #
- # There needs to be an interface for this in Zope 3, but that's a
- # large task since it affects lots of Z3 code. __parent__ should
- # be defined by an interface from which ILocation is derived.
-
- def __init__(self, file, mode):
- self.__parent__ = file
- self.mode = mode
-
- def close(self):
- if not self._closed:
- self._close()
- self._closed = True
- if "_sio" in self.__dict__:
- del self._sio
-
- def __getstate__(self):
- """Make sure the accessors can't be stored in ZODB."""
- cls = self.__class__
- raise TypeError("%s.%s instance is not picklable"
- % (cls.__module__, cls.__name__))
-
- _write = False
-
- def _get_stream(self):
- # get the right string io
- if self._sio is None:
- self._data = self.__parent__._data
- # create if we don't have one yet
- self._sio = cStringIO.StringIO() # cStringIO creates immutable
- # instance if you pass a string, unlike StringIO :-/
- if not self._write:
- self._sio.write(self._data)
- self._sio.seek(0)
- elif self._data is not self.__parent__._data:
- # if the data for the underlying object has changed,
- # update our view of the data:
- pos = self._sio.tell()
- self._data = self.__parent__._data
- self._sio = cStringIO.StringIO()
- self._sio.write(self._data)
- self._sio.seek(pos) # this may seek beyond EOF, but that appears to
- # be how it is supposed to work, based on experiments. Writing
- # will insert NULLs in the previous positions.
- return self._sio
-
- def _close(self):
- pass
-
-
-class Reader(Accessor):
-
- zope.interface.implements(
- zope.file.interfaces.IFileReader)
-
- _data = File._data
-
- def read(self, size=-1):
- if self._closed:
- raise ValueError("I/O operation on closed file")
- return self._get_stream().read(size)
-
- def seek(self, offset, whence=0):
- if self._closed:
- raise ValueError("I/O operation on closed file")
- if whence not in (0, 1, 2):
- raise ValueError("illegal value for `whence`")
- self._get_stream().seek(offset, whence)
-
- def tell(self):
- if self._closed:
- raise ValueError("I/O operation on closed file")
- if self._sio is None:
- return 0L
- else:
- return self._sio.tell()
-
-
-class Writer(Accessor):
-
- zope.interface.implements(
- zope.file.interfaces.IFileWriter)
-
- _write = True
-
- def flush(self):
- if self._closed:
- raise ValueError("I/O operation on closed file")
- if self._sio is not None:
- self.__parent__._data = self._sio.getvalue()
- self.__parent__.size = len(self.__parent__._data)
- self._data = self.__parent__._data
-
- def write(self, data):
- if self._closed:
- raise ValueError("I/O operation on closed file")
- self._get_stream().write(data)
-
- def _close(self):
- self.flush()
-
-class WriterPlus(Writer, Reader):
- pass
-
-class ReaderPlus(Writer, Reader):
-
- _write = False
More information about the Checkins
mailing list