Commits

Lynn Rees committed 6113bbd

[svn]

Comments (0)

Files changed (3)

branches/0.2/wsgiform.py

-# Copyright (c) 2006 L. C. Rees
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-#    1. Redistributions of source code must retain the above copyright notice, 
-#       this list of conditions and the following disclaimer.
-#    
-#    2. Redistributions in binary form must reproduce the above copyright 
-#       notice, this list of conditions and the following disclaimer in the
-#       documentation and/or other materials provided with the distribution.
-#
-#    3. Neither the name of WsgiForm nor the names of its contributors may be used
-#       to endorse or promote products derived from this software without
-#       specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-'''WSGI middleware for parsing form data into dictionaries, individual environ
-entries, cgi.FieldStorage instances, or keyword arguments that can be passed to
-WSGI applications in the environ dictionary. Features include hooks for form
-validation, escaping, and data sterilization.
-'''
-
-import cgi, re, string
-from xml.sax import saxutils
-
-_trans = string.maketrans('', '')
-_zip = re.compile(r'(^\d{5}$)|(^\d{5}-*\d{4}$)')
-_ip4 = re.compile('r^[1-2]{0,1}[1-9]{0,1}[$')
-
-def _hyperescape(data):
-    '''Escapes punctuation with HTML entities except ., -, and _.'''
-    # Escape &
-    data = re.sub(r'&(?!#\d\d;)', '&', data)
-    # Escape ;
-    data = re.sub(r'(?<!&#\d\d);', '&#59;', data)
-    # Escape #
-    data = re.sub(r'(?<!&)#(?!\d\d;)', '&#35;', data)
-    # Escape other chars except ., -, and _
-    for char in '<>"\'()!${}*+,%/:=?@[\\]^`|~':
-        data = data.replace(char, '&#%d;' % ord(char))
-    return data
-
-def _escape(data):
-    '''Escapes &, <, >, ", and ' with HTML entities.'''
-    return saxutils.escape(data, {'"':"&quot;", "'":'&#39;'})
-
-def _sterilize(data):
-    '''Removes all ASCII characters except alphanums, ., -, and _.'''
-    return data.translate(_trans, '&#;<>"\'()!${}*+,%/:=?@[\\]^`|~')
-
-def _runfunc(qdict, func):
-    '''Runs a function on a dictionary.'''
-    # Handle single entries
-    for key, value in qdict.iteritems():
-        if isinstance(value, basestring):
-            qdict[key] = func(value)
-        # Handle lists
-        elif isinstance(value, list):
-            for num, item in enumerate(value):
-                if isinstance(value, basestring): value[num] = func(value)
-    return qdict
-
-def extract(environ, strict=False):
-    '''Extracts strings in form data.'''
-    qdict = cgi.parse(environ['wsgi.input'], environ, strict, strict)
-    for key, value in qdict.iteritems():
-        if len(value) == 1: qdict[key] = value[0]
-    return qdict
-
-def escape(environ, strict=False):
-    '''Escapes XML/HTML in form data.'''    
-    return _runfunc(extract(environ, strict), _escape) 
-
-def hyperescape(environ, strict=False):
-    '''Hyperescapes XML/HTML in form data.'''    
-    return _runfunc(extract(environ, strict), _hyperescape) 
-
-def sterilize(environ, strict=False):
-    '''Removes all form data characters except alphanumerics, ., -, and _.'''
-    return _runfunc(extract(environ, strict), _sterilize)
-
-def istext(text):
-    return isinstance(text, basestring)
-
-def isint(num):
-    return isinstance(int(num), num)
-
-def islength(data, length):
-    return len(data) == length
-
-def iszipcode(data):
-    if _zip.match(data): return True
-    
-
-
-class WsgiForm(object):
-
-    '''Class that parsing form data into dictionaries, individual environ entries,
-    cgi.FieldStorage instances, or keyword arguments that can be passed to WSGI
-    applications in the environ dictionary. 
-    '''
-
-    _keys = {'fieldstorage':'wsgiform.fieldstorage', 'dict':'wsgiform.dict',
-        'kwargs':'wsgize.kwargs', 'environ':'wsgiform.%s'}
-    _funclist = {'escape':escape, 'hyperescape':hyperescape, 'sterilize':sterilize} 
-
-    def __init__(self, app, **kw):
-        '''@param app WSGI callable
-        @param kw Keyword arguments.'''
-        self._app = app
-        # Style and key for form data passing format
-        self._style = kw.get('style', 'dict')
-        self._key = self._keys.get(self._style)
-        # Dictionary of validators where the keywords are form field names 
-        self._validators = kw.get('validators', {})
-        # Stop on errors or empty fields
-        self._strict = kw.get('strict', False)
-        # Function to escape metachars
-        self._func = self._funclist[(kw.get('func', 'escape'))]
-        # Function to handle form validation errors
-        self._errorhandler = kw.get('errapp', self._errapp)
-        
-    def __call__(self, env, start_return):
-        '''Call function.'''
-        # Return fieldstorage
-        if self._style == 'fieldstorage':
-            env[self._key] = cgi.FieldStorage(fp=env['wsgi.input'], environ=env)
-        else:
-            qdict = self._func(env, self._strict)
-            if self._validators:
-                if not self._validate(qdict):
-                    return self._errorhandler(environ, start_return)                    
-            # Make individual environ entries
-            if self._style == 'environ':
-                for k, v in qdict.iteritems(): env[self._key % k] = v
-            # Make kwargs or dict
-            else:
-                env[self._key] = qdict
-        return self._app(env, start_return)    
-    
-    def _validate(self, qdict):
-        '''Validates form data.
-
-        qdict Dictionary of validators indexed by form field        
-        '''
-        for key, value in qdict.iteritems():
-            try:
-                if not self._validators[key](value): return False                    
-            except KeyError: pass
-        return True
-
-    def _errorapp(self, environ, start_return):
-        start_return('200 OK', ('Content-type', 'text/plain'))
-        return ['Data in form was invalid.']
-
-def form(**kw):
-    '''Decorator for form processing.'''
-    def decorator(application):
-        return WsgiForm(application, **kw)
-    return decorator            
-     
-
-__all__ = ['WsgiForm', 'form']

branches/0.2/wsgiform/form.py

+# Copyright (c) 2006 L. C. Rees
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+#    1. Redistributions of source code must retain the above copyright notice, 
+#       this list of conditions and the following disclaimer.
+#    
+#    2. Redistributions in binary form must reproduce the above copyright 
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#
+#    3. Neither the name of WsgiForm nor the names of its contributors may be used
+#       to endorse or promote products derived from this software without
+#       specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+'''WSGI middleware for parsing form data into dictionaries, individual environ
+entries, cgi.FieldStorage instances, or keyword arguments that can be passed to
+WSGI applications in the environ dictionary. Features include hooks for form
+validation, escaping, and data sterilization.
+'''
+
+import cgi, re, string
+from xml.sax import saxutils
+
+_trans = string.maketrans('', '')
+_zip = re.compile(r'(^\d{5}$)|(^\d{5}-*\d{4}$)')
+_ip4 = re.compile('r^[1-2]{0,1}[1-9]{0,1}[$')
+
+def _hyperescape(data):
+    '''Escapes punctuation with HTML entities except ., -, and _.'''
+    # Escape &
+    data = re.sub(r'&(?!#\d\d;)', '&#38;', data)
+    # Escape ;
+    data = re.sub(r'(?<!&#\d\d);', '&#59;', data)
+    # Escape #
+    data = re.sub(r'(?<!&)#(?!\d\d;)', '&#35;', data)
+    # Escape other chars except ., -, and _
+    for char in '<>"\'()!${}*+,%/:=?@[\\]^`|~':
+        data = data.replace(char, '&#%d;' % ord(char))
+    return data
+
+def _escape(data):
+    '''Escapes &, <, >, ", and ' with HTML entities.'''
+    return saxutils.escape(data, {'"':"&quot;", "'":'&#39;'})
+
+def _sterilize(data):
+    '''Removes all ASCII characters except alphanums, ., -, and _.'''
+    return data.translate(_trans, '&#;<>"\'()!${}*+,%/:=?@[\\]^`|~')
+
+def _runfunc(qdict, func):
+    '''Runs a function on a dictionary.'''
+    # Handle single entries
+    for key, value in qdict.iteritems():
+        if isinstance(value, basestring):
+            qdict[key] = func(value)
+        # Handle lists
+        elif isinstance(value, list):
+            for num, item in enumerate(value):
+                if isinstance(value, basestring): value[num] = func(value)
+    return qdict
+
+def extract(environ, strict=False):
+    '''Extracts strings in form data.'''
+    qdict = cgi.parse(environ['wsgi.input'], environ, strict, strict)
+    for key, value in qdict.iteritems():
+        if len(value) == 1: qdict[key] = value[0]
+    return qdict
+
+def escape(environ, strict=False):
+    '''Escapes XML/HTML in form data.'''    
+    return _runfunc(extract(environ, strict), _escape) 
+
+def hyperescape(environ, strict=False):
+    '''Hyperescapes XML/HTML in form data.'''    
+    return _runfunc(extract(environ, strict), _hyperescape) 
+
+def sterilize(environ, strict=False):
+    '''Removes all form data characters except alphanumerics, ., -, and _.'''
+    return _runfunc(extract(environ, strict), _sterilize)
+
+def istext(text):
+    return isinstance(text, basestring)
+
+def isint(num):
+    return isinstance(int(num), num)
+
+def islength(data, length):
+    return len(data) == length
+
+def iszipcode(data):
+    if _zip.match(data): return True
+    
+
+
+class WsgiForm(object):
+
+    '''Class that parsing form data into dictionaries, individual environ entries,
+    cgi.FieldStorage instances, or keyword arguments that can be passed to WSGI
+    applications in the environ dictionary. 
+    '''
+
+    _keys = {'fieldstorage':'wsgiform.fieldstorage', 'dict':'wsgiform.dict',
+        'kwargs':'wsgize.kwargs', 'environ':'wsgiform.%s'}
+    _funclist = {'escape':escape, 'hyperescape':hyperescape, 'sterilize':sterilize} 
+
+    def __init__(self, app, **kw):
+        '''@param app WSGI callable
+        @param kw Keyword arguments.'''
+        self._app = app
+        # Style and key for form data passing format
+        self._style = kw.get('style', 'dict')
+        self._key = self._keys.get(self._style)
+        # Dictionary of validators where the keywords are form field names 
+        self._validators = kw.get('validators', {})
+        # Stop on errors or empty fields
+        self._strict = kw.get('strict', False)
+        # Function to escape metachars
+        self._func = self._funclist[(kw.get('func', 'escape'))]
+        # Function to handle form validation errors
+        self._errorhandler = kw.get('errapp', self._errapp)
+        
+    def __call__(self, env, start_return):
+        '''Call function.'''
+        # Return fieldstorage
+        if self._style == 'fieldstorage':
+            env[self._key] = cgi.FieldStorage(fp=env['wsgi.input'], environ=env)
+        else:
+            qdict = self._func(env, self._strict)
+            if self._validators:
+                if not self._validate(qdict):
+                    return self._errorhandler(environ, start_return)                    
+            # Make individual environ entries
+            if self._style == 'environ':
+                for k, v in qdict.iteritems(): env[self._key % k] = v
+            # Make kwargs or dict
+            else:
+                env[self._key] = qdict
+        return self._app(env, start_return)    
+    
+    def _validate(self, qdict):
+        '''Validates form data.
+
+        qdict Dictionary of validators indexed by form field        
+        '''
+        for key, value in qdict.iteritems():
+            try:
+                if not self._validators[key](value): return False                    
+            except KeyError: pass
+        return True
+
+    def _errorapp(self, environ, start_return):
+        start_return('200 OK', ('Content-type', 'text/plain'))
+        return ['Data in form was invalid.']
+
+def form(**kw):
+    '''Decorator for form processing.'''
+    def decorator(application):
+        return WsgiForm(application, **kw)
+    return decorator            
+     
+
+__all__ = ['WsgiForm', 'form']

branches/0.2/wsgiform/validators.py

Empty file added.