~robru/gwibber/foursquare-fixup

« back to all changes in this revision

Viewing changes to gwibber/gwibber/utils/download.py

  • Committer: Barry Warsaw
  • Date: 2012-09-14 20:29:11 UTC
  • Revision ID: barry@python.org-20120914202911-pyvq07821iqua9k8
Full support for RFC 4627 application/json implicit charset encodings.  See $3
of the RFC for details.

Show diffs side-by-side

added added

removed removed

Lines of Context:
85
85
 
86
86
    def get_json(self):
87
87
        """Interpret and return the results as JSON data."""
88
 
        return json.loads(self.get_string())
 
88
        request = self._download()
 
89
        with urlopen(request) as result:
 
90
            payload = result.read()
 
91
            info = result.info()
 
92
        # RFC 4627 $3.  JSON text SHALL be encoded in Unicode.  The default
 
93
        # encoding is UTF-8.  Since the first two characters of a JSON text
 
94
        # will always be ASCII characters [RFC0020], it is possible to
 
95
        # determine whether an octet stream is UTF-8, UTF-16 (BE or LE), or
 
96
        # UTF-32 (BE or LE) by looking at the pattern of nulls in the first
 
97
        # four octets.
 
98
        charset = info.get_content_charset()
 
99
        if charset is None:
 
100
            octet_0, octet_1, octet_2, octet_3 = payload[:4]
 
101
            if 0 not in (octet_0, octet_1, octet_2, octet_3):
 
102
                charset = 'utf-8'
 
103
            elif (octet_1 == octet_3 == 0) and octet_2 != 0:
 
104
                charset = 'utf-16le'
 
105
            elif (octet_0 == octet_2 == 0) and octet_1 != 0:
 
106
                charset = 'utf-16be'
 
107
            elif (octet_1 == octet_2 == octet_3 == 0):
 
108
                charset = 'utf-32le'
 
109
            elif (octet_0 == octet_1 == octet_2 == 0):
 
110
                charset = 'utf-32be'
 
111
        return json.loads(payload.decode(charset))
89
112
 
90
113
 
91
114
def get_json(*args, **kws):