summaryrefslogtreecommitdiff
path: root/paste/wareweb/cgifields.py
blob: f838447c4f45c1a1b041f7a9c56eb5f4b1be7ec9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import cgi
from UserDict import UserDict

def parse_fields(environ):
    fs = cgi.FieldStorage(
        environ['wsgi.input'],
        environ=environ,
        keep_blank_values=True,
        strict_parsing=False)
    try:
        keys = fs.keys()
    except TypeError:
        # Maybe an XML-RPC request
        keys = []
    d = {}
    for key in keys:
        value = fs[key]
        if not isinstance(value, list):
            if not value.filename:
                # Turn the MiniFieldStorage into a string:
                value = value.value
        else:
            value = [v.value for v in value]
        d[key] = value
    if environ['REQUEST_METHOD'].upper() == 'POST':
        # Then we must also parse GET variables
        getfields = cgi.parse_qs(
            environ.get('QUERY_STRING', ''),
            keep_blank_values=True,
            strict_parsing=False)
        for name, value in getfields.items():
            if not d.has_key(name):
                if isinstance(value, list) and len(value) == 1:
                    # parse_qs always returns a list of lists,
                    # while FieldStorage only uses lists for
                    # keys that actually repeat; this fixes that.
                    value = value[0]
                d[name] = value
    return d

class Fields(UserDict):

    def __init__(self, field_dict):
        self.data = field_dict

    def __getattr__(self, attr):
        # @@: I don't like this.  Should it give a KeyError?
        # should it exist at all?
        if attr.startswith('_'):
            raise AttributeError
        return self.data.get(attr)

    def __contains__(self, key):
        return key in self.data
        
    def __iter__(self):
        return iter(self.data)

    def getlist(self, name):
        """
        Return the named item as a list ([] if name not found,
        [self[name]] if only one field passed in).
        """
        v = self.data.get(name, [])
        if isinstance(v, list):
            return v
        return [v]

    def itemlist(self):
        """
        Return a list of (name, [values...]).  Like .items(),
        except all values becomes a list (like .getlist()).
        """
        items = []
        for name, value in self.iteritems():
            if isinstance(value, list):
                items.append((name, value))
            else:
                items.append((name, [value]))
        return items
    
    __str__ = UserDict.__repr__