0001from cStringIO import StringIO
0002import cgi
0003import urllib
0004from httpencode.format import Format
0005
0006def load_form(fp, content_type):
0007    environ = {
0008        'REQUEST_METHOD': 'POST',
0009        'CONTENT_TYPE': content_type,
0010        'QUERY_STRING': '',
0011        }
0012    if hasattr(fp, 'file'):
0013        # Unwrap, because we know we won't read past the end
0014        environ['CONTENT_LENGTH'] = fp.length
0015        fp = fp.file
0016    else:
0017        # We really need to get the content length :(
0018        data = fp.read()
0019        fp = StringIO(data)
0020        environ['CONTENT_LENGTH'] = len(data)
0021    fs = cgi.FieldStorage(fp=fp,
0022                          environ=environ,
0023                          keep_blank_values=1)
0024    return fs
0025
0026def dump_form_iter(data, content_type):
0027    if isinstance(data, cgi.FieldStorage):
0028        # @@: We don't deal with MiniFieldStorage; should we?
0029        data = [
0030            (field.name, field.value)
0031            for field in data.list]
0032    elif hasattr(data, 'items'):
0033        # Allow for dictionaries
0034        data = data.items()
0035    # We should update headers to be multipart/form-data if there was
0036    # a file upload of some sort
0037    return [urllib.urlencode(data, doseq=True)]
0038
0039# We should figure out when to get dump to multipart/form-data
0040form = Format(
0041    'form', ['application/x-www-form-urlencoded', 'multipart/form-data'],
0042    type='cgi.FieldStorage',
0043    load=load_form,
0044    dump_iter=dump_form_iter,
0045    secure=True)
0046
0047# @@: This should be a multidict:
0048def load_pyform(fp, content_type):
0049    fs = load_form(fp, content_type)
0050    result = {}
0051    for field in fs.list:
0052        if field.name in result:
0053            if not isinstance(result[field.name], list):
0054                result[field.name] = [result[field.name], field.value]
0055            else:
0056                result[field.name].append(field.value)
0057        else:
0058            result[field.name] = field.value
0059    return result
0060
0061def dump_pyform_iter(data, content_type):
0062    return dump_form_iter(data, content_type)
0063
0064pyform = Format(
0065    'pyform', ['application/x-www-form-urlencoded', 'multipart/form-data'],
0066    type='python',
0067    load=load_pyform,
0068    dump_iter=dump_pyform_iter,
0069    secure=True)