[Zope3-checkins] SVN: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ Move image part from zope.app.file to zope.app.image

Roger Ineichen roger at projekt01.ch
Thu Jan 20 11:56:45 EST 2005


Log message for revision 28890:
  Move image part from zope.app.file to zope.app.image
  
  TODO: Check it out.
  Can we really support BBB for the interface IImage and the class Image?

Changed:
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/PACKAGE.cfg
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/SETUP.cfg
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/__init__.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/__init__.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/configure.zcml
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/ftests.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_edit.pt
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_icon.gif
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/__init__.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/test_imagedata.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/configure.zcml
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/DEPENDENCIES.cfg
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/SETUP.cfg
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/__init__.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/configure.zcml
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/zope.app.image.fssync-configure.zcml
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/__init__.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/test_image.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image-configure.zcml
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/interfaces.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/meta.zcml
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/__init__.py
  A   Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/test_image.py

-=-
Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/PACKAGE.cfg
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/PACKAGE.cfg	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/PACKAGE.cfg	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,4 @@
+# The fssync support is a separate component:
+<collection>
+  fssync -
+</collection>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/PACKAGE.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/SETUP.cfg
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/SETUP.cfg	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/SETUP.cfg	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,5 @@
+# Tell zpkg how to install the ZCML slugs.
+
+<data-files zopeskel/etc/package-includes>
+  image-*.zcml
+</data-files>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/__init__.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/__init__.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,20 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Image content components
+
+$Id: __init__.py 26745 2004-07-24 04:02:18Z pruggera $
+"""
+__docformat__ = 'restructuredtext'
+
+from image import Image


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/__init__.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/__init__.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/configure.zcml	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/configure.zcml	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,62 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:browser="http://namespaces.zope.org/browser"
+    i18n_domain="zope"
+    >
+
+  <browser:editform
+      schema="zope.app.image.interfaces.IImage"
+      name="upload.html"
+      menu="zmi_views" title="Upload"
+      label="Upload an image"
+      permission="zope.ManageContent"
+      class=".image.ImageUpload"
+      template="image_edit.pt"
+      />
+
+  <browser:page
+      name="index.html"
+      for="zope.app.image.interfaces.IImage"
+      permission="zope.View"
+      allowed_attributes="__call__ tag"
+      class=".image.ImageData"
+      />
+
+  <browser:icon
+      name="zmi_icon"
+      for="zope.app.image.interfaces.IImage"
+      file="image_icon.gif"
+      />
+
+  <browser:addMenuItem
+      class="zope.app.image.image.Image"
+      title="Image"
+      description="An Image"
+      permission="zope.ManageContent"
+      view="zope.app.image.Image"
+      />
+
+  <browser:addform
+      schema="zope.app.image.interfaces.IImage"
+      label="Add an Image"
+      content_factory="zope.app.image.image.Image"
+      name="zope.app.image.Image"
+      permission="zope.ManageContent"
+      />
+
+
+  <!-- Preview views - requires zope.app.preview -->
+
+  <configure package="zope.app.preview">
+
+    <browser:page
+        for="zope.app.image.interfaces.IImage"
+        name="preview.html"
+        template="preview.pt"
+        permission="zope.ManageContent"
+        menu="zmi_views" title="Preview"
+        />
+
+  </configure>
+
+</configure>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/ftests.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/ftests.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/ftests.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,124 @@
+##############################################################################
+#
+# Copyright (c) 2003, 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Functional tests for Image.
+
+$Id: ftests.py 25177 2004-06-02 13:17:31Z jim $
+"""
+import unittest
+from StringIO import StringIO
+
+from zope.app.tests.functional import BrowserTestCase
+from zope.app.file.image import Image
+from zope.app.image.tests.test_image import zptlogo
+
+
+class ImageTest(BrowserTestCase):
+
+    content = zptlogo
+
+    def addImage(self):
+        image = Image(self.content)
+        root = self.getRootFolder()
+        root['image'] = image
+        self.commit()
+
+    def testAddForm(self):
+        response = self.publish(
+            '/+/zope.app.image.Image=',
+            basic='mgr:mgrpw')
+        self.assertEqual(response.getStatus(), 200)
+        body = response.getBody()
+        self.assert_('Add an Image' in body)
+        self.assert_('Content Type' in body)
+        self.assert_('Data' in body)
+        self.assert_('Object Name' in body)
+        self.assert_('"Add"' in body)
+        self.checkForBrokenLinks(body, '/+/zope.app.image.Image=',
+                                 'mgr:mgrpw')
+
+    def testAdd(self):
+        response = self.publish(
+            '/+/zope.app.image.Image=',
+            form={'type_name': u'zope.app.image.Image',
+                  'field.data': StringIO(self.content),
+                  'add_input_name': u'image',
+                  'UPDATE_SUBMIT': u'Add'},
+            basic='mgr:mgrpw')
+        self.assertEqual(response.getStatus(), 302)
+        self.assertEqual(response.getHeader('Location'),
+                         'http://localhost/@@contents.html')
+        root = self.getRootFolder()
+        self.assert_('image' in root)
+        image = root['image']
+        self.assertEqual(image.data, self.content)
+
+    def testUploadForm(self):
+        self.addImage()
+        response = self.publish(
+            '/image/@@upload.html',
+            basic='mgr:mgrpw')
+        self.assertEqual(response.getStatus(), 200)
+        body = response.getBody()
+        self.assert_('Upload an image' in body)
+        self.assert_('Content Type' in body)
+        self.assert_('Data' in body)
+        self.assert_('1 KB 16x16' in body)
+        self.checkForBrokenLinks(body, '/image/@@upload.html', 'mgr:mgrpw')
+
+    def testUpload(self):
+        self.addImage()
+        response = self.publish(
+            '/image/@@upload.html',
+            form={'field.data': StringIO(''),
+                  'UPDATE_SUBMIT': u'Change'},
+            basic='mgr:mgrpw')
+        self.assertEqual(response.getStatus(), 200)
+        body = response.getBody()
+        self.assert_('Upload an image' in body)
+        self.assert_('Content Type' in body)
+        self.assert_('Data' in body)
+        self.assert_('0 KB ?x?' in body)
+        root = self.getRootFolder()
+        image = root['image']
+        self.assertEqual(image.data, '')
+        self.assertEqual(image.contentType, 'image/gif')
+        
+    def testIndex(self):
+        self.addImage()
+        response = self.publish(
+            '/image/@@index.html',
+            basic='mgr:mgrpw')
+        self.assertEqual(response.getStatus(), 200)
+        body = response.getBody()
+        self.assertEqual(body, self.content)
+        self.checkForBrokenLinks(body, '/image/@@index.html', 'mgr:mgrpw')
+
+    def testPreview(self):
+        self.addImage()
+        response = self.publish(
+            '/image/@@preview.html',
+            basic='mgr:mgrpw')
+        self.assertEqual(response.getStatus(), 200)
+        body = response.getBody()
+        self.assert_('<iframe src="."' in body)
+        self.checkForBrokenLinks(body, '/image/@@preview.html', 'mgr:mgrpw')
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(ImageTest),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/ftests.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,93 @@
+##############################################################################
+#
+# 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.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 image editing.
+
+$Id: image.py 26745 2004-07-24 04:02:18Z pruggera $
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.app.size import byteDisplay
+from zope.app.size.interfaces import ISized
+
+
+class ImageData(object):
+
+    def __call__(self):
+        image = self.context
+        if self.request is not None:
+            self.request.response.setHeader('content-type', image.contentType)
+        return image.data
+
+    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.context.getImageSize()[0]
+        if height is None:
+            height = self.context.getImageSize()[1]
+
+        # 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 [a.lower() for a in 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
+
+
+class ImageUpload(object):
+    """Image edit view mix-in that provides access to image size info"""
+
+    def size(self):
+        sized = ISized(self.context)
+        return sized.sizeForDisplay()


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_edit.pt
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_edit.pt	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_edit.pt	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,23 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+  <div metal:use-macro="view/generated_form/macros/body">
+
+  <form action=".">   
+
+    <table metal:fill-slot="extra_top">
+      <tr>
+        <td i18n:translate="">Size</td>
+        <td tal:content="view/size" i18n:translate=""
+           >103 x 45 pixels, 43KB</td>            
+      </tr>
+    </table>
+
+  </form>
+
+  </div>
+</div>
+</body>
+
+</html>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_edit.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_icon.gif
===================================================================
(Binary files differ)


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/image_icon.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/__init__.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/__init__.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/test_imagedata.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/test_imagedata.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/test_imagedata.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,69 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""Test Image Data handling
+
+$Id: test_imagedata.py 26567 2004-07-16 06:58:27Z srichter $
+"""
+import unittest
+
+from zope.app.image.image import Image
+from zope.app.image.browser.image import ImageData
+
+class Test(unittest.TestCase):
+
+    def testData(self):
+        """ """
+        image = Image('Data')
+        id = ImageData()
+        id.context = image
+        id.request = None
+        self.assertEqual(id(), 'Data')
+
+    def testTag(self):
+        """ """
+
+        # We need that, sinc eabsolute_url is not implemented yet.
+        def absolute_url():
+            return '/img'
+
+        image = Image()
+        fe = ImageData()
+        fe.context = image
+        fe.request = None
+        fe.absolute_url = absolute_url
+
+        self.assertEqual(fe.tag(),
+            '<img src="/img" alt="" height="-1" width="-1" border="0" />')
+        self.assertEqual(fe.tag(alt="Test Image"),
+            '<img src="/img" alt="Test Image" '
+            'height="-1" width="-1" border="0" />')
+        self.assertEqual(fe.tag(height=100, width=100),
+            '<img src="/img" alt="" height="100" width="100" border="0" />')
+        self.assertEqual(fe.tag(border=1),
+            '<img src="/img" alt="" height="-1" width="-1" border="1" />')
+        self.assertEqual(fe.tag(css_class="Image"),
+            '<img src="/img" alt="" '
+            'height="-1" width="-1" border="0" class="Image" />')
+        self.assertEqual(fe.tag(height=100, width="100",
+                         border=1, css_class="Image"),
+            '<img src="/img" alt="" '
+            'height="100" width="100" class="Image" border="1" />')
+
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(Test)
+
+if __name__=='__main__':
+    unittest.main()


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/browser/tests/test_imagedata.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/configure.zcml	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/configure.zcml	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,60 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    i18n_domain='zope'
+    >
+
+  <!-- setting up content types -->
+
+  <interface 
+      interface=".interfaces.IImage" 
+      type="zope.app.content.interfaces.IContentType"
+      /> 
+
+  <permission
+      id="zope.AddImages"
+      title="[add-images-permission] Add Images"
+      />
+
+
+  <!-- content classes -->
+
+  <content class=".image.Image">
+    <factory
+        id="zope.app.content.Image"
+        title="Image"
+        description="An Image"
+        />
+
+    <require
+        permission="zope.View"
+        interface="zope.app.file.interfaces.IImage"
+        />
+
+    <require
+        permission="zope.ManageContent"
+        set_schema="zope.app.file.interfaces.IFile"
+        />
+
+    <implements
+        interface="zope.app.annotation.interfaces.IAttributeAnnotatable"
+        />
+  </content>
+
+  <adapter
+      factory=".image.ImageSized"
+      provides="zope.app.size.interfaces.ISized"
+      for=".interfaces.IImage"
+      />
+
+  <adapter
+      for="zope.app.folder.interfaces.IFolder"
+      provides="zope.app.filerepresentation.interfaces.IFileFactory"
+      factory=".image.FileFactory"
+      permission="zope.ManageContent"
+      />
+
+  <!-- include browser package -->
+
+  <include package=".browser" />
+
+</configure>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/DEPENDENCIES.cfg
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/DEPENDENCIES.cfg	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/DEPENDENCIES.cfg	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,3 @@
+zope.file
+zope.fssync
+zope.interface


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/DEPENDENCIES.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/SETUP.cfg
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/SETUP.cfg	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/SETUP.cfg	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,5 @@
+# Tell zpkg how to install the ZCML slugs.
+
+<data-files zopeskel/etc/package-includes>
+  zope.app.file.fssync-configure.zcml
+</data-files>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/__init__.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/__init__.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1 @@
+# This directory is a Python package.


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/configure.zcml	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/configure.zcml	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,12 @@
+<configure
+    xmlns='http://namespaces.zope.org/zope'
+    xmlns:fssync='http://namespaces.zope.org/fssync'
+    i18n_domain='zope'
+    >
+
+  <fssync:adapter
+      class="zope.app.image.Image"
+      factory=".adapter.FileAdapter"
+      />
+
+</configure>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/zope.app.image.fssync-configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/zope.app.image.fssync-configure.zcml	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/zope.app.image.fssync-configure.zcml	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1 @@
+<include package="zope.app.image.fssync" />


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/fssync/zope.app.image.fssync-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/__init__.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/__init__.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/test_image.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/test_image.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/test_image.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,112 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""File Functional Tests
+
+$Id: test_image.py 25177 2004-06-02 13:17:31Z jim $
+"""
+import unittest
+import cgi
+from cStringIO import StringIO
+from transaction import get_transaction
+from zope.app.tests.functional import BrowserTestCase
+from zope.publisher.browser import FileUpload
+
+from zope.app.image.image import Image
+
+zptlogo = (
+    'GIF89a\x10\x00\x10\x00\xd5\x00\x00\xff\xff\xff\xff\xff\xfe\xfc\xfd\xfd'
+    '\xfa\xfb\xfc\xf7\xf9\xfa\xf5\xf8\xf9\xf3\xf6\xf8\xf2\xf5\xf7\xf0\xf4\xf6'
+    '\xeb\xf1\xf3\xe5\xed\xef\xde\xe8\xeb\xdc\xe6\xea\xd9\xe4\xe8\xd7\xe2\xe6'
+    '\xd2\xdf\xe3\xd0\xdd\xe3\xcd\xdc\xe1\xcb\xda\xdf\xc9\xd9\xdf\xc8\xd8\xdd'
+    '\xc6\xd7\xdc\xc4\xd6\xdc\xc3\xd4\xda\xc2\xd3\xd9\xc1\xd3\xd9\xc0\xd2\xd9'
+    '\xbd\xd1\xd8\xbd\xd0\xd7\xbc\xcf\xd7\xbb\xcf\xd6\xbb\xce\xd5\xb9\xcd\xd4'
+    '\xb6\xcc\xd4\xb6\xcb\xd3\xb5\xcb\xd2\xb4\xca\xd1\xb2\xc8\xd0\xb1\xc7\xd0'
+    '\xb0\xc7\xcf\xaf\xc6\xce\xae\xc4\xce\xad\xc4\xcd\xab\xc3\xcc\xa9\xc2\xcb'
+    '\xa8\xc1\xca\xa6\xc0\xc9\xa4\xbe\xc8\xa2\xbd\xc7\xa0\xbb\xc5\x9e\xba\xc4'
+    '\x9b\xbf\xcc\x98\xb6\xc1\x8d\xae\xbaFgs\x00\x00\x00\x00\x00\x00\x00\x00'
+    '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+    '\x00,\x00\x00\x00\x00\x10\x00\x10\x00\x00\x06z@\x80pH,\x12k\xc8$\xd2f\x04'
+    '\xd4\x84\x01\x01\xe1\xf0d\x16\x9f\x80A\x01\x91\xc0ZmL\xb0\xcd\x00V\xd4'
+    '\xc4a\x87z\xed\xb0-\x1a\xb3\xb8\x95\xbdf8\x1e\x11\xca,MoC$\x15\x18{'
+    '\x006}m\x13\x16\x1a\x1f\x83\x85}6\x17\x1b $\x83\x00\x86\x19\x1d!%)\x8c'
+    '\x866#\'+.\x8ca`\x1c`(,/1\x94B5\x19\x1e"&*-024\xacNq\xba\xbb\xb8h\xbeb'
+    '\x00A\x00;'
+    )
+
+class TestImage(BrowserTestCase):
+
+    def _setupImage(self):
+        response = self.publish('/+/action.html',
+                                basic='mgr:mgrpw',
+                                form={'type_name': u'zope.app.content.Image',
+                                      'id': u'img'})
+
+        fs = cgi.FieldStorage()
+        fs.name = 'field.data'
+        fs.value = 'test.gif'
+        fs.filename = 'test.gif'
+        fs.file = StringIO(zptlogo)
+        response = self.publish('/img/@@upload.html',
+                                basic='mgr:mgrpw',
+                                form={'field.data': FileUpload(fs),
+                                      'field.contentType': u'image/gif',
+                                      'UPDATE_SUBMIT': 'Change'})
+        
+
+    def testAddImage(self):
+        # Step 1: add the image
+        response = self.publish('/+/action.html',
+                                basic='mgr:mgrpw',
+                                form={'type_name': u'zope.app.content.Image',
+                                      'id': u'img'})
+        self.assertEqual(response.getStatus(), 302)
+        self.assertEqual(response.getHeader('Location'),
+                         'http://localhost/@@contents.html')
+        # Step 2: check that it it visible in the folder listing
+        response = self.publish('/')
+        self.assertEqual(response.getStatus(), 200)
+        self.assert_(response.getBody().find('img') != -1)
+        # Step 3: check that its contents are available
+        response = self.publish('/img')
+        self.assertEqual(response.getStatus(), 200)
+
+
+    def testImageUpload(self):
+        self._setupImage()
+
+        root = self.getRootFolder()
+        self.assertEqual(root['img'].contentType, u'image/gif')
+        self.assertEqual(root['img'].data, zptlogo)
+
+
+    def testImageUploadOnlyChangingContentType(self):
+        self._setupImage()
+
+        response = self.publish('/img/@@upload.html',
+                                basic='mgr:mgrpw',
+                                form={'field.contentType': u'image/gif2',
+                                      'UPDATE_SUBMIT': u'Change'})
+        
+        root = self.getRootFolder()
+        self.assertEqual(root['img'].contentType, u'image/gif2')
+        self.assertEqual(root['img'].data, zptlogo)
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestImage))
+    return suite
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/ftests/test_image.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image-configure.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image-configure.zcml	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image-configure.zcml	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1 @@
+<include package="zope.app.image"/>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,152 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""Image content type implementation
+
+$Id: image.py 26745 2004-07-24 04:02:18Z pruggera $
+"""
+__docformat__ = 'restructuredtext'
+
+import struct
+from cStringIO import StringIO
+
+from zope.interface import implements
+
+from zope.app.size.interfaces import ISized
+from zope.app.size import byteDisplay
+from zope.app.content_types import guess_content_type
+from zope.app.i18n import ZopeMessageIDFactory as _
+
+from zope.app.file import File
+from interfaces import IImage
+
+class Image(File):
+    implements(IImage)
+
+    def __init__(self, data=''):
+        '''See interface `IFile`'''
+        super(Image, self).__init__(data)
+        self.contentType, self._width, self._height = getImageInfo(data)
+
+    def _setData(self, data):
+        super(Image, self)._setData(data)
+
+        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)
+
+class ImageSized(object):
+    implements(ISized)
+
+    def __init__(self, image):
+        self._image = image
+
+    def sizeForSorting(self):
+        '''See `ISized`'''
+        return ('byte', self._image.getSize())
+
+    def sizeForDisplay(self):
+        '''See `ISized`'''
+        w, h = self._image.getImageSize()
+        if w < 0:
+            w = '?'
+        if h < 0:
+            h = '?'
+        bytes = self._image.getSize()
+        byte_size = byteDisplay(bytes)
+        mapping = byte_size.mapping
+        size = _(byte_size + ' ${width}x${height}')
+        mapping.update({'width': str(w), 'height': str(h)})
+        size.mapping = mapping 
+        return size
+
+class FileFactory(object):
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, name, content_type, data):
+        if not content_type and data:
+            content_type, width, height = getImageInfo(data)
+        if not content_type:
+            content_type, encoding = guess_content_type(name, data, '')
+
+        if content_type.startswith('image/'):
+            return Image(data)
+
+        return File(data, content_type)
+
+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


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/image.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/interfaces.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/interfaces.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/interfaces.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""Basic Image interfaces.
+
+$Id: interfaces.py 28871 2005-01-19 14:23:47Z rogerineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+from zope.app.file.interfaces import IImage as BBBIImage
+
+
+class IImage(BBBIImage):
+    """This interface defines an Image that can be displayed.
+    """
+
+    def getImageSize():
+        """Return a tuple (x, y) that describes the dimensions of
+        the object.
+        """


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/interfaces.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/meta.zcml
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/meta.zcml	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/meta.zcml	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,12 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    i18n_domain='zope'
+    >
+
+  <!-- BBB: 2005/01/20 -->
+  <!-- provide old Image class and getImageInfo method -->
+  <modulealias
+    module="zope.app.image.image"
+    alias="zope.app.file.image" />
+
+</configure>


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/meta.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/__init__.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/__init__.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/__init__.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/test_image.py
===================================================================
--- Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/test_image.py	2005-01-20 16:54:50 UTC (rev 28889)
+++ Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/test_image.py	2005-01-20 16:56:45 UTC (rev 28890)
@@ -0,0 +1,168 @@
+##############################################################################
+#
+# 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.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.
+#
+##############################################################################
+"""Test Image content component
+
+$Id: test_image.py 26567 2004-07-16 06:58:27Z srichter $
+"""
+import unittest
+from zope.interface.verify import verifyClass
+from zope.app.file.file import File, FileWriteFile, FileReadFile
+from zope.app.image.interfaces import IImage
+from zope.app.image.image import Image, FileFactory, ImageSized
+
+zptlogo = (
+    'GIF89a\x10\x00\x10\x00\xd5\x00\x00\xff\xff\xff\xff\xff\xfe\xfc\xfd\xfd'
+    '\xfa\xfb\xfc\xf7\xf9\xfa\xf5\xf8\xf9\xf3\xf6\xf8\xf2\xf5\xf7\xf0\xf4\xf6'
+    '\xeb\xf1\xf3\xe5\xed\xef\xde\xe8\xeb\xdc\xe6\xea\xd9\xe4\xe8\xd7\xe2\xe6'
+    '\xd2\xdf\xe3\xd0\xdd\xe3\xcd\xdc\xe1\xcb\xda\xdf\xc9\xd9\xdf\xc8\xd8\xdd'
+    '\xc6\xd7\xdc\xc4\xd6\xdc\xc3\xd4\xda\xc2\xd3\xd9\xc1\xd3\xd9\xc0\xd2\xd9'
+    '\xbd\xd1\xd8\xbd\xd0\xd7\xbc\xcf\xd7\xbb\xcf\xd6\xbb\xce\xd5\xb9\xcd\xd4'
+    '\xb6\xcc\xd4\xb6\xcb\xd3\xb5\xcb\xd2\xb4\xca\xd1\xb2\xc8\xd0\xb1\xc7\xd0'
+    '\xb0\xc7\xcf\xaf\xc6\xce\xae\xc4\xce\xad\xc4\xcd\xab\xc3\xcc\xa9\xc2\xcb'
+    '\xa8\xc1\xca\xa6\xc0\xc9\xa4\xbe\xc8\xa2\xbd\xc7\xa0\xbb\xc5\x9e\xba\xc4'
+    '\x9b\xbf\xcc\x98\xb6\xc1\x8d\xae\xbaFgs\x00\x00\x00\x00\x00\x00\x00\x00'
+    '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+    '\x00,\x00\x00\x00\x00\x10\x00\x10\x00\x00\x06z@\x80pH,\x12k\xc8$\xd2f\x04'
+    '\xd4\x84\x01\x01\xe1\xf0d\x16\x9f\x80A\x01\x91\xc0ZmL\xb0\xcd\x00V\xd4'
+    '\xc4a\x87z\xed\xb0-\x1a\xb3\xb8\x95\xbdf8\x1e\x11\xca,MoC$\x15\x18{'
+    '\x006}m\x13\x16\x1a\x1f\x83\x85}6\x17\x1b $\x83\x00\x86\x19\x1d!%)\x8c'
+    '\x866#\'+.\x8ca`\x1c`(,/1\x94B5\x19\x1e"&*-024\xacNq\xba\xbb\xb8h\xbeb'
+    '\x00A\x00;'
+    )
+
+class TestImage(unittest.TestCase):
+
+    def _makeImage(self, *args, **kw):
+        return Image(*args, **kw)
+
+    def testEmpty(self):
+        file = self._makeImage()
+        self.assertEqual(file.contentType, '')
+        self.assertEqual(file.data, '')
+
+    def testConstructor(self):
+        file = self._makeImage('Data')
+        self.assertEqual(file.contentType, '')
+        self.assertEqual(file.data, 'Data')
+
+    def testMutators(self):
+        image = self._makeImage()
+
+        image.contentType = 'image/jpeg'
+        self.assertEqual(image.contentType, 'image/jpeg')
+
+        image._setData(zptlogo)
+        self.assertEqual(image.data, zptlogo)
+        self.assertEqual(image.contentType, 'image/gif')
+        self.assertEqual(image.getImageSize(), (16, 16))
+
+    def testInterface(self):
+        self.failUnless(IImage.implementedBy(Image))
+        self.failUnless(verifyClass(IImage, Image))
+
+class TestFileAdapters(unittest.TestCase):
+
+    def _makeFile(self, *args, **kw):
+        return Image(*args, **kw)
+
+    def test_ReadFile(self):
+        file = self._makeFile()
+        content = "This is some file\ncontent."
+        file.data = content
+        file.contentType = 'text/plain'
+        self.assertEqual(FileReadFile(file).read(), content)
+        self.assertEqual(FileReadFile(file).size(), len(content))
+
+    def test_WriteFile(self):
+        file = self._makeFile()
+        content = "This is some file\ncontent."
+        FileWriteFile(file).write(content)
+        self.assertEqual(file.data, content)
+
+class DummyImage(object):
+
+    def __init__(self, width, height, bytes):
+        self.width = width
+        self.height = height
+        self.bytes = bytes
+
+    def getSize(self):
+        return self.bytes
+
+    def getImageSize(self):
+        return self.width, self.height
+
+
+class TestFileFactory(unittest.TestCase):
+
+    def test_image(self):
+        factory = FileFactory(None)
+        f = factory("spam.txt", "image/foo", "hello world")
+        self.assert_(isinstance(f, Image), f)
+        f = factory("spam.txt", "", zptlogo)
+        self.assert_(isinstance(f, Image), f)
+
+    def test_text(self):
+        factory = FileFactory(None)
+        f = factory("spam.txt", "", "hello world")
+        self.assert_(isinstance(f, File), f)
+        self.assert_(not isinstance(f, Image), f)
+        f = factory("spam.txt", "", "\0\1\2\3\4")
+        self.assert_(isinstance(f, File), f)
+        self.assert_(not isinstance(f, Image), f)
+        f = factory("spam.txt", "text/splat", zptlogo)
+        self.assert_(isinstance(f, File), f)
+        self.assert_(not isinstance(f, Image), f)
+        f = factory("spam.txt", "application/splat", zptlogo)
+        self.assert_(isinstance(f, File), f)
+        self.assert_(not isinstance(f, Image), f)
+
+class TestSized(unittest.TestCase):
+
+    def testInterface(self):
+        from zope.app.size.interfaces import ISized
+        self.failUnless(ISized.implementedBy(ImageSized))
+        self.failUnless(verifyClass(ISized, ImageSized))
+
+    def test_zeroSized(self):
+        s = ImageSized(DummyImage(0, 0, 0))
+        self.assertEqual(s.sizeForSorting(), ('byte', 0))
+        self.assertEqual(s.sizeForDisplay(), u'0 KB ${width}x${height}')
+        self.assertEqual(s.sizeForDisplay().mapping['width'], '0')
+        self.assertEqual(s.sizeForDisplay().mapping['height'], '0')
+
+    def test_arbitrarySize(self):
+        s = ImageSized(DummyImage(34, 56, 78))
+        self.assertEqual(s.sizeForSorting(), ('byte', 78))
+        self.assertEqual(s.sizeForDisplay(), u'1 KB ${width}x${height}')
+        self.assertEqual(s.sizeForDisplay().mapping['width'], '34')
+        self.assertEqual(s.sizeForDisplay().mapping['height'], '56')
+
+    def test_unknownSize(self):
+        s = ImageSized(DummyImage(-1, -1, 23))
+        self.assertEqual(s.sizeForSorting(), ('byte', 23))
+        self.assertEqual(s.sizeForDisplay(), u'1 KB ${width}x${height}')
+        self.assertEqual(s.sizeForDisplay().mapping['width'], '?')
+        self.assertEqual(s.sizeForDisplay().mapping['height'], '?')
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(TestImage),
+        unittest.makeSuite(TestFileAdapters),
+        unittest.makeSuite(TestFileFactory),
+        unittest.makeSuite(TestSized)
+        ))
+
+if __name__=='__main__':
+    unittest.TextTestRunner().run(test_suite())


Property changes on: Zope3/branches/jhauser-filefieldwidget/src/zope/app/image/tests/test_image.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Zope3-Checkins mailing list