[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