Statistics
| Branch: | Tag: | Revision:

root / api / emitter.py @ ed66d976

History | View | Annotate | Download (1.8 kB)

1 00b4f1be Faidon Liambotis
# vim: ts=4 sts=4 et ai sw=4 fileencoding=utf-8
2 00b4f1be Faidon Liambotis
#
3 00b4f1be Faidon Liambotis
# Copyright © 2010 Greek Research and Technology Network
4 00b4f1be Faidon Liambotis
#
5 00b4f1be Faidon Liambotis
6 00b4f1be Faidon Liambotis
from piston.resource import Resource as BaseResource
7 00b4f1be Faidon Liambotis
import re
8 00b4f1be Faidon Liambotis
9 00b4f1be Faidon Liambotis
_accept_re = re.compile(r'([^\s;,]+)(?:[^,]*?;\s*q=(\d*(?:\.\d+)?))?')
10 00b4f1be Faidon Liambotis
11 00b4f1be Faidon Liambotis
def parse_accept_header(value):
12 00b4f1be Faidon Liambotis
    """Parse an HTTP Accept header
13 00b4f1be Faidon Liambotis

14 00b4f1be Faidon Liambotis
    Returns an ordered by quality list of tuples (value, quality)
15 00b4f1be Faidon Liambotis
    """
16 00b4f1be Faidon Liambotis
    if not value:
17 00b4f1be Faidon Liambotis
        return []
18 00b4f1be Faidon Liambotis
19 00b4f1be Faidon Liambotis
    result = []
20 00b4f1be Faidon Liambotis
    for match in _accept_re.finditer(value):
21 00b4f1be Faidon Liambotis
        quality = match.group(2)
22 00b4f1be Faidon Liambotis
        if not quality:
23 00b4f1be Faidon Liambotis
            quality = 1
24 00b4f1be Faidon Liambotis
        else:
25 00b4f1be Faidon Liambotis
            quality = max(min(float(quality), 1), 0)
26 00b4f1be Faidon Liambotis
        result.append((match.group(1), quality))
27 00b4f1be Faidon Liambotis
28 00b4f1be Faidon Liambotis
    # sort by quality
29 00b4f1be Faidon Liambotis
    result.sort(key=lambda x: x[1])
30 00b4f1be Faidon Liambotis
31 00b4f1be Faidon Liambotis
    return result
32 00b4f1be Faidon Liambotis
33 00b4f1be Faidon Liambotis
# XXX: works as intended but not used since piston's XMLEmitter doesn't output
34 00b4f1be Faidon Liambotis
# XML according to our spec :(
35 00b4f1be Faidon Liambotis
class Resource(BaseResource):
36 00b4f1be Faidon Liambotis
    def determine_emitter(self, request, *args, **kwargs):
37 00b4f1be Faidon Liambotis
        """
38 00b4f1be Faidon Liambotis
        Override default emitter policy to account for Accept header
39 00b4f1be Faidon Liambotis

40 00b4f1be Faidon Liambotis
        emitter_format (.json or .xml suffix in URL) always takes precedence.
41 00b4f1be Faidon Liambotis

42 00b4f1be Faidon Liambotis
        After that, the Accept header is checked; if both JSON and XML are
43 00b4f1be Faidon Liambotis
        equally preferred, use JSON.
44 00b4f1be Faidon Liambotis

45 00b4f1be Faidon Liambotis
        If none of the two were provided, then use JSON as per the
46 00b4f1be Faidon Liambotis
        specification.
47 00b4f1be Faidon Liambotis
        """
48 00b4f1be Faidon Liambotis
49 00b4f1be Faidon Liambotis
        em = request.GET.get('format', 'xml')
50 00b4f1be Faidon Liambotis
        if 'emitter_format' in kwargs:
51 00b4f1be Faidon Liambotis
            em = kwargs.pop('emitter_format')
52 00b4f1be Faidon Liambotis
        elif 'HTTP_ACCEPT' in request.META:
53 00b4f1be Faidon Liambotis
            accepts = parse_accept_header(request.META['HTTP_ACCEPT'])
54 00b4f1be Faidon Liambotis
            for content_type, quality in accepts:
55 00b4f1be Faidon Liambotis
                if content_type == 'application/json':
56 00b4f1be Faidon Liambotis
                    break
57 00b4f1be Faidon Liambotis
                elif content_type == 'application/xml':
58 00b4f1be Faidon Liambotis
                    em = request.GET.get('format', 'xml')
59 00b4f1be Faidon Liambotis
                    break
60 00b4f1be Faidon Liambotis
61 00b4f1be Faidon Liambotis
        return em