[Checkins] SVN: z3c.formwidget.query/ Initial import.

Malthe Borch mborch at gmail.com
Thu Apr 10 20:43:45 EDT 2008


Log message for revision 85225:
  Initial import.

Changed:
  A   z3c.formwidget.query/
  A   z3c.formwidget.query/trunk/
  A   z3c.formwidget.query/trunk/.installed.cfg
  A   z3c.formwidget.query/trunk/AUTHOR.txt
  A   z3c.formwidget.query/trunk/README.txt
  A   z3c.formwidget.query/trunk/bootstrap.py
  A   z3c.formwidget.query/trunk/buildout.cfg
  A   z3c.formwidget.query/trunk/setup.py
  A   z3c.formwidget.query/trunk/src/
  A   z3c.formwidget.query/trunk/src/z3c/
  A   z3c.formwidget.query/trunk/src/z3c/__init__.py
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/__init__.py
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/query/
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/query/README.txt
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/query/__init__.py
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/query/interfaces.py
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/query/tests.py
  A   z3c.formwidget.query/trunk/src/z3c/formwidget/query/widget.py

-=-
Added: z3c.formwidget.query/trunk/.installed.cfg
===================================================================
--- z3c.formwidget.query/trunk/.installed.cfg	                        (rev 0)
+++ z3c.formwidget.query/trunk/.installed.cfg	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,27 @@
+[buildout]
+installed_develop_eggs = /Users/mborch/co/z3c.formwidget.query/develop-eggs/z3c.formwidget.query.egg-link
+parts = test
+
+[test]
+__buildout_installed__ = /Users/mborch/co/z3c.formwidget.query/parts/test
+	/Users/mborch/co/z3c.formwidget.query/bin/test
+__buildout_signature__ = zc.recipe.testrunner-1.0.0-py2.5.egg zc.recipe.egg-1.0.0-py2.5.egg setuptools-0.6c8-py2.5.egg zope.testing-3.5.1-py2.5.egg zc.buildout-1.0.1-py2.5.egg zc.buildout-1.0.1-py2.5.egg
+_b = /Users/mborch/co/z3c.formwidget.query/bin
+_d = /Users/mborch/co/z3c.formwidget.query/develop-eggs
+_e = /Users/mborch/Development/sources/buildout
+bin-directory = /Users/mborch/co/z3c.formwidget.query/bin
+develop-eggs-directory = /Users/mborch/co/z3c.formwidget.query/develop-eggs
+eggs = z3c.formwidget.query
+eggs-directory = /Users/mborch/Development/sources/buildout
+executable = /opt/local/bin/python2.5
+find-links = http://download.zope.org/distribution/
+index = http://download.zope.org/ppix
+location = /Users/mborch/co/z3c.formwidget.query/parts/test
+recipe = zc.recipe.testrunner
+script = /Users/mborch/co/z3c.formwidget.query/bin/test
+
+[buildout]
+installed_develop_eggs = /Users/mborch/co/z3c.formwidget.query/develop-eggs/z3c.formwidget.query.egg-link
+
+[buildout]
+parts = test

Added: z3c.formwidget.query/trunk/AUTHOR.txt
===================================================================
--- z3c.formwidget.query/trunk/AUTHOR.txt	                        (rev 0)
+++ z3c.formwidget.query/trunk/AUTHOR.txt	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1 @@
+Malthe Borch <mborch at gmail.com>

Added: z3c.formwidget.query/trunk/README.txt
===================================================================
--- z3c.formwidget.query/trunk/README.txt	                        (rev 0)
+++ z3c.formwidget.query/trunk/README.txt	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,15 @@
+Overview
+========
+
+This package implements a widget that lets users enter a query and
+select from the results.
+
+The widget currently works with ``zope.schema.Choice``-fields
+supplying a query source [1].
+
+Results need to implement or adapt to ``ITitledTokenizedTerm``.
+
+------
+
+[1] The source needs to implement ``IQuerySource`` as defined in this
+package.

Added: z3c.formwidget.query/trunk/bootstrap.py
===================================================================
--- z3c.formwidget.query/trunk/bootstrap.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/bootstrap.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 71627 2006-12-20 16:46:11Z jim $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)

