Source code for uw.web.wsgi.form
"""HTML form result handling.
Routines for easily creating WSGI handlers which handle HTML form results.
"""
from operator import attrgetter
from .delegate import DelegateHandler
from .parameter import get_form_fields as delegate_get_form_fields, ParamHandler
[docs]class CGIFormResults (dict):
"""A representation of the form results component of a CGI request.
:param cgi.FieldStorage cgi_fields: The values to be inserted into
this form results dictionary.
"""
def __init__ (self, cgi_fields):
super (CGIFormResults, self).__init__ ()
if cgi_fields.list is not None:
for item in cgi_fields.list:
if item.name not in self:
self[item.name] = []
self[item.name].append (item)
def __missing__ (self, name):
return []
[docs] def optional_field (self, name):
"""Obtain an optional field from the CGI results.
:param name: the name of the field.
Return the single result for the named field, or None if there are
none. If there are multiple results, an exception will be raised.
"""
if name in self:
(result,) = self[name]
return result
else:
return None
[docs] def optional_field_value (self, name):
"""Obtain an optional field value from the CGI results.
:param name: the name of the field.
Return the value of the single result for the named field, or None if
there are none. If there are multiple results, an exception will be
raised.
"""
result = self.optional_field (name)
return None if result is None else result.value
[docs] def required_field (self, name):
"""Obtain a required field from the CGI results.
:param name: the name of the field.
Return the single result for the named field, or raise an exception if
there are none. If there are multiple results, an exception will be
raised.
"""
(result,) = self[name]
return result
[docs] def required_field_value (self, name):
"""Obtain a required field value from the CGI results.
:param name: the name of the field.
Return the value of the single result for the named field, or raise an
exception if there are none. If there are multiple results, an
exception will be raised.
"""
return self.required_field (name).value
[docs] def multiple_field (self, name):
"""Obtain a multiple field from the CGI results.
:param name: the name of the field.
Return a list of all results for the named field.
"""
return self[name]
[docs] def multiple_field_value (self, name):
"""Obtain multiple field values from the CGI results.
:param name: the name of the field.
Return a list of the values of all the results for the named field.
"""
return list(map (attrgetter ('value'), self.multiple_field (name)))
[docs]def get_form_fields (environ):
"""Extract submitted HTML form results from the WSGI environment.
:param environ: the WSGI environment.
Builds a CGIFormResults from the wsgi.input environment entry.
"""
return CGIFormResults (delegate_get_form_fields (environ))
[docs]def use_form_param (handler):
"""Wrap a hander; extract form variable values as a parameter.
Returns a handler which constructs a CGIFormResults dictionary and save it
in the 'form' parameter before chaining to the provided handler.
"""
return ParamHandler (handler, 'form', get_form_fields)
[docs]def parse_form_value (value, parser):
"""Parse a form value in a way that is usually appropriate.
:param value: the string value, typically obtained from the form
results.
:param parser: the parser to convert a non-empty string into a typed
result.
The value may be None or a string. If it is None or a blank string then
None is returned. Otherwise the value, stripped of leading and trailing
whitespace, is passed to the parser and the result returned.
Typically parsers include the standard float and int functions.
"""
if value is None:
return None
value = value.strip ()
if not value:
return None
return parser (value)
#def delegate_field (name, main_handler, value_handler):
# def delegate_field_handler (form, **params):
# if form.has_key (name):
# return value_handler ...
# else:
# return main_handler ...
# return delegate_field_handler
[docs]class DelegateField (DelegateHandler):
"""Delegate to an inner handler based on a CGI field value.
:param page_handler: The handler for requests with none of the specified
fields present.
:param get_form_handler(\*\*field_values): The handler for requests with
the given values for the specified fields.
:param fields: A dictionary from field names to the procedure to use to
extract the field value from the CGIFormResults form value. Typical
values include CGIFormResults.optional_field_value and friends.
"""
def __init__ (self, page_handler, get_form_handler, fields):
self.__page_handler = page_handler
self.__get_form_handler = get_form_handler
self.__fields = fields
@property
def page_handler (self):
return self.__page_handler
@property
def get_form_handler (self):
return self.__get_form_handler
@property
def fields (self):
return self.__fields
[docs] def get_handler (self, environ):
"""Get the handler which will be used to handle the specified request.
"""
form = get_params (environ)['form']
field_values = {}
for name, field in self.fields.entries ():
field_values[name] = field.get_field (form, name)
return self.get_form_handler (**field_values)
#def make_form_handler (parse_form, render_form, action):
# def get_handler ():
# form_value = parse_form (form)
# return title, render_form (form_value)
#
# def post_handler ():
# form_value = parse_form (form)
# try:
# result = action (form_value)
# return title, result
# except FormActionError, x:
# return title, [x.format (), render_form (form_value)]
#
# return delegate_get_post (get_handler, post_handler)