[Zope3-checkins] CVS: Zope3/src/zope/app/content - __init__.py:1.1.2.1 configure.zcml:1.1.2.1 document.gif:1.1.2.1 dtml.gif:1.1.2.1 dtmlpage.py:1.1.2.1 file.py:1.1.2.1 file_icon.gif:1.1.2.1 folder.py:1.1.2.1 folder_icon.gif:1.1.2.1 i18nimage.py:1.1.2.1 image.py:1.1.2.1 image_icon.gif:1.1.2.1 sql.py:1.1.2.1 zpt.gif:1.1.2.1 zpt.py:1.1.2.1

Jim Fulton jim@zope.com
Mon, 23 Dec 2002 14:31:31 -0500


Update of /cvs-repository/Zope3/src/zope/app/content
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/app/content

Added Files:
      Tag: NameGeddon-branch
	__init__.py configure.zcml document.gif dtml.gif dtmlpage.py 
	file.py file_icon.gif folder.py folder_icon.gif i18nimage.py 
	image.py image_icon.gif sql.py zpt.gif zpt.py 
Log Message:
Initial renaming before debugging

=== Added File Zope3/src/zope/app/content/__init__.py ===
#
# This file is necessary to make this directory a package.


=== Added File Zope3/src/zope/app/content/configure.zcml ===
<zopeConfigure xmlns="http://namespaces.zope.org/zope">

<!-- Simple Folder Directives -->

<content class="zope.app.content.folder.Folder">

  <implements interface="zope.app.interfaces.container.IContentContainer" />

  <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
  
  <factory
      id="Folder"
      permission="Zope.ManageContent"
      title="Folder"
      description="Minimal folder" />

  <allow
      interface="zope.app.interfaces.services.service.Read"
      />

  <require
      permission="Zope.ManageServices"
      interface="zope.app.interfaces.services.service.Write"
      />

  <require
      permission="Zope.View"
      interface="zope.app.interfaces.container.IReadContainer" 
      />

  <require
      permission="Zope.ManageContent"
      interface="zope.app.interfaces.container.IWriteContainer"
      />

</content>

<!-- XXX Do we really need RootFolder? -->

<content class="zope.app.content.folder.RootFolder">

  <implements interface="zope.app.interfaces.container.IContentContainer" />

  <require like_class="zope.app.content.folder.Folder" />

  <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

</content>

<include package=".Views" />

</zopeConfigure>

<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
   xmlns:browser='http://namespaces.zope.org/browser'
>
  <permission id="Zope.AddImages" title="Add Images" />

  <content class="zope.app.content.image.Image">

    <factory
        id="Image"
        permission="Zope.ManageContent"
        title="Image"
        description="An Image" />

    <require
        permission="Zope.View"
        interface="zope.app.interfaces.content.file.IReadFile"
        attributes="getImageSize"
        />

    <require
        permission="Zope.ManageContent"
        interface="zope.app.interfaces.content.file.IWriteFile"
        set_schema="zope.app.interfaces.content.file.IReadFile"
        />

    <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

  </content>

  <content class="zope.app.content.i18nimage.I18nImage">
    <factory
        id="I18nImage"
        permission="Zope.ManageContent"
        title="I18n Image"
        description="An Internationalized Image" />
    <require
        permission="Zope.View"
        interface="zope.app.interfaces.content.file.IReadFile"
        attributes="getImageSize"
        />
    <require
        permission="Zope.ManageContent"
        interface="zope.app.interfaces.content.file.IWriteFile" />
    <require
        permission="Zope.View"
        attributes="getDefaultLanguage getAvailableLanguages" />
    <require
        permission="Zope.ManageContent"
        attributes="setDefaultLanguage removeLanguage" />

    <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

  </content>

  <include package=".Views" />

</zopeConfigure>

<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
>

<content class="zope.app.content.zpt.ZPTPage">
  <factory
      id="ZPTPage"
      permission="Zope.ManageContent"
      title="ZPT Page"
      description="A simple, content-based Page Template" />

  <factory
      id=".pt"
      permission="Zope.ManageContent"
      title="ZPT Page" />

  <factory
      id=".zpt"
      permission="Zope.ManageContent"
      title="ZPT Page" />

  <require
      permission="Zope.View"
      attributes="__call__" />

  <require
      permission="Zope.ManageContent"
      interface="zope.app.content.zpt.IZPTPage"
      set_attributes="source" />

  <require
      permission="Zope.View"
      interface="zope.app.content.zpt.IRenderZPTPage" />

  <implements
      interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