Added: z3c.formwidget.query/trunk/buildout.cfg
===================================================================
--- z3c.formwidget.query/trunk/buildout.cfg	                        (rev 0)
+++ z3c.formwidget.query/trunk/buildout.cfg	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,9 @@
+[buildout]
+develop = .
+parts = test
+
+find-links = http://download.zope.org/distribution/
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.formwidget.query
\ No newline at end of file

Added: z3c.formwidget.query/trunk/setup.py
===================================================================
--- z3c.formwidget.query/trunk/setup.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/setup.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,54 @@
+#!python
+from setuptools import setup, find_packages
+
+setup(name='z3c.formwidget.query',
+      version='0.1',
+      author = "Zope Community",
+      author_email = "zope3-dev at zope.org",
+      description = "A source query widget for z3c.form.",
+      long_description=open('README.txt').read(),
+      license = "ZPL 2.1",
+      keywords = "zope zope3 z3c.form",
+      url='http://svn.zope.org/z3c.formwidget',
+      zip_safe=False,
+      packages=find_packages('src'),
+      include_package_data=True,
+      package_dir = {'':'src'},
+      namespace_packages=['z3c', 'z3c.formwidget'],
+      extras_require = dict(test=['zope.app.testing',
+                                  'zope.testing',
+                                  'zope.app.securitypolicy',
+                                  'zope.app.zcmlfiles',
+                                  'zope.testbrowser',
+                                  ]),
+      install_requires = ['setuptools',
+                          'z3c.form',
+                          'zope.app.cache',
+                          'zope.app.container',
+                          'zope.app.file',
+                          'zope.app.form',
+                          'zope.app.i18n',
+                          'zope.app.pagetemplate',
+                          'zope.component',
+                          'zope.event',
+                          'zope.filerepresentation',
+                          'zope.formlib',
+                          'zope.i18n',
+                          'zope.i18nmessageid',
+                          'zope.interface',
+                          'zope.lifecycleevent',
+                          'zope.publisher',
+                          'zope.schema',
+                          'zope.security',
+                          'zope.traversing',
+                          ],
+      classifiers = ['Development Status :: 4 - Alpha',
+                     'Environment :: Web Environment',
+                     'Framework :: Zope3',
+                     'Intended Audience :: Developers',
+                     'License :: OSI Approved :: Zope Public License',
+                     'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
+                     'Programming Language :: Python',
+                     'Topic :: Software Development :: Libraries :: Python Modules',
+                     ],
+      )

