"""FieldStorage.py

This module defines a subclass of the standard Python cgi.FieldStorage class
with an extra method that will allow a FieldStorage to parse a query string
even in a POST request.

"""


import cgi, os, urllib


class FieldStorage(cgi.FieldStorage):

    def __init__(self, fp=None, headers=None, outerboundary="",
            environ=os.environ, keep_blank_values=0, strict_parsing=0):
        self._environ = environ
        self._strict_parsing = strict_parsing
        self._keep_blank_values = keep_blank_values
        cgi.FieldStorage.__init__(self, fp, headers, outerboundary,
            environ, keep_blank_values, strict_parsing)

    def parse_qs(self):
        """Explicitly parse the query string, even if it's a POST request."""
        self._method = self._environ.get('REQUEST_METHOD', '').upper()
        if self._method == "GET" or self._method == "HEAD":
            # print __file__, "bailing on GET or HEAD request"
            return # bail because cgi.FieldStorage already did this
        self._qs = self._environ.get('QUERY_STRING', None)
        if not self._qs:
            # print __file__, "bailing on no query_string"
            return # bail if no query string

        r = {}
        for name_value in self._qs.split('&'):
            nv = name_value.split('=', 2)
            if len(nv) != 2:
                if self._strict_parsing:
                    raise ValueError, "bad query field: %r" % (name_value,)
                continue
            name = urllib.unquote(nv[0].replace('+', ' '))
            value = urllib.unquote(nv[1].replace('+', ' '))
            if len(value) or self._keep_blank_values:
                if r.has_key(name):
                    r[name].append(value)
                else:
                    r[name] = [value]

        # Only append values that aren't already in the FieldStorage's keys;
        # This makes POSTed vars override vars on the query string
        if not self.list:
            # This makes sure self.keys() are available, even
            # when valid POST data wasn't encountered.
            self.list = []
        for key, values in r.items():
            if not self.has_key(key):
                for value in values:
                    self.list.append(cgi.MiniFieldStorage(key, value))