[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Image - Image.py:1.1.2.1 ImageData.py:1.1.2.1 ImageEdit.py:1.1.2.1 __init__.py:1.1.2.1 edit.pt:1.1.2.1
Stephan Richter
srichter@cbu.edu
Sat, 19 Jan 2002 23:57:33 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Image
In directory cvs.zope.org:/tmp/cvs-serv30501/Image
Added Files:
Tag: Zope-3x-branch
Image.py ImageData.py ImageEdit.py __init__.py edit.pt
Log Message:
- Restructuring the directory structure in Zope.App.OFS
- Added a simple Image support including two views
NOTE: The ImageData.tag() method does not work yet, since absolute_url is
not implemented yet.
=== Added File Zope3/lib/python/Zope/App/OFS/Image/Image.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 struct
from Zope.App.OFS.File.NaiveFile import INaiveFile, NaiveFile
from Zope.App.Security.IAttributeRolePermissionManageable \
import IAttributeRolePermissionManageable
class IImage(INaiveFile):
"""This interface defines an Image that can be displayed.
"""
def getSize():
"""Return a tuple (x, y) that describes the dimensions of
the object.
"""
_RAISE_KEYERROR = []
class Image(NaiveFile):
""" """
__implements__ = IImage
def __init__(self, data=None):
""" """
self._contentType, self._width, self._height = getImageInfo(data)
self._data = data
def edit(self, data, contentType=None):
"""See interface INaiveFile
Note: It ignores the content type!
"""
contentType, self._width, self._height = getImageInfo(data)
if contentType:
self._contentType = contentType
self._data = data
############################################################
# Implementation methods for interface
# Zope.App.OFS.Image.IImage
def getSize(self):
'''See interface IImage'''
return (self._width, self._height)
#
############################################################
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[:8] == '\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[:8] == '\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[:2] == '\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: pass
return content_type, width, height
=== Added File Zope3/lib/python/Zope/App/OFS/Image/ImageData.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 string
from Zope.Publisher.Browser.AttributePublisher import AttributePublisher
from Zope.PageTemplate.PageTemplateFile import PageTemplateFile
class ImageData(AttributePublisher):
__implements__ = AttributePublisher.__implements__
def __init__( self, image ):
self._image = image
def index(self, REQUEST=None):
image = self.getContext()
if REQUEST is not None:
REQUEST['RESPONSE'].setHeader('content-type', image.getContentType())
return image.getData()
def tag(self, height=None, width=None, alt=None,
scale=0, xscale=0, yscale=0, css_class=None, **args):
"""
Generate an HTML IMG tag for this image, with customization.
Arguments to self.tag() can be any valid attributes of an IMG tag.
'src' will always be an absolute pathname, to prevent redundant
downloading of images. Defaults are applied intelligently for
'height', 'width', and 'alt'. If specified, the 'scale', 'xscale',
and 'yscale' keyword arguments will be used to automatically adjust
the output height and width values of the image tag.
Since 'class' is a Python reserved word, it cannot be passed in
directly in keyword arguments which is a problem if you are
trying to use 'tag()' to include a CSS class. The tag() method
will accept a 'css_class' argument that will be converted to
'class' in the output tag to work around this.
"""
if width is None:
width=self.getContext().getSize()[0]
if height is None:
height = self.getContext().getSize()[0]
# Auto-scaling support
xdelta = xscale or scale
ydelta = yscale or scale
if xdelta and width:
width = str(int(round(int(width) * xdelta)))
if ydelta and height:
height = str(int(round(int(height) * ydelta)))
result='<img src="%s"' % (self.absolute_url())
if alt is None:
alt=getattr(self, 'title', '')
result = '%s alt="%s"' % (result, alt)
if height is not None:
result = '%s height="%s"' % (result, height)
if width is not None:
result = '%s width="%s"' % (result, width)
if not 'border' in map(string.lower, args.keys()):
result = '%s border="0"' % result
if css_class is not None:
result = '%s class="%s"' % (result, css_class)
for key in args.keys():
value = args.get(key)
result = '%s %s="%s"' % (result, key, value)
return '%s />' % result
def getContext(self):
return self._image
=== Added File Zope3/lib/python/Zope/App/OFS/Image/ImageEdit.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 image editing.
"""
from Zope.Publisher.Browser.AttributePublisher import AttributePublisher
from Zope.PageTemplate.PageTemplateFile import PageTemplateFile
class ImageEdit(AttributePublisher):
__implements__ = AttributePublisher.__implements__
def __init__( self, image ):
self._image = image
def editAction(self, data, contentType, REQUEST=None):
image = self.getContext()
if contentType != image.getContentType():
image.setContentType(contentType)
if data:
image.edit(data.read())
if REQUEST is not None:
return self.index(REQUEST, msg='Image Edited.')
def getContext( self ):
return self._image
index = PageTemplateFile('www/image_edit.pt')
=== Added File Zope3/lib/python/Zope/App/OFS/Image/__init__.py ===
=== Added File Zope3/lib/python/Zope/App/OFS/Image/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="options/msg | nothing">
Message will go here.
</p>
<form action="editAction" method="post" enctype="multipart/form-data">
<table class="EditTable">
<tbody>
<tr>
<th class="EditAttributeName">Content-Type</th>
<td class="EditAttributeValue">
<input type="text" name="contentType"
tal:attributes="value here/getContentType" />
</td>
</tr>
<tr>
<th class="EditAttributeName">Size</th>
<td class="EditAttributeValue"
tal:content="here/getSize">
</td>
</tr>
<tr>
<th class="EditAttributeName">Data</th>
<td class="EditAttributeValue">
<input type="file" name="data"
tal:attributes="value string:Select a File" />
</td>
</tr>
</tbody>
</table>
<input type="submit" name="edit" value="Save Changes">
</form>
</div>
</body>
</html>