Added: z3c.formwidget.query/trunk/src/z3c/__init__.py
===================================================================
--- z3c.formwidget.query/trunk/src/z3c/__init__.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/src/z3c/__init__.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: z3c.formwidget.query/trunk/src/z3c/formwidget/__init__.py
===================================================================
--- z3c.formwidget.query/trunk/src/z3c/formwidget/__init__.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/src/z3c/formwidget/__init__.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: z3c.formwidget.query/trunk/src/z3c/formwidget/query/README.txt
===================================================================
--- z3c.formwidget.query/trunk/src/z3c/formwidget/query/README.txt	                        (rev 0)
+++ z3c.formwidget.query/trunk/src/z3c/formwidget/query/README.txt	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,125 @@
+z3c.formwidget.query
+====================
+
+This package provides a widget to query a source.
+
+  >>> from z3c.form import testing
+  >>> testing.setupFormDefaults()
+
+We must register a form page template to render forms.
+
+  >>> from z3c.form import form, testing
+  >>> factory = form.FormTemplateFactory(
+  ...     testing.getPath('../tests/simple_subedit.pt'))
+
+Let's register our new template-based adapter factory:
+
+  >>> component.provideAdapter(factory)
+
+Sources
+-------
+
+Let's start by defining a source.
+
+  >>> from z3c.formwidget.query.interfaces import IQuerySource
+  >>> from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
+
+  >>> class ItalianCities(object):
+  ...     interface.implements(IQuerySource)
+  ...
+  ...     vocabulary = SimpleVocabulary((
+  ...         SimpleTerm(u'Bologna', 'bologna', u'Bologna'),
+  ...         SimpleTerm(u'Palermo', 'palermo', u'Palermo'),
+  ...         SimpleTerm(u'Sorrento', 'sorrento', u'Sorrento')))
+  ...
+  ...     def __init__(self, context):
+  ...         self.context = context
+  ...
+  ...     __contains__ = vocabulary.__contains__
+  ...     __iter__ = vocabulary.__iter__
+  ...
+  ...     def search(self, query_string):
+  ...         return [v for v in self if query_string.lower() in v.value.lower()]
+
+  >>> from zope.schema.interfaces import IContextSourceBinder
+
+  >>> class ItalianCitiesSourceBinder(object):
+  ...     interface.implements(IContextSourceBinder)
+  ...
+  ...     def __call__(self, context):
+  ...         return ItalianCities(context)
+  
+Fields setup
+------------
+
+  >>> import zope.component
+  >>> import zope.schema
+  >>> import zope.app.form.browser
+  >>> from zope.publisher.interfaces.browser import IBrowserRequest
+
+First we have to create a field and a request:
+
+  >>> city = zope.schema.Choice(
+  ...     __name__='city',
+  ...     title=u'City',
+  ...     description=u'Select a city.',
+  ...     source=ItalianCitiesSourceBinder())
+
+Widget
+------
+
+  >>> class Content(object):
+  ...     city = None
+  
+  >>> content = Content()
+  >>> field = city.bind(content)
+
+  >>> from z3c.formwidget.query.widget import QuerySourceFieldWidget
+
+  >>> def setupWidget(field, context, request):
+  ...     widget = QuerySourceFieldWidget(field, request)
+  ...     widget.name = field.__name__
+  ...     return widget
+
+  >>> from z3c.form.testing import TestRequest
+  >>> request = TestRequest()
+
+An empty query is not carried out.
+  
+  >>> widget = setupWidget(field, content, request)
+  
+  >>> 'type="radio"' in widget()
+  False
+
+Let's make a query for "bologna".
+
+  >>> request = TestRequest(form={
+  ...     'city.widgets.query': u'bologna'})
+  
+  >>> widget = setupWidget(field, content, request)
+
+Verify results:
+  
+  >>> 'Bologna' in widget()
+  True
+
+  >>> 'Sorrento' in widget()
+  False
+
+We'll select 'Bologna' from the list.
+
+  >>> request = TestRequest(form={
+  ...     'city.widgets.query': u'bologna',
+  ...     'city': ('bologna',)})
+
+  >>> widget = setupWidget(field, content, request)
+
+Verify that Bologna has been selected.
+
+  >>> 'checked="checked"' in widget()
+  True
+
+Todo
+----
+
+- Functional testing with zope.testbrowser

Added: z3c.formwidget.query/trunk/src/z3c/formwidget/query/__init__.py
===================================================================
--- z3c.formwidget.query/trunk/src/z3c/formwidget/query/__init__.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/src/z3c/formwidget/query/__init__.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,2 @@
+from zope.i18nmessageid import MessageFactory
+MessageFactory = MessageFactory('z3c.formwidget.query')

Added: z3c.formwidget.query/trunk/src/z3c/formwidget/query/interfaces.py
===================================================================
--- z3c.formwidget.query/trunk/src/z3c/formwidget/query/interfaces.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/src/z3c/formwidget/query/interfaces.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,5 @@
+from zope.schema.interfaces import ISource
+
+class IQuerySource(ISource):
+    def search(query_string):
+        """Return values that match query."""

Added: z3c.formwidget.query/trunk/src/z3c/formwidget/query/tests.py
===================================================================
--- z3c.formwidget.query/trunk/src/z3c/formwidget/query/tests.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/src/z3c/formwidget/query/tests.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,27 @@
+import doctest
+import unittest
+from zope import interface, component, schema
+from zope.testing import doctestunit
+from zope.app.testing import setup
+
+def setUp(test):
+    test.globs = dict(
+        root=setup.placefulSetUp(True),
+        pprint=doctestunit.pprint,
+        interface=interface,
+        component=component,
+        schema=schema)
+        
+def tearDown(test):
+    setup.placefulTearDown()
+
+def test_suite():
+    return unittest.TestSuite((
+        doctestunit.DocFileSuite(
+            'README.txt',
+            setUp=setUp, tearDown=tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: z3c.formwidget.query/trunk/src/z3c/formwidget/query/widget.py
===================================================================
--- z3c.formwidget.query/trunk/src/z3c/formwidget/query/widget.py	                        (rev 0)
+++ z3c.formwidget.query/trunk/src/z3c/formwidget/query/widget.py	2008-04-11 00:43:40 UTC (rev 85225)
@@ -0,0 +1,113 @@
+import zope.component
+import zope.interface
+import zope.schema
+import zope.schema.interfaces
+
+from zope.app.form.browser.interfaces import ITerms
+from zope.schema.vocabulary import SimpleVocabulary
+from zope.schema.interfaces import ITitledTokenizedTerm
+from zope.schema.interfaces import ISource, IContextSourceBinder
+
+import z3c.form.interfaces
+import z3c.form.button
+import z3c.form.form
+import z3c.form.field
+import z3c.form.widget
+import z3c.form.browser.radio
+
+from z3c.formwidget.query import MessageFactory as _
+
+class QueryTerms(SimpleVocabulary):
+    zope.interface.implements(ITerms)
+    
+    def __init__(self, values):
+        terms = [ITitledTokenizedTerm.providedBy(value) and value or \
+                 ITitledTokenizedTerm(value) for value in values]
+
+        super(QueryTerms, self).__init__(terms)
+
+    def getTerm(self, value):
+        try:
+            return self.by_value[value]
+        except KeyError:
+            raise LookupError(value)
+
+    def getValue(self, token):
+        try:
+            return self.by_token[token]
+        except KeyError:
+            raise LookupError(token)
+
+class QuerySubForm(z3c.form.form.Form):
+    zope.interface.implements(z3c.form.interfaces.ISubForm)
+
+    fields = z3c.form.field.Fields(
+        zope.schema.TextLine(
+        __name__='query',
+        required=False))
+
+    def __init__(self, context, request, prefix=None):
+        super(QuerySubForm, self).__init__(context, request)
+
+        if prefix is not None:
+            self.prefix = prefix    
+
+    @z3c.form.button.buttonAndHandler(_(u"Search"))
+    def search(self, action):
+        data, errors = self.widgets.extract()
+        if not errors:
+            z3c.form.form.applyChanges(self, self.context, data)
+
+class QueryContext(object):
+    query = None
+
+class QuerySourceWidget(z3c.form.browser.radio.RadioWidget):
+    _queryform = None
+    _resultsform = None
+
+    def update(self):
+        # setup query form
+        prefix = self.name
+        
+        subform = self.subform = QuerySubForm(QueryContext(), self.request, prefix)
+        subform.update()
+
+        data, errors = subform.extractData()
+        if errors:
+            return
+
+        # query source
+        query = data['query']
+        source = self.field.source
+
+        if IContextSourceBinder.providedBy(source):
+            source = source(self.context)
+
+        assert ISource.providedBy(source)
+
+        if query is not None:
+            results = source.search(query)
+        else:
+            results = ()
+            
+        # set terms
+        self.terms = QueryTerms(results)
+
+                # update widget
+        super(QuerySourceWidget, self).update()
+        
+    def render(self):
+        subform = self.subform
+        if self.terms:
+            return "\n".join((subform.render(), super(QuerySourceWidget, self).render()))
+
+        return subform.render()
+
+    def __call__(self):
+        self.update()
+        return self.render()
+    
+ at zope.component.adapter(zope.schema.interfaces.IChoice, z3c.form.interfaces.IFormLayer)
+ at zope.interface.implementer(z3c.form.interfaces.IFieldWidget)
+def QuerySourceFieldWidget(field, request):
+    return z3c.form.widget.FieldWidget(field, QuerySourceWidget(request))



More information about the Checkins mailing list