[Checkins] SVN: Sandbox/dirceu/megrok.form/ Adding megrok.form.
megrok.form is a helper package that provides some very
useful fields, widgets and constraints for Grok.
Dirceu Pereira Tiegs
dirceutiegs at gmail.com
Tue Jan 29 19:40:35 EST 2008
Log message for revision 83310:
Adding megrok.form. megrok.form is a helper package that provides some very useful fields, widgets and constraints for Grok.
Changed:
A Sandbox/dirceu/megrok.form/
A Sandbox/dirceu/megrok.form/buildout.cfg
A Sandbox/dirceu/megrok.form/setup.py
A Sandbox/dirceu/megrok.form/src/
A Sandbox/dirceu/megrok.form/src/megrok/
A Sandbox/dirceu/megrok.form/src/megrok/__init__.py
A Sandbox/dirceu/megrok.form/src/megrok/form/
A Sandbox/dirceu/megrok.form/src/megrok/form/README.txt
A Sandbox/dirceu/megrok.form/src/megrok/form/__init__.py
A Sandbox/dirceu/megrok.form/src/megrok/form/app.py
A Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml
A Sandbox/dirceu/megrok.form/src/megrok/form/fields.py
A Sandbox/dirceu/megrok.form/src/megrok/form/interfaces.py
A Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml
A Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py
A Sandbox/dirceu/megrok.form/src/megrok/form/validators.py
-=-
Property changes on: Sandbox/dirceu/megrok.form
___________________________________________________________________
Name: svn:ignore
+
bin
develop-eggs
parts
.installed.cfg
src/megrok.widget.egg-info
Added: Sandbox/dirceu/megrok.form/buildout.cfg
===================================================================
--- Sandbox/dirceu/megrok.form/buildout.cfg (rev 0)
+++ Sandbox/dirceu/megrok.form/buildout.cfg 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,68 @@
+[buildout]
+develop = .
+parts = app data zopectl i18n test
+find-links = http://download.zope.org/distribution/
+newest = false
+extends= http://grok.zope.org/releaseinfo/grok-0.11.1.cfg
+versions = versions
+
+[data]
+recipe = zc.recipe.filestorage
+
+[app]
+recipe = zc.zope3recipes>=0.5.3:application
+eggs = megrok.form
+site.zcml = <include package="megrok.form" />
+ <include package="zope.app.twisted" />
+
+ <configure i18n_domain="megrok.form">
+ <unauthenticatedPrincipal id="zope.anybody"
+ title="Unauthenticated User" />
+ <unauthenticatedGroup id="zope.Anybody"
+ title="Unauthenticated Users" />
+ <authenticatedGroup id="zope.Authenticated"
+ title="Authenticated Users" />
+ <everybodyGroup id="zope.Everybody"
+ title="All Users" />
+ <principal id="zope.manager"
+ title="Manager"
+ login="admin"
+ password_manager="Plain Text"
+ password="admin"
+ />
+
+ <!-- Replace the following directive if you don't want
+ public access -->
+ <grant permission="zope.View"
+ principal="zope.Anybody" />
+ <grant permission="zope.app.dublincore.view"
+ principal="zope.Anybody" />
+
+ <role id="zope.Manager" title="Site Manager" />
+ <role id="zope.Member" title="Site Member" />
+ <grantAll role="zope.Manager" />
+ <grant role="zope.Manager"
+ principal="zope.manager" />
+ </configure>
+
+[data]
+recipe = zc.recipe.filestorage
+
+# this section named so that the start/stop script is called bin/zopectl
+[zopectl]
+recipe = zc.zope3recipes:instance
+application = app
+zope.conf = ${data:zconfig}
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = megrok.form
+defaults = ['--tests-pattern', '^f?tests$', '-v']
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = lovely.recipe:i18n
+package = megrok.form
+domain = megrok.form
+location = src/megrok.form
+output = locales
Added: Sandbox/dirceu/megrok.form/setup.py
===================================================================
--- Sandbox/dirceu/megrok.form/setup.py (rev 0)
+++ Sandbox/dirceu/megrok.form/setup.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,33 @@
+from setuptools import setup, find_packages
+
+version = '0.1'
+
+setup(name='megrok.form',
+ version=version,
+ description="",
+ long_description="""\
+""",
+ # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+ classifiers=[],
+ keywords="",
+ author="Dirceu Pereira Tiegs",
+ author_email="dirceutiegs at gmail.com",
+ url="",
+ license="ZPL",
+ package_dir={'': 'src'},
+ namespace_packages=['megrok'],
+ packages=find_packages('src'),
+ include_package_data=True,
+ zip_safe=False,
+ install_requires=['setuptools',
+ 'grok',
+ 'zc.resourcelibrary',
+ 'z3c.widget',
+ 'zc.datetimewidget',
+ 'collective.namedfile',
+ # Add extra requirements here
+ ],
+ entry_points="""
+ # Add entry points here
+ """,
+ )
Property changes on: Sandbox/dirceu/megrok.form/src
___________________________________________________________________
Name: svn:ignore
+
megrok.form.egg-info
Property changes on: Sandbox/dirceu/megrok.form/src/megrok
___________________________________________________________________
Name: svn:ignore
+
*.pyc
Added: Sandbox/dirceu/megrok.form/src/megrok/__init__.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/__init__.py (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/__init__.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,6 @@
+# namespace package boilerplate
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Property changes on: Sandbox/dirceu/megrok.form/src/megrok/form
___________________________________________________________________
Name: svn:ignore
+
*.pyc
Added: Sandbox/dirceu/megrok.form/src/megrok/form/README.txt
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/README.txt (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/README.txt 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,41 @@
+===========
+megrok.form
+===========
+
+:Author: Dirceu Pereira Tiegs
+
+megrok.form is a helper package that provides some very useful fields, widgets and validation methods for Grok.
+
+Fields
+------
+
+- Email, a TextLine field with a default validator (contraint);
+- HTML, a Text field that uses z3c.widget.tiny;
+- File, from collective.namedfile;
+- Image, from collective.namedfile;
+
+Widgets
+-------
+
+megrok.form overrides the default widgets for:
+
+- zope.interface.schema.Date (using zc.datetimewidget.widget.DateWidget);
+- zope.interface.schema.Datetime (using zc.datetimewidget.widget.DatetimeWidget);
+
+Validators / Constraints
+------------------------
+
+megrok.form add validators for:
+
+- SSN
+- US Phone Numbers;
+- International Phone Numbers;
+- Zip Code
+- URL
+- Email
+
+TODO
+----
+
+- Remove "app.py" and add some automated tests;
+- Release the egg on cheeseshop.
\ No newline at end of file
Added: Sandbox/dirceu/megrok.form/src/megrok/form/__init__.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/__init__.py (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/__init__.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1 @@
+# this directory is a package
Added: Sandbox/dirceu/megrok.form/src/megrok/form/app.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/app.py (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/app.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,44 @@
+import grok
+from zope import interface, schema
+from megrok.form.fields import Email, Image, HTML, File
+
+class megrokform_test(grok.Application, grok.Container):
+ pass
+
+class IPerson(interface.Interface):
+ """ A simple class used to show how to use widgets and fields from megrok.form
+ """
+ name = schema.TextLine(title=u"Name")
+ email = Email(title=u"Email")
+ picture = Image(title=u"Picture")
+ description = HTML(title=u"Description")
+ birthday = schema.Date(title=u"Birthday")
+ resume = File(title=u"Resume")
+
+class Person(grok.Model):
+ interface.implements(IPerson)
+
+ def __init__(self, name, email, picture, description, birthday, resume):
+ self.name = name
+ self.email = email
+ self.picture = picture
+ self.description = description
+ self.birthday = birthday
+ self.resume = resume
+
+class AddPerson(grok.AddForm):
+ grok.context(megrokform_test)
+ form_fields = grok.AutoFields(Person)
+
+ @grok.action('Add person')
+ def add(self, **data):
+ obj = Person(**data)
+ name = data['name'].lower().replace(' ', '_')
+ self.context[name] = obj
+
+class Edit(grok.EditForm):
+ grok.context(Person)
+ form_fields = grok.AutoFields(Person)
+
+class Index(grok.DisplayForm):
+ grok.context(Person)
Added: Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/configure.zcml 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,22 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+ xmlns:grok="http://namespaces.zope.org/grok">
+
+ <include package="zope.app.component" file="meta.zcml" />
+ <include package="zope.app.pagetemplate" file="meta.zcml" />
+ <include package="zc.resourcelibrary" file="meta.zcml" />
+ <include package="zc.resourcelibrary" />
+
+ <include package="z3c.widget.tiny" />
+
+ <include package="zc.datetimewidget" file="overrides.zcml" />
+ <include package="zc.datetimewidget" />
+
+ <include package="zope.app.publisher.browser" file="meta.zcml" />
+ <include package="collective.namedfile" />
+
+ <include file="overrides.zcml" />
+
+ <include package="grok" />
+ <grok:grok package="." />
+
+</configure>
Added: Sandbox/dirceu/megrok.form/src/megrok/form/fields.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/fields.py (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/fields.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,13 @@
+from zope import interface, schema
+from collective.namedfile.field import NamedImage as Image
+from collective.namedfile.field import NamedFile as File
+import validators
+import interfaces
+
+class Email(schema.TextLine):
+ def __init__(self, **kw):
+ kw['constraint'] = validators.isEmail
+ super(Email, self).__init__(**kw)
+
+class HTML(schema.Text):
+ interface.implements(interfaces.IHTML)
\ No newline at end of file
Added: Sandbox/dirceu/megrok.form/src/megrok/form/interfaces.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/interfaces.py (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/interfaces.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,4 @@
+from zope import schema
+
+class IHTML(schema.interfaces.ITextLine):
+ u"""Field containing a HTML unicode string."""
\ No newline at end of file
Added: Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/overrides.zcml 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,19 @@
+<configure xmlns='http://namespaces.zope.org/zope'
+ xmlns:browser='http://namespaces.zope.org/browser'>
+
+ <view
+ type="zope.publisher.interfaces.browser.IBrowserRequest"
+ for=".interfaces.IHTML"
+ provides="zope.app.form.interfaces.IInputWidget"
+ factory="z3c.widget.tiny.widget.TinyWidget"
+ permission="zope.Public"
+ />
+
+ <browser:page
+ for="grok.interfaces.IGrokForm"
+ name="file"
+ class="collective.namedfile.browser.FileViewDispatcher"
+ permission="zope.Public"
+ />
+
+</configure>
Added: Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/test_validators.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,46 @@
+import unittest
+import validators
+
+class TestValidation(unittest.TestCase):
+
+ def test_isSSN(self):
+ v = validators.isSSN
+ self.failUnlessEqual(v('111223333'), True)
+ self.failUnlessEqual(v('111-22-3333', ignore=r'-'), True)
+
+ def test_isUSPhoneNumber(self):
+ v = validators.isUSPhoneNumber
+ self.failUnlessEqual(v('(212) 555-1212',
+ ignore=r'[\s\(\)\-]'), True)
+ self.failUnlessEqual(v('2125551212',
+ ignore=r'[\s\(\)\-]'), True)
+
+ self.failUnlessEqual(v('(212) 555-1212'), True)
+
+ def test_isInternationalPhoneNumber(self):
+ v = validators.isInternationalPhoneNumber
+ self.failUnlessEqual(v('+1 713 942 2377'), True)
+ self.failUnlessEqual(v('+1 832 201 8856'), True)
+
+ def test_isZipCode(self):
+ v = validators.isZipCode
+ self.failUnlessEqual(v('03750'), True)
+ self.failUnlessEqual(v('33701-4313', ignore=r'-'), True)
+
+ def test_isURL(self):
+ v = validators.isURL
+ self.failUnlessEqual(v('http://foo.bar:8080/manage'), True)
+ self.failUnlessEqual(v('https://foo.bar:8080/manage'), True)
+ self.failUnlessEqual(v('irc://tiran@irc.freenode.net:6667/#plone'), True)
+ self.failUnlessEqual(v('fish://tiran:password@myserver/~/'), True)
+ self.failIfEqual(v('http://\n'), True)
+ self.failIfEqual(v('../foo/bar'), True)
+
+ def test_isEmail(self):
+ v = validators.isEmail
+ self.failUnlessEqual(v('test at test.com'), True)
+ self.failIfEqual(v('@foo.bar'), True)
+ self.failIfEqual(v('me'), True)
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
Added: Sandbox/dirceu/megrok.form/src/megrok/form/validators.py
===================================================================
--- Sandbox/dirceu/megrok.form/src/megrok/form/validators.py (rev 0)
+++ Sandbox/dirceu/megrok.form/src/megrok/form/validators.py 2008-01-30 00:40:34 UTC (rev 83310)
@@ -0,0 +1,48 @@
+import re
+
+def validate_expression(value, expression, **kwargs):
+ ignore = kwargs.get('ignore', None)
+ if ignore:
+ if isinstance(ignore, basestring):
+ ignore = re.compile(ignore)
+ value = ignore.sub('', value)
+ if expression.match(value):
+ return True
+ return False
+
+def isSSN(value, **kwargs):
+ expr = re.compile(r'^\d{9}$')
+ errmsg = 'is not a well formed SSN.'
+ return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+
+def isUSPhoneNumber(value, **kwargs):
+ expr = re.compile(r'^\d{10}$')
+ if not kwargs.get('ignore', None):
+ kwargs['ignore'] = re.compile(r'[\(\)\-\s]')
+ errmsg = 'is not a valid us phone number.'
+ return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+
+def isInternationalPhoneNumber(value, **kwargs):
+ expr = re.compile(r'^\d+$')
+ if not kwargs.get('ignore', None):
+ kwargs['ignore'] = re.compile(r'[\(\)\-\s\+]')
+ errmsg = 'is not a valid international phone number.'
+ return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+
+def isZipCode(value, **kwargs):
+ expr = re.compile(r'^(\d{5}|\d{9})$')
+ errmsg = 'is not a valid zip code.'
+ return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+
+def isURL(value, **kwargs):
+ protocols = ('http', 'ftp', 'irc', 'news', 'imap', 'gopher', 'jabber',
+ 'webdav', 'smb', 'fish', 'ldap', 'pop3', 'smtp', 'sftp', 'ssh'
+ )
+ expr = re.compile(r'(%s)s?://[^\s\r\n]+' % '|'.join(protocols))
+ errmsg = 'is not a valid url.'
+ return validate_expression(value, expr, errmsg=errmsg, **kwargs)
+
+def isEmail(value, **kwargs):
+ expr = re.compile(r"^(\w&.%#$&'\*+-/=?^_`{}|~]+!)*[\w&.%#$&'\*+-/=?^_`{}|~]+@(([0-9a-z]([0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,6}|([0-9]{1,3}\.){3}[0-9]{1,3})$", re.IGNORECASE)
+ errmsg = 'is not a valid email address.'
+ return validate_expression(value, expr, errmsg=errmsg, **kwargs)
\ No newline at end of file
More information about the Checkins
mailing list