[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/File - File.py:1.1.2.1 FileChunk.py:1.1.2.1 FileEdit.py:1.1.2.1 IFile.py:1.1.2.1 NaiveFile.py:1.1.2.2 NaiveFileEdit.py:NONE
Stephan Richter
srichter@cbu.edu
Mon, 21 Jan 2002 12:42:07 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/File
In directory cvs.zope.org:/tmp/cvs-serv22486/File
Modified Files:
Tag: Zope-3x-branch
NaiveFile.py
Added Files:
Tag: Zope-3x-branch
File.py FileChunk.py FileEdit.py IFile.py
Removed Files:
Tag: Zope-3x-branch
NaiveFileEdit.py
Log Message:
NaiveFile and File:
- I fixed the Interface to also return the size of the file
- Implemented a real file that saves data chunks a la Zope 2
- Cleaned up the API, so that both NaiveFile and File can use the same
views, which I think is what Zope 3 is all about.
- TODO: Support File upload from the Web.
Image:
- Cleaned up API and methods
- renamed Interface method getSize() to getImageSize()
- Image now inherits File instead of NaiveFile
=== Added File Zope3/lib/python/Zope/App/OFS/File/File.py ===
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
import Persistence
from types import StringType, NoneType
from FileChunk import FileChunk
from IFile import IFile
from Zope.App.Security.IAttributeRolePermissionManageable \
import IAttributeRolePermissionManageable
# set the size of the chunks
MAXCHUNKSIZE = 1 << 16
class File(Persistence.Persistent):
""" """
__implements__ = IFile
def __init__(self, data=None, contentType=None):
""" """
self.setData(data)
if contentType is None:
self._contentType = ''
else:
self._contentType = contentType
def __str__(self):
return self.getData()
def __len__(self):
return 1
############################################################
# Implementation methods for interface
# Zope.App.OFS.IFile.IFile
def setContentType(self, contentType):
'''See interface IFile'''
self._contentType = contentType
def getContentType(self):
'''See interface IFile'''
return self._contentType
def edit(self, data, contentType=None):
'''See interface IFile'''
self.setData(data)
if contentType is not None:
self._contentType = contentType
def getData(self):
'''See interface IFile'''
if hasattr(self._data, '__class__') and self._data.__class__ is FileChunk:
return str(self._data)
else:
return self._data
def setData(self, data):
'''See interface IFile'''
# Handle case when data is a string
if type(data) is StringType:
size = len(data)
if size < MAXCHUNKSIZE:
self._data, self._size = FileChunk(data), size
return None
self._data, self._size = FileChunk(data), size
return None
# Handle case when data is a string
if type(data) is NoneType:
self._data, self._size = None, 0
return None
# Handle case when data is already a FileChunk
if hasattr(data, '__class__') and data.__class__ is FileChunk:
size = len(data)
self._data, self._size = data, size
return None
# Handle case when File is a file object
seek = data.seek
read = data.read
seek(0, 2)
size = end = data.tell()
if size <= 2*MAXCHUNKSIZE:
seek(0)
if size < n:
self._data, self._size = read(size), size
return None
self._data, self._size = FileChunk(read(size)), size
return None
# 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 None
# 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.
data._p_jar = jar
# 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 None
def getSize(self):
'''See interface IFile'''
return self._size
#
############################################################
=== Added File Zope3/lib/python/Zope/App/OFS/File/FileChunk.py ===
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
import Persistence
class FileChunk(Persistence.Persistent):
# Wrapper for possibly large data
next = None
def __init__(self, data):
self._data = data
def __getslice__(self, i, j):
return self._data[i:j]
def __len__(self):
data = str(self)
return len(data)
def __str__(self):
next = self.next
if next is None:
return self._data
result = [self.data]
while next is not None:
self = next
r.append(self._data)
next = self.next
return ''.join(r)
=== Added File Zope3/lib/python/Zope/App/OFS/File/FileEdit.py ===
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
"""
Define view component for naive file editing.
"""
import os
from Zope.Publisher.Browser.AttributePublisher import AttributePublisher
from Zope.PageTemplate.PageTemplateFile import PageTemplateFile
class FileEdit( AttributePublisher ):
__implements__ = AttributePublisher.__implements__
def __init__( self, file ):
self._file = file
def edit(self, data, contentType, REQUEST=None):
file = self.getContext()
file.edit(data, contentType)
if REQUEST is not None:
return self.index(REQUEST, msg='File Edited.')
def getContext( self ):
return self._file
index = PageTemplateFile('edit.pt')
=== Added File Zope3/lib/python/Zope/App/OFS/File/IFile.py ===
# This software is subject to the provisions of the Zope Public License,
# Version 1.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
from Interface import Interface
class IFile(Interface):
"""This interface describes the basic methods that are required to implement
a file as a Zope Content object.
"""
def edit(data, contentType=None):
"""Sets the data and the content type for the object.
Since some implementations will provide their content type through the
data, it is good to leave the argument optional.
"""
def setData(data):
"""Sets ONLY the data without changing the content type."""
def getData():
"""Returns the bits (data) of the File itself."""
def setContentType(contentType):
"""Sets the content type of the file."""
def getContentType():
"""Returns the content type of the file using mime-types syntax."""
def getSize():
"""Return the size of the file.
Note that only the file's content is counted and not the entire
Python object.
"""
=== Zope3/lib/python/Zope/App/OFS/File/NaiveFile.py 1.1.2.1 => 1.1.2.2 ===
import Persistence
-from Interface import Interface
+from IFile import IFile
from Zope.App.Security.IAttributeRolePermissionManageable \
import IAttributeRolePermissionManageable
-class INaiveFile(Interface):
- """This is a simple implementation of a File in Zope.
-
- Warning: You should not use this interface to implement large data
- files.
- """
-
- def edit(data, contentType=None):
- """Sets the data and the content type for the object.
-
- Since some implementations will provide their content type through the
- data, it is good to leave the argument optional.
- """
-
-
- def setData(data):
- """Sets ONLY the data without changing the content type."""
-
-
- def getData():
- """Returns the bits (data) of the File itself."""
-
-
- def setContentType(contentType):
- """Sets the content type of the file."""
-
-
- def getContentType():
- """Returns the content type of the file using mime-types syntax."""
-
-
-
_RAISE_KEYERROR = []
-class NaiveFile(Persistence.Persistent):
- """ """
+class NaiveFile:
+ """This is a very simple implementation of a file.
+
+ WARNING: This implementation should not be used to save large amounts
+ of Data.
+ """
- __implements__ = INaiveFile
+ __implements__ = IFile
def __init__(self, data=None, contentType=None):
""" """
- self._data = data
+ self.setData(data)
if contentType is None:
self._contentType = ''
else:
self._contentType = contentType
+
+
+ def __str__(self):
+ return self.getData()
+
+
+ def __len__(self):
+ return 1
############################################################
# Implementation methods for interface
- # Zope.App.OFS.NaiveFile.INaiveFile
+ # Zope.App.OFS.File.IFile
def setContentType(self, contentType):
- '''See interface INaiveFile'''
+ '''See interface IFile'''
self._contentType = contentType
def getContentType(self):
- '''See interface INaiveFile'''
+ '''See interface IFile'''
return self._contentType
def edit(self, data, contentType=None):
- '''See interface INaiveFile'''
+ '''See interface IFile'''
self._data = data
if contentType is not None:
self._contentType = contentType
def getData(self):
- '''See interface INaiveFile'''
+ '''See interface IFile'''
return self._data
def setData(self, data):
- '''See interface INaiveFile'''
+ '''See interface IFile'''
+ if data is not None:
+ self._size = len(data)
+ else:
+ self._size = 0
self._data = data
+
+
+ def getSize(self):
+ '''See interface IFile'''
+ return self._size
#
############################################################
=== Removed File Zope3/lib/python/Zope/App/OFS/File/NaiveFileEdit.py ===