[Checkins] SVN: z3c.imagewidget/trunk/src/ Very, very basic image widget based on session widget.

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Sep 21 09:35:14 EDT 2006


Log message for revision 70289:
  Very, very basic image widget based on session widget.
  

Changed:
  A   z3c.imagewidget/trunk/src/
  A   z3c.imagewidget/trunk/src/z3c/
  A   z3c.imagewidget/trunk/src/z3c/__init__.py
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/DEPENDENCIES.cfg
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/README.txt
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/__init__.py
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/add.pt
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/configure.zcml
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/edit.pt
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/form.py
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/interfaces.py
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/tests.py
  A   z3c.imagewidget/trunk/src/z3c/imagewidget/widget.py

-=-
Added: z3c.imagewidget/trunk/src/z3c/__init__.py
===================================================================
--- z3c.imagewidget/trunk/src/z3c/__init__.py	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/__init__.py	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.imagewidget/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/DEPENDENCIES.cfg
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/DEPENDENCIES.cfg	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/DEPENDENCIES.cfg	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1 @@
+z3c.sessionwidget

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/README.txt
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/README.txt	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/README.txt	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,150 @@
+================
+The Image Widget
+================
+
+This package really does not provide any widget code at all, but is a set of
+forms that work with the session widget to provide an image upload and display
+*before* the data is stored in the content. Thus the following tests will
+simply test the various forms.
+
+  >>> from z3c.imagewidget import form, widget
+
+Adding an Image
+---------------
+
+The add form is a view on the image (session) widget and the request:
+
+  >>> from zope.publisher.browser import TestRequest
+  >>> request = TestRequest()
+
+  >>> import zope.schema
+  >>> from zope.app.file.interfaces import IImage
+  >>> imgField = zope.schema.Object(
+  ...     title=u'Image', schema=IImage)
+
+  >>> imgWidget = widget.ImageInputWidget(imgField, request)
+  >>> imgWidget.session.get('data')
+  >>> imgWidget.session.get('changed')
+
+  >>> addForm = form.AddImageForm(imgWidget, request)
+  >>> addForm.createAndAdd({'data': '%PNG...'})
+
+  >>> imgWidget.session['data']
+  <zope.app.file.image.Image object at ...>
+  >>> imgWidget.session['changed']
+  True
+
+Let's also make sure that the image data is what it needs to be:
+
+  >>> imgWidget.session['data'].data
+  '%PNG...'
+
+
+Editing an Image
+----------------
+
+Now that we have an image we can change it.
+
+  >>> image = imgWidget.session['data']
+  >>> imgWidget.session['changed'] = False
+
+  >>> editForm = form.EditImageForm(image, request)
+  >>> editForm.widget = imgWidget
+  >>> editForm.adapters = {}
+  >>> editForm.handle_edit_action.success({'data': '%PNG2...'})
+
+  >>> editForm.status
+  u'Image updated.'
+  >>> imgWidget.session['data'].data
+  '%PNG2...'
+  >>> imgWidget.session['changed']
+  True
+
+You can also generate the URL for the image for display:
+
+  >>> editForm.imageURL
+  '.../++session++z3c.sessionwidget.SessionInputWidget/field./++item++data/'
+
+When uploading an empty image, the image is set to None:
+
+  >>> imgWidget.session['changed'] = False
+
+  >>> editForm.handle_edit_action.success({'data': ''})
+
+  >>> imgWidget.session['data']
+  >>> imgWidget.session['changed']
+  True
+
+
+The Controller Form
+-------------------
+
+The controller form manages the forms to be displayed. So let's restart the
+example above and make sure everything works:
+
+  >>> imgWidget.name = 'data'
+
+  >>> imgWidget.session['data'] = None
+  >>> imgWidget.session['changed'] = False
+
+We also need some component setup:
+
+  >>> import zope.component
+  >>> from zope.app.form.browser import BytesWidget
+  >>> from zope.schema.interfaces import IBytes
+  >>> from zope.app.form.interfaces import IInputWidget
+
+  >>> zope.component.provideAdapter(
+  ...    BytesWidget, (IBytes, TestRequest), IInputWidget)
+
+At the beginning we have an add form, since no image is available as input:
+
+  >>> widgetForm = form.ImageSessionWidgetForm(imgWidget, request)
+  >>> widgetForm.update()
+  >>> widgetForm.imageForm
+  <z3c.imagewidget.form.AddImageForm object at ...>
+
+If we now upload an image, we end at an edit form:
+
+  >>> request = TestRequest(form={
+  ...     'imageForm.data': '%PNG...',
+  ...     'imageForm.actions.add': ''})
+
+  >>> widgetForm = form.ImageSessionWidgetForm(imgWidget, request)
+  >>> widgetForm.update()
+  >>> widgetForm.imageForm
+  <z3c.imagewidget.form.EditImageForm object at ...>
+
+  >>> imgWidget.session['data'].data
+  '%PNG...'
+
+Now let's change the image and we get back the edit form:
+
+  >>> request = TestRequest(form={
+  ...     'imageForm.data': '%PNG2...',
+  ...     'imageForm.actions.55706461746520696d616765': ''})
+
+  >>> widgetForm = form.ImageSessionWidgetForm(imgWidget, request)
+  >>> widgetForm.update()
+  >>> widgetForm.imageForm
+  <z3c.imagewidget.form.EditImageForm object at ...>
+
+  >>> imgWidget.session['data'].data
+  '%PNG2...'
+
+Passing empty data should give us back the add form.
+
+  >>> request = TestRequest(form={
+  ...     'imageForm.data': '',
+  ...     'imageForm.actions.55706461746520696d616765': ''})
+
+  >>> widgetForm = form.ImageSessionWidgetForm(imgWidget, request)
+  >>> widgetForm.update()
+  >>> widgetForm.imageForm
+  <z3c.imagewidget.form.AddImageForm object at ...>
+
+
+TO DO
+-----
+
+Use PIL to enforce size.


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/__init__.py
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/__init__.py	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/__init__.py	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,3 @@
+# Make a package.
+
+from z3c.imagewidget.widget import ImageInputWidget


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/add.pt
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/add.pt	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/add.pt	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,10 @@
+<tal:block define="widget nocall:view/widgets/data">
+  <div metal:use-macro="context/@@form_macros/widget_row" />
+</tal:block>
+
+<div id="actionsView">
+  <span class="actionButtons">
+    <input tal:repeat="action view/actions"
+           tal:replace="structure action/render" />
+  </span>
+</div>


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/add.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/configure.zcml
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/configure.zcml	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/configure.zcml	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,12 @@
+<configure
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:zope="http://namespaces.zope.org/zope">
+
+  <page
+      name="SessionInputWidget.form"
+      for=".widget.ImageInputWidget"
+      class=".form.ImageSessionWidgetForm"
+      permission="zope.Public"
+      />
+
+</configure>


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/edit.pt
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/edit.pt	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/edit.pt	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,25 @@
+<div tal:replace="structure view/widgets/data" />
+
+<div class="form-controls" tal:condition="view/availableActions">
+  <input tal:repeat="action view/actions"
+         tal:replace="structure action/render"
+         />
+</div>
+
+<div class="form-status"
+     tal:define="status view/status"
+     tal:condition="status">
+
+  <div class="summary" tal:content="view/status" i18n:translate="">
+    Form status summary
+  </div>
+
+  <ul class="errors" tal:condition="view/errors">
+     <li tal:repeat="error view/error_views">
+        <span tal:replace="structure error">Error Type</span>
+     </li>
+  </ul>
+</div>
+
+<img src=""
+     tal:attributes="src view/imageURL" />


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/edit.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/form.py
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/form.py	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/form.py	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,115 @@
+##############################################################################
+#
+# Copyright (c) 2006 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 Widget Forms
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.formlib import form
+from zope.publisher.browser import BrowserPage
+from zope.traversing.browser.absoluteurl import absoluteURL
+from zope.app.component import hooks
+from zope.app.file.interfaces import IImage
+from zope.app.file.image import Image
+from zope.app.i18n import ZopeMessageFactory as _
+from zope.app.pagetemplate import ViewPageTemplateFile
+
+from z3c.sessionwidget.widget import SESSION_KEY
+
+
+class AddImageForm(form.AddFormBase):
+    """Add an image.
+
+    This view expects the session widget as context.
+    """
+
+    label = _('Add Image')
+    prefix = 'imageForm'
+    form_fields = form.Fields(IImage).select('data')
+    template = ViewPageTemplateFile('add.pt')
+
+    def createAndAdd(self, data):
+        imagedata = data.get('data')
+        if imagedata:
+            image = Image(imagedata)
+            self.context.session['data'] = image
+            self.context.session['changed'] = True
+
+
+class EditImageForm(form.EditFormBase):
+    """Edit an image
+
+    This view uses the image as context.
+    """
+
+    label = u''
+    prefix = 'imageForm'
+    form_fields = form.Fields(IImage).select('data')
+    actions = form.Actions()
+    template = ViewPageTemplateFile('edit.pt')
+
+    # We need the widget, so we have a link back to sanity
+    widget = None
+
+    @form.action(_("Update image"))
+    def handle_edit_action(self, action, data):
+        if data['data'] == '':
+            self.widget.session['data'] = None
+        elif form.applyChanges(
+            self.context, self.form_fields, data, self.adapters):
+            self.status = _('Image updated.')
+        self.widget.session['changed'] = True
+
+    @property
+    def imageURL(self):
+        baseURL = absoluteURL(hooks.getSite(), self.request)
+        return baseURL + '/++session++%s/%s/++item++data/' %(
+            SESSION_KEY, self.widget.name)
+
+
+class ImageSessionWidgetForm(BrowserPage):
+    """A form for the session widget to upload images.
+
+    This form adapts the session widget (context) and the request.
+    """
+
+    def update(self):
+        image = self.context.session['data']
+        if not image:
+            # show the add form and call update
+            self.imageForm = AddImageForm(self.context, self.request)
+            self.imageForm.update()
+            if self.context.session['data']:
+                # after adding a image show the edit form and return
+                image = self.context.session['data']
+                self.imageForm = EditImageForm(image, self.request)
+                self.imageForm.widget = self.context
+                self.imageForm.update()
+
+        else:
+            # show the edit form and call update
+            self.imageForm = EditImageForm(image, self.request)
+            self.imageForm.widget = self.context
+            self.imageForm.update()
+            if not self.context.session['data']:
+                self.imageForm = AddImageForm(self.context, self.request)
+                self.imageForm.update()
+
+
+    def render(self):
+        return self.imageForm()
+
+    def __call__(self):
+        self.update()
+        return self.render()


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/form.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/interfaces.py
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/interfaces.py	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/interfaces.py	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,40 @@
+##############################################################################
+#
+# Copyright (c) 2006 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 Widget Interfaces
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.schema
+
+from zope.app.form.browser import interfaces
+from zope.app.i18n import ZopeMessageFactory as _
+
+
+class IImageWidget(interfaces.IBrowserWidget):
+    """A widget for inputting and displaying images."""
+
+    width = zope.schema.Int(
+        title=_(u'Width'),
+        description=_(u'The width of the image is to be rendered or '
+                      u'sized to.'),
+        required=False,
+        missing_value=None)
+
+    height = zope.schema.Int(
+        title=_(u'Height'),
+        description=_(u'The height of the image is to be rendered or '
+                      u'sized to.'),
+        required=False,
+        missing_value=None)


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/tests.py
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/tests.py	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/tests.py	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,55 @@
+##############################################################################
+#
+# Copyright (c) 2006 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 Widgets Test
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import doctest
+import unittest
+import zope.component
+from zope.app.session import interfaces
+from zope.app.session import session
+from zope.app.testing import placelesssetup
+from zope.app.session.http import CookieClientIdManager
+from zope.publisher.interfaces import IRequest
+from zope.testing.doctestunit import DocFileSuite
+
+
+def setUp(test):
+    placelesssetup.setUp()
+    zope.component.provideAdapter(
+        session.ClientId, (IRequest,), interfaces.IClientId)
+    zope.component.provideAdapter(
+        session.Session, (IRequest,), interfaces.ISession)
+    zope.component.provideUtility(
+        CookieClientIdManager(), interfaces.IClientIdManager)
+    zope.component.provideUtility(
+        session.PersistentSessionDataContainer(),
+        interfaces.ISessionDataContainer)
+
+def tearDown(test):
+    placelesssetup.tearDown()
+
+
+def test_suite():
+    return unittest.TestSuite((
+        DocFileSuite('README.txt',
+                     setUp=setUp, tearDown=tearDown,
+                     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+                     ),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.imagewidget/trunk/src/z3c/imagewidget/widget.py
===================================================================
--- z3c.imagewidget/trunk/src/z3c/imagewidget/widget.py	2006-09-21 13:33:59 UTC (rev 70288)
+++ z3c.imagewidget/trunk/src/z3c/imagewidget/widget.py	2006-09-21 13:35:13 UTC (rev 70289)
@@ -0,0 +1,30 @@
+##############################################################################
+#
+# Copyright (c) 2006 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 Widget Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+from zope.schema import fieldproperty
+
+import z3c.sessionwidget
+from z3c.imagewidget import interfaces
+
+class ImageInputWidget(z3c.sessionwidget.SessionInputWidget):
+    """Image input widget."""
+    zope.interface.implements(interfaces.IImageWidget)
+
+    width = fieldproperty.FieldProperty(interfaces.IImageWidget['width'])
+    height = fieldproperty.FieldProperty(interfaces.IImageWidget['height'])


Property changes on: z3c.imagewidget/trunk/src/z3c/imagewidget/widget.py
___________________________________________________________________
Name: svn:keywords
   + Id



More information about the Checkins mailing list