[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