</content>

<adapter factory="zope.app.content.zpt.SearchableText"
         provides="zope.app.interfaces.index.text.interfaces.ISearchableText"
         for="zope.app.content.zpt.IZPTPage" />

<include package=".Views" />

</zopeConfigure>

<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
   xmlns:browser='http://namespaces.zope.org/browser'
>

  <content class="zope.app.content.dtmlpage.DTMLPage">

    <factory
        id="DTMLPage"
        permission="Zope.ManageContent"
        title="DTML Page"
        description="A simple, content-based Page Template" />

    <require permission="Zope.View"
                      attributes="__call__" />

    <require permission="Zope.ManageContent"
                      interface="zope.app.content.dtmlpage.IDTMLPage" />

    <require permission="Zope.View"
                      interface="zope.app.content.dtmlpage.IRenderDTMLPage" />


    <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

  </content>

  <include package=".Views" />

</zopeConfigure>

<zopeConfigure
   xmlns="http://namespaces.zope.org/zope"
   xmlns:vfs="http://namespaces.zope.org/vfs">

  <include package=".File" />
  <include package=".Folder" />
  <include package=".Image" />
  <include package=".ZPTPage" />
  <include package=".DTMLPage" />
  <include package=".SQLScript" />

</zopeConfigure>

<zopeConfigure xmlns='http://namespaces.zope.org/zope'>

<content class="zope.app.content.file.File">

  <factory
      id="File"
      permission="Zope.ManageContent"
      title="File"
      description="A File" />

  <require
      permission="Zope.View"
      interface="zope.app.interfaces.content.file.IReadFile" />

  <require
      permission="Zope.ManageContent"
      interface="zope.app.interfaces.content.file.IWriteFile"
      set_schema="zope.app.interfaces.content.file.IReadFile"
      />

  <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

</content>

<content class="zope.app.interfaces.content.18nfile.I18nFile">
  <factory
      id="I18nFile"
      permission="Zope.ManageContent"
      title="I18n File"
      description="An Internationalized File" />
  <require
      permission="Zope.View"
      interface="zope.app.interfaces.content.file.IReadFile" />
  <require
      permission="Zope.ManageContent"
      interface="zope.app.interfaces.content.file.IWriteFile" />
  <require
      permission="Zope.View"
      attributes="getDefaultLanguage getAvailableLanguages" />
  <require
      permission="Zope.ManageContent"
      attributes="setDefaultLanguage removeLanguage" />

  <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

</content>

<adapter factory="zope.app.content.file.SearchableText"
         provides="zope.app.interfaces.index.text.interfaces.ISearchableText"
         for="zope.app.interfaces.content.file.IReadFile" />

<include package=".Views" />

</zopeConfigure>



<zopeConfigure xmlns="http://namespaces.zope.org/zope">

  <!-- SQL Script Directives -->

  <permission id="Zope.AddSQLScripts" title="Add SQL Scripts" />

  <content class="zope.app.content.sql.SQLScript">

    <factory
        id="SQLScript"
        permission="Zope.ManageContent"
        title="SQL Script"
        description="Dynamic SQL Script" />

    <require
        permission = "Zope.ManageContent"
        interface = ".ISQLScript."
        set_schema = ".ISQLScript."
        />

    <require
        permission="Zope.ManageContent"
        interface="zope.app.interfaces.content.file.IFileContent" />

    <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

  </content>


  <!-- Arguments Directives -->

  <content class="zope.app.content.sql.Arguments">
    <require
        permission="Zope.ManageContent"
        interface="zope.interface.common.mapping.IEnumerableMapping" />
  </content>


  <!-- SQL DTML Directives -->

  <content class="zope.app.content.sql.SQLDTML">
    <require
        permission="Zope.ManageContent"
        attributes="__call__" />
  </content>


  <!-- Further Directives -->

  <include package=".Views" />

</zopeConfigure>


=== Added File Zope3/src/zope/app/content/document.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/content/dtml.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/content/dtmlpage.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: dtmlpage.py,v 1.1.2.1 2002/12/23 19:31:29 jim Exp $
"""
from zope.interface import Interface
from zope.interface.element import Attribute
import zope.schema
from persistence import Persistent

from zope.proxy.context import ContextMethod
from zope.proxy.context.context import getWrapperContainer
from zope.security.proxy import ProxyFactory

from zope.documenttemplate.pdocumenttemplate import MultiMapping
from zope.documenttemplate.dt_html import HTML
from zope.app.interfaces.annotation import IAnnotatable
from zope.app.interfaces.content.file import IFileContent


class IDTMLPage(Interface):
    """DTML Pages are a persistent implementation of DTML."""
    
    def setSource(text, content_type='text/html'):
        """Save the source of the page template."""

    def getSource():
        """Get the source of the page template."""

    source = Zope.Schema.Bytes(
        title=u"Source",
        description=u"""The source od the page template.""",
        required=True)


class IRenderDTMLPage(Interface):

    content_type = Attribute('Content type of generated output')

    def render(request, *args, **kw):
        """Render the page template.

        The first argument is bound to the top-level 'request'
        variable. The positional arguments are bound to the 'args'
        variable and the keyword arguments are bound to the 'options'
        variable.
        """


class DTMLPage(Persistent):

    # XXX Putting IFileContent at the end gives an error!
    __implements__ = IFileContent, IDTMLPage, IRenderDTMLPage, IAnnotatable


    def __init__(self, source=''):
        self.setSource(source)

    def getSource(self):
        '''See interface IDTMLPage'''
        return self.template.read()

    def setSource(self, text, content_type='text/html'):
        '''See interface IDTMLPage'''
        self.template = HTML(text.encode('utf-8'))
        self.content_type = content_type

    def render(self, request, *args, **kw):
        """See interface IDTMLRenderPage"""

        instance = ProxyFactory(getWrapperContainer(self))
        request = ProxyFactory(request)
        
        for k in kw:
            kw[k] = ProxyFactory(kw[k])
        kw['REQUEST'] = request

        return self.template(instance, request, **kw)


    render = ContextMethod(render)

    __call__ = render

    source = property(getSource, setSource, None,
                      """Source of the DTML Page.""")


=== Added File Zope3/src/zope/app/content/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/12/23 19:31:29 jim Exp $
"""
from types import StringType, UnicodeType, NoneType
import datetime
zerotime = datetime.datetime.fromtimestamp(0)

from persistence import Persistent
from transaction import get_transaction

from zope.component import getAdapter
from zope.publisher.browser import FileUpload

from zope.app.interfaces.dublincore import IZopeDublinCore
from zope.app.interfaces.annotation import IAnnotatable


from zope.app.interfaces.content.file import IFile, IReadFile

# set the size of the chunks
MAXCHUNKSIZE = 1 << 16

class File(Persistent):
    __implements__ = IFile, IAnnotatable

    def __init__(self, data='', contentType=''):
        self.data = data
        self.contentType = contentType


    def __len__(self):
        return self.size


    def setContentType(self, contentType):
        '''See interface Zope.App.OFS.Content.File.IFile.IFile'''
        self._contentType = contentType

        
    def getContentType(self):
        '''See interface Zope.App.OFS.Content.File.IFile.IFile'''
        return self._contentType

        
    def edit(self, data, contentType=None):
        '''See interface Zope.App.OFS.Content.File.IFile.IFile'''
        # XXX This seems broken to me, as setData can override the
        # content type explicitly passed in.
        
        if contentType is not None:
            self._contentType = contentType
        if hasattr(data, '__class__') and data.__class__ is FileUpload \
           and not data.filename:
           data = None          # Ignore empty files
        if data is not None:
            self.data = data


    def getData(self):
        '''See interface Zope.App.OFS.Content.File.IFile.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 Zope.App.OFS.Content.File.IFile.IFile'''
        # Handle case when data is a string
        if isinstance(data, UnicodeType):
            data = data.encode('UTF-8')

        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 None
        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 data 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 < MAXCHUNKSIZE:
                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().savepoint()
        
        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().savepoint()

            # 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 Zope.App.OFS.Content.File.IFile.IFile'''
        return self._size

    data = property(getData, setData, None,
                    """Contains the data of the file.""")

    contentType = property(getContentType, setContentType, None,
                           """Specifies the content type of the data.""")

    size = property(getSize, None, None,
                    """Specifies the size of the file in bytes. Read only.""")


# Adapter for ISearchableText

from zope.app.interfaces.index.text.interfaces import ISearchableText

class SearchableText:

    __implements__ = ISearchableText
    __used_for__ = IReadFile

    def __init__(self, file):
        self.file = file

    def getSearchableText(self):
        if self.file.contentType == "text/plain":
            return [unicode(self.file.data)]
        else:
            return None


"""

$Id: file.py,v 1.1.2.1 2002/12/23 19:31:29 jim 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
            result.append(self._data)
            next = self.next
        
        return ''.join(result)


=== Added File Zope3/src/zope/app/content/file_icon.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/content/folder.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.
# 
##############################################################################

from zope.app.interfaces.traversing.containmentroot import IContainmentRoot

class IRootFolder(IFolder, IContainmentRoot):
    """The standard Zope root Folder object interface."""


class RootFolder(Folder):
    """The standard Zope root Folder implementation."""

    __implements__ = Folder.__implements__, IRootFolder


from zope.app.interfaces.container import IContainer

import persistence
from zodb.btrees.OOBTree import OOBTree
from zope.app.services.service \
     import ServiceManagerContainer

from zope.app.interfaces.services.service import \
     IServiceManagerContainer
from zope.exceptions import DuplicationError

class IFolder(IContainer, IServiceManagerContainer):
    """The standard Zope Folder object interface."""

class Folder(Persistence.Persistent, ServiceManagerContainer):
    """The standard Zope Folder implementation."""

    __implements__ = IFolder
    
    def __init__(self):
        self.data = OOBTree()

    def keys(self):
        """Return a sequence-like object containing the names 
           associated with the objects that appear in the folder
        """
        return self.data.keys()

    def __iter__(self):
        return iter(self.data.keys())

    def values(self):
        """Return a sequence-like object containing the objects that
           appear in the folder.
        """
        return self.data.values()

    def items(self):
        """Return a sequence-like object containing tuples of the form
           (name, object) for the objects that appear in the folder.
        """
        return self.data.items()

    def __getitem__(self, name):
        """Return the named object, or the value of the default 
           argument if given and the named object is not found.
           If no default is given and the object is not found a
           KeyError is raised.
        """
        return self.data[name]

    def get(self, name, default=None):
        """Return the named object, or the value of the default 
           argument if given and the named object is not found.
           If no default is given and the object is not found a
           KeyError is raised.
        """
        return self.data.get(name, default)

    def __contains__(self, name):
        """Return true if the named object appears in the folder."""
        return self.data.has_key(name)

    def __len__(self):
        """Return the number of objects in the folder."""
        return len(self.data)

    def setObject(self, name, object):
        """Add the given object to the folder under the given name."""

        if not (isinstance(name, str) or isinstance(name, unicode)):
            raise TypeError("Name must be a string rather than a %s" %
                            name.__class__.__name__)
        if not name:
            raise TypeError("Name must not be empty")

        if name in self.data:
            raise DuplicationError("name, %s, is already in use" % name)

        self.data[name] = object
        return name

    def __delitem__(self, name):
        """Delete the named object from the folder. Raises a KeyError
           if the object is not found."""
        del self.data[name]



=== Added File Zope3/src/zope/app/content/folder_icon.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/content/i18nimage.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.
# 
##############################################################################
"""
Revision Information:
$Id: i18nimage.py,v 1.1.2.1 2002/12/23 19:31:29 jim Exp $
"""

import struct

from zope.app.content.image import IImage, Image, getImageInfo
from zope.app.interfaces.content.18nfile import II18nFile, I18nFile
from zope.app.interfaces.annotation import IAnnotatable


class II18nImage(II18nFile, IImage):
    """I18n aware image interface."""


class I18nImage(I18nFile):
    """An internationalized Image object.  Note that images of all
    languages share the same content type.
    """

    __implements__ = (
        II18nImage,
        IAnnotatable,
        )


    def _create(self, data):
        return Image(data)


    def setData(self, data, language=None):
        '''See interface IFile'''
        super(I18nImage, self).setData(data, language)

        if language is None or language == self.getDefaultLanguage():
            # Uploading for the default language only overrides content
            # type.  Note: do not use the argument data here, it doesn't
            # work.
            contentType = getImageInfo(self.getData(language))[0]
            if contentType:
                self.setContentType(contentType)


    ############################################################
    # Implementation methods for interface
    # Zope.App.OFS.Image.IImage

    def getImageSize(self, language=None):
        '''See interface IImage'''
        return self._get(language).getImageSize()

    #
    ############################################################


=== Added File Zope3/src/zope/app/content/image.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: image.py,v 1.1.2.1 2002/12/23 19:31:29 jim Exp $
"""
import struct

from zope.app.content.file import File
from zope.app.interfaces.content.file import IFile
from zope.app.interfaces.annotation import IAnnotatable
from cStringIO import StringIO


class IImage(IFile):
    """This interface defines an Image that can be displayed."""

    def getImageSize():
        """Return a tuple (x, y) that describes the dimensions of
        the object."""

class Image(File):
    __implements__ = IImage, IAnnotatable

    def __init__(self, data=None):
        '''See interface Zope.App.OFS.Content.File.IFile.IFile'''
        self.contentType, self._width, self._height = getImageInfo(data)
        self.data = data


    def setData(self, data):
        
        super(Image, self).setData(data)

        if data is not None:
            contentType = None
            contentType, self._width, self._height = getImageInfo(self.data)
            if contentType:
                self.contentType = contentType


    def getImageSize(self):
        '''See interface IImage'''
        return (self._width, self._height)

    data = property(File.getData, setData, None,
                    """Contains the data of the file.""")


def getImageInfo(data):
    data = str(data)
    size = len(data)
    height = -1
    width = -1
    content_type = ''

    # handle GIFs   
    if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
        # Check to see if content_type is correct
        content_type = 'image/gif'
        w, h = struct.unpack("<HH", data[6:10])
        width = int(w)
        height = int(h)

    # See PNG v1.2 spec (http://www.cdrom.com/pub/png/spec/)
    # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
    # and finally the 4-byte width, height
    elif ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
          and (data[12:16] == 'IHDR')):
        content_type = 'image/png'
        w, h = struct.unpack(">LL", data[16:24])
        width = int(w)
        height = int(h)
            
    # Maybe this is for an older PNG version.
    elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
        # Check to see if we have the right content type
        content_type = 'image/png'
        w, h = struct.unpack(">LL", data[8:16])
        width = int(w)
        height = int(h)

    # handle JPEGs
    elif (size >= 2) and data.startswith('\377\330'):
        content_type = 'image/jpeg'
        jpeg = StringIO(data)
        jpeg.read(2)
        b = jpeg.read(1)
        try:
            while (b and ord(b) != 0xDA):
                while (ord(b) != 0xFF): b = jpeg.read(1)
                while (ord(b) == 0xFF): b = jpeg.read(1)
                if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
                    jpeg.read(3)
                    h, w = struct.unpack(">HH", jpeg.read(4))
                    break
                else:
                    jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
                b = jpeg.read(1)
            width = int(w)
            height = int(h)
        except struct.error:
            pass
        except ValueError:
            pass

    return content_type, width, height


=== Added File Zope3/src/zope/app/content/image_icon.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/content/sql.py === (548/648 lines abridged)
##############################################################################
#
# Copyright (c) 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: sql.py,v 1.1.2.1 2002/12/23 19:31:29 jim Exp $
"""

import re
from persistence.dict import PersistentDict
from zope.interface.common.mapping import IEnumerableMapping

unparmre = re.compile(r'([\000- ]*([^\000- ="]+))')
parmre = re.compile(r'([\000- ]*([^\000- ="]+)=([^\000- ="]+))')
qparmre = re.compile(r'([\000- ]*([^\000- ="]+)="([^"]*)")')

InvalidParameter = 'Invalid Parameter'

class Arguments(PersistentDict):
    """Hold arguments of SQL Script"""

    __implements__ = IEnumerableMapping


def parseArguments(text, result=None):
    """Parse argument string."""

    # Make some initializations
    if result is None:
        result  = {}

    __traceback_info__ = text

    # search for the first argument assuming a default value (unquoted) was
    # given
    match_object = parmre.match(text)

    if match_object:
        name    = match_object.group(2)
        value   = {'default': match_object.group(3)}

[-=- -=- -=- 548 lines omitted -=- -=- -=-]

            if not isinstance(expr, StringTypes):
                raise
            raise ('Missing Input',
                   'Missing input variable, **%s**' % name)

        # XXX Shrug, should these tyoes be really hard coded? What about
        # Dates and other types a DB supports; I think we should make this
        # a plugin.
        if t == 'int':
            try:
                if isinstance(v, StringTypes):
                    int(v)
                else:
                    v = str(int(v))
            except:
                if not v and args.has_key('optional') and args['optional']:
                    return 'null'
                raise ValueError, (
                    'Invalid integer value for **%s**' % name)

        elif t == 'float':
            try:
                if isinstance(v, StringTypes):
                    float(v)
                else:
                    v = str(float(v))
            except:
                if not v and args.has_key('optional') and args['optional']:
                    return 'null'
                raise ValueError, (
                    'Invalid floating-point value for **%s**' % name)

        else:
            orig_v = v
            v = str(v)
            if (not v or orig_v is None) and t == 'nb':
                if args.has_key('optional') and args['optional']:
                    return 'null'
                else:
                    raise ValueError, (
                        'Invalid empty string value for **%s**' % name)
            
            v = self.sql_quote__(v)

        return v

    __call__ = render


valid_type = {'int':1, 'float':1, 'string':1, 'nb': 1}.has_key


=== Added File Zope3/src/zope/app/content/zpt.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/content/zpt.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: zpt.py,v 1.1.2.1 2002/12/23 19:31:29 jim Exp $
"""

import re

from zope.interface import Interface
from zope.interface.element import Attribute
import zope.schema
from persistence import Persistent

from zope.proxy.context import ContextMethod
from zope.proxy.context.context import getWrapperContainer
from zope.security.proxy import ProxyFactory

from zope.pagetemplate.pagetemplate import PageTemplate
from zope.app.pagetemplate.engine import AppPT

class IZPTPage(Interface):
    """ZPT Pages are a persistent implementation of Page Templates.

       Note: I introduced some new methods whose functionality is
             actually already covered by some other methods but I
             want to start inforcing a common coding standard.
    """

    def setSource(text, content_type='text/html'):
        """Save the source of the page template.

        'text' must be Unicode.
        """

    def getSource():
        """Get the source of the page template."""

    source = Zope.Schema.Text(
        title=u"Source",
        description=u"""The source of the page template.""",
        required=True)


class IRenderZPTPage(Interface):

    content_type = Attribute('Content type of generated output')

    def render(request, *args, **kw):
        """Render the page template.

        The first argument is bound to the top-level 'request'
        variable. The positional arguments are bound to the 'args'
        variable and the keyword arguments are bound to the 'options'
        variable.
        """


class ZPTPage(AppPT, PageTemplate, Persistent):

    __implements__ = IZPTPage, IRenderZPTPage

    def getSource(self):
        '''See interface Zope.App.OFS.ZPTPage.ZPTPage.IZPTPage'''
        return self.read()

    def setSource(self, text, content_type='text/html'):
        '''See interface Zope.App.OFS.ZPTPage.ZPTPage.IZPTPage'''
        if not isinstance(text, unicode):
            raise TypeError("source text must be Unicode")

        self.pt_edit(text.encode('utf-8'), content_type)

    def pt_getContext(self, instance, request, **_kw):
        # instance is a View component
        namespace = super(ZPTPage, self).pt_getContext(**_kw)
        namespace['request'] = request
        namespace['context'] = instance
        return namespace

    def render(self, request, *args, **keywords):
        instance = getWrapperContainer(self)

        request = ProxyFactory(request)
        instance = ProxyFactory(instance)
        if args: args = ProxyFactory(args)
        kw = ProxyFactory(keywords)

        namespace = self.pt_getContext(instance, request,
                                       args=args, options=kw)

        return self.pt_render(namespace)

    render = ContextMethod(render)

    source = property(getSource, setSource, None,
                      """Source of the Page Template.""")


# Adapter for ISearchableText
from zope.app.interfaces.index.text.interfaces import ISearchableText

class SearchableText:

    __used_for__ = IZPTPage
    __implements__ = ISearchableText

    def __init__(self, page):
        self.page = page

    def getSearchableText(self):
        text = self.page.getSource()
        if isinstance(text, str):
            text = unicode(self.page.source, 'utf-8')
        # else:
        #   text was already Unicode, which happens, but unclear how it
        #   gets converted to Unicode since the ZPTPage stores UTF-8 as
        #   an 8-bit string.
        
        
        if self.page.content_type.startswith('text/html'):
            tag = re.compile(r"<[^>]+>")
            text = tag.sub('', text)
        
           
        return [text]