form.py :  » Database » PyDO » skunkweb-3.4.4 » pylibs » formlib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Database » PyDO 
PyDO » skunkweb 3.4.4 » pylibs » formlib » form.py
######################################################################## 
#  Copyright (C) 2002 Jacob Smullyan <smulloni@smullyan.org>
#                     Drew Csillag <drew_csillag@yahoo.com>
#  
#      You may distribute under the terms of either the GNU General
#      Public License or the SkunkWeb License, as specified in the
#      README file.
########################################################################

from containers import FieldContainer
from hooks import Hook

__all__=['UNDEF', 'Field', 'DomainField', 'Form', 'FormErrorMessage',
         'CompositeField', 'FieldProxy']

class _undef(object):
    def __str__(self):
        return "UNDEF"

    def __repr__(self):
        return "<UNDEF>"
    
UNDEF=_undef()

class Field(object):
    def __init__(self,
                 name,
                 description="",
                 default=None,
                 multiple=0,
                 setable=1):
        self.name=name
        self.description=description
        self.__multiple=multiple
        self.setable=setable
        if default==None:
            self.clearDefault()
        else:
            self._set_default(default)
        self.clearValue()
 
    def _get_default(self):
        return self._default

    def _set_default(self, default):
        self._default=self.checkValue(default)

    def clearDefault(self):
        self._default=None

    default=property(_get_default, _set_default)
        
    def _get_value(self):
        if not isinstance(self.__value, _undef):
            return self.__value
        else:
            return self.default

    def _set_value(self, value):
        self.__value=self.checkValue(value)

    def clearValue(self):
        self.__value=UNDEF

    value=property(_get_value, _set_value)
    
    def _get_multiple(self):
        return self.__multiple

    multiple=property(_get_multiple)

    def checkValue(self, value):
        isseq=isinstance(value, list) or isinstance(value, tuple)
        if self.multiple and not isseq:
            return value is not None and [value] or []
        elif isseq and not self.multiple:
            raise ValueError, "value cannot be a sequence for this field"
        return value
        
    def validate(self, form=None):
        """\
        Override to return a list of FormErrors
        """
        pass

    def _setData(self, data):
        if self.setable:
            self._set_value(data.get(self.name))
        
        
class FieldProxy(object):
    "A proxy for abstracting a proxied name out from a "\
    "field which may be known by another "\
    "name as a means of indirection"
    def __init__(self, proxyName, proxiedField):
        self._name = proxyName
        self.field = proxiedField

    def __getattr__(self, name):
        if name == 'name':
            return self._name
        else:
            return getattr(self.field, name)
        
    def _get_name(self):
        return self._name
    def _set_name(self, newname):
        self._name = newname
    name=property(_get_name, _set_name)     
        
    def _get_value(self):
        return self.field.value
    def _set_value(self, value):
        self.field.value = value
    value=property(_get_value, _set_value)

def _defaultValueComposer(fieldList):
    """\
    Generates a single 'value' by concatentating each field.value into
    a single newline delimited list
    """
    return '\n'.join([str(fld.value) for fld in fieldList])

class CompositeField(Field):

    "Represents a composite group of fields which are logically"\
    "grouped beneath a single name"

    def __init__(self,
                 name,
                 description="",
                 default=None,
                 multiple=1,
                 setable=1,
                 componentFields=None,
                 componentFieldDelimiter='_',
                 valueComposer=_defaultValueComposer):
        Field.__init__(self,
                       name=name,
                       description=description,
                       default=default,
                       multiple=multiple,
                       setable=setable)
        self.delimiter = componentFieldDelimiter
        if componentFields is None:
            componentFields=[]

        tmpComponents = []
        for fld in componentFields:
            prxy = FieldProxy(self._getComponentName(fld), fld)
            tmpComponents.append(prxy)
        self._fields = FieldContainer(tmpComponents,
                                          fieldmapper=_getname,
                                          storelists=0)
        self.errors=FieldContainer(fieldmapper=_getfield,
                                   storelists=1)
        self.composeValue = valueComposer
                
    def _get_fields(self):
        return self._fields
    fields=property(_get_fields)

    def _getComponentName(self, x):
        """
        Method for generating the keys by which fields are indexed
        within the composite field
        """
        return "%s%s%s" % (self.name, self.delimiter, x.name)

    def _get_value(self):
        """
        The value of a composite field is the result of calling the
        valueComposer on the composite field's component fields.
        """
        return self.composeValue(self.fields)
    value=property(_get_value)
    
    def _setData(self, data):
        if self.setable:
            for ky in data.keys():
                if self.fields.has_key(ky):
                    chgfld = self.fields[ky]
                    chgfld.value = data.get(ky)

class DomainField(Field):
    """
    a variety of field in which the
    the possible values of the field consist
    of an enumeration or menu. 
    """
    def __init__(self,
                 name,
                 domain,
                 description="",
                 default=None,
                 multiple=0,
                 setable=1,
                 lenient=0):
        self.__domain=domain
        self.lenient=lenient
        Field.__init__(self, name, description, default, multiple, setable)
        
    def _get_domain(self):
        return self.__domain

    def _set_domain(self, domain):
        if self.default is not None \
               and not self.in_domain(self.default, domain):
            raise ValueError, \
                  "pre-existing default conflicts with new domain; "\
                  "clear the default before setting domain"
        self.__domain=domain

    domain=property(_get_domain, _set_domain)

    def in_domain(self, value, domain=None):
        if self.lenient:
            return 1
        if (self.multiple and value==[]) or \
           ((not self.multiple) and value==None):
            return 1
        if not domain:
            domain=self.domain
        if value in domain:
            return 1
        if self.multiple and \
               (isinstance(value, list) or isinstance(value, tuple)):
            return reduce(lambda x, y: x and y,
                          [i in domain for i in value])
        return 0

    def checkValue(self, value):
        """
        determines whether the value is permissible for the field.
        This is not meant to perform validation of user input,
        but to prevent programmatic errors.
        """
        value=Field.checkValue(self, value)
        if not self.in_domain(value):
            raise ValueError, "value for '%s' not present in domain: %s" % (self.name, value)
        return value

class Form(object):
    def __init__(self,
                 name=None,
                 method='POST',
                 action="",
                 enctype=None,
                 fields=None,
                 validators=None,
                 processors=None):
        self.name=name
        self.method=method
        self.action=action
        self.enctype=enctype
        self._set_fields(fields)
        self.validators=validators or []
        self.processHook=Hook(processors or [])
        self.submitted=None
        self.errors=FieldContainer(fieldmapper=_getfield,
                                   storelists=1)
        self.state=None

    
    def _get_fields(self):
        return self._fields

    def _set_fields(self, fields):
        self._fields=FieldContainer(fields or [],
                                    fieldmapper=_getname,
                                    storelists=0)

    fields=property(_get_fields, _set_fields)


    def getData(self, prune=1):
        d={}
        for k, v in self.fields.iteritems():
            if prune and k.startswith('_') or not v.setable:
                continue
            d[k]=v.value
        return d

    def setData(self, data):
        for f in self.fields:
            f._setData(data)

    def submit(self, data):
        self.reset()
        self.setData(data)
        self.submitted=1
        self.validate()

    def reset(self):
        for f in self.fields:
            f.clearValue()
        self.submitted=0
        self.errors[:]=[]
        self.state=None
        
    def validate(self):
        self.errors[:]=[]
        for l in ([f.validate for f in self.fields], self.validators):
            for func in l:
                e=func(self)
                if e:
                    self.errors.extend(e)

    def process(self,
                *args,
                **kwargs):
        return self.processHook(self, *args, **kwargs)
    
def _getname(x):
    return x.name

class FormErrorMessage(object):
    def __init__(self, field, errormsg):
        self.field=field
        self.errormsg=errormsg

def _getfield(x):
    return x.field

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.