[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Content/File - File.py:1.1.2.1 FileChunk.py:1.1.2.1 FileEdit.py:1.1.2.1 FileFields.py:1.1.2.1 IFile.py:1.1.2.1 NaiveFile.py:1.1.2.1 __init__.py:1.1.2.1 edit.pt:1.1.2.1 file.zcml:1.1.2.1
Stephan Richter
srichter@cbu.edu
Wed, 27 Mar 2002 10:54:36 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Content/File
In directory cvs.zope.org:/tmp/cvs-serv12282/Content/File
Added Files:
Tag: Zope-3x-branch
File.py FileChunk.py FileEdit.py FileFields.py IFile.py
NaiveFile.py __init__.py edit.pt file.zcml
Log Message:
New Content Objects:
- NaiveFile --> all the data is stored in one string
- File --> Uses a BTree to store the data in chunks (more efficient)
- Image --> Can store and display an image a la Z2 (based on File)
- ZPTPage --> A simple version of ZPT for the content space to allow some
dynamics data (please do not use this for scripting)
Also:
- Expansion of supported views
- all edit screens are Formulator supported
=== Added File Zope3/lib/python/Zope/App/OFS/Content/File/File.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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
#
##############################################################################
"""
$Id: File.py,v 1.1.2.1 2002/03/27 15:54:35 srichter Exp $
"""
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,
IAttributeRolePermissionManageable,
)
def __init__(self, data=None, contentType=None):
""" """
self.setData(data)
if contentType is None:
self._contentType = ''
else:
self._contentType = contentType
def __len__(self):
return self.getSize()
############################################################
# 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 isinstance(data, 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 isinstance(data, 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/Content/File/FileChunk.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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
#
##############################################################################
"""
$Id: FileChunk.py,v 1.1.2.1 2002/03/27 15:54:35 srichter Exp $
"""
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/Content/File/FileEdit.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
"""
from Zope.App.Formulator.Form import Form
from Zope.PageTemplate.PageTemplateFile import PageTemplateFile
class FileEdit(Form):
__implements__ = Form.__implements__
name = 'editForm'
title = 'Edit Form'
description = ('This edit form allows you to make changes to the ' +
'properties of this file.')
_fieldViewNames = ['ContentTypeFieldView', 'DataFieldView']
template = PageTemplateFile('edit.pt')
=== Added File Zope3/lib/python/Zope/App/OFS/Content/File/FileFields.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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
#
##############################################################################
"""
$Id: FileFields.py,v 1.1.2.1 2002/03/27 15:54:35 srichter Exp $
"""
from Zope.App.Formulator.FieldRegistry import getField
from Zope.App.Formulator.ValidatorRegistry import getValidator
ContentTypeField = getField('StringField')(
id = 'contentType',
title = 'Content Type',
description = 'The content type identifies the type of data.',
default = 'text/plain',
)
DataField = getField('FileField')(
id = 'data',
title = 'Data',
description = 'The actual content of the object.',
)
=== Added File Zope3/lib/python/Zope/App/OFS/Content/File/IFile.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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
#
##############################################################################
"""
$Id: IFile.py,v 1.1.2.1 2002/03/27 15:54:35 srichter Exp $
"""
from Interface import Interface
class IFile(Interface):
"""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.
"""
=== Added File Zope3/lib/python/Zope/App/OFS/Content/File/NaiveFile.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# 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.
##############################################################################
"""
$Id: NaiveFile.py,v 1.1.2.1 2002/03/27 15:54:35 srichter Exp $
"""
import Persistence
from IFile import IFile
from Zope.App.Security.IAttributeRolePermissionManageable \
import IAttributeRolePermissionManageable
_RAISE_KEYERROR = []
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__ = (
IFile,
IAttributeRolePermissionManageable)
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.File.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._data = data
if contentType is not None:
self._contentType = contentType
def getData(self):
'''See interface IFile'''
return self._data
def setData(self, data):
'''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
#
############################################################
=== Added File Zope3/lib/python/Zope/App/OFS/Content/File/__init__.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# 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.
##############################################################################
"""
$Id: __init__.py,v 1.1.2.1 2002/03/27 15:54:35 srichter Exp $
"""
=== Added File Zope3/lib/python/Zope/App/OFS/Content/File/edit.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css">
<!--
.ContentIcon {
width: 20px;
}
.ContentTitle {
text-align: left;
}
-->
</style>
</head>
<body>
<div metal:fill-slot="body">
<p tal:content="here/msg"
tal:condition="python: hasattr(here, 'msg')">
Message will go here.
</p>
<p tal:content="container/description">
Description of the Form.
</p>
<div tal:condition="python: options.has_key('errors') and options['errors']">
Errors:
<div tal:repeat="error options/errors | nothing"
tal:content="error">Foo </div>
</div>
<form action="action" method="post">
<table class="EditTable">
<tbody>
<tr tal:repeat="fieldView python:container.getFieldViews(request)">
<th class="EditAttributeName"
tal:content="python: fieldView.getContext().getValue('title')">Title</th>
<td class="EditAttributeValue"
tal:content="structure fieldView/render"><input />
</td>
</tr>
</tbody>
</table>
<input type="submit" name="edit" value="Save Changes">
</form>
</div>
</body>
</html>
=== Added File Zope3/lib/python/Zope/App/OFS/Content/File/file.zcml ===
<zopeConfigure
xmlns='http://namespaces.zope.org/zope'
xmlns:security='http://namespaces.zope.org/security'
xmlns:zmi='http://namespaces.zope.org/zmi'
>
<!-- NaiveFile Directives -->
<security:permission permission_id="Zope.AddNaiveFiles"
title="Add Naive Files" />
<zmi:provideClass name=".NaiveFile."
permission_id="Zope.AddNaiveFiles"
title="Naive File"
description="This is a simple file" />
<security:protectClass name=".NaiveFile."
permission_id="Zope.View" />
<!-- File Directives -->
<security:permission permission_id="Zope.AddFiles" title="Add Files" />
<zmi:provideClass name=".File."
permission_id="Zope.AddFiles"
title="File"
description="A File" />
<security:protectClass name=".File."
permission_id="Zope.View" />
<!-- tabs for folder -->
<zmi:tabs for=".IFile.">
<zmi:tab label="View" action=""/>
<zmi:tab label="Edit" action="edit;view"/>
<zmi:tab label="Role Permissions" action="RolePermissionsManagement;view"/>
</zmi:tabs>
<!-- Further Directives -->
<include package=".Views" file="views.zcml" />
</zopeConfigure>