django-piston / piston / resource.py

Diff from to

piston/resource.py

 from django.db.models.query import QuerySet
 from django.http import Http404
 
+try:
+    import mimeparse
+except ImportError:
+    mimeparse = None
+
 from emitters import Emitter
 from handler import typemapper
 from doc import HandlerMethod
         self.email_errors = getattr(settings, 'PISTON_EMAIL_ERRORS', True)
         self.display_errors = getattr(settings, 'PISTON_DISPLAY_ERRORS', True)
         self.stream = getattr(settings, 'PISTON_STREAM_OUTPUT', False)
+        # Emitter selection
+        self.strict_accept = getattr(settings, 'PISTON_STRICT_ACCEPT_HANDLING',
+                                     False)
+        self.default_emitter = getattr(settings, 'PISTON_DEFAULT_EMITTER',
+                                       'json')
 
     def determine_emitter(self, request, *args, **kwargs):
         """
         Function for determening which emitter to use
         for output. It lives here so you can easily subclass
         `Resource` in order to change how emission is detected.
-
-        You could also check for the `Accept` HTTP header here,
-        since that pretty much makes sense. Refer to `Mimer` for
-        that as well.
         """
-        em = kwargs.pop('emitter_format', None)
-
-        if not em:
-            em = request.GET.get('format', 'json')
-
-        return em
+        try:
+            return kwargs['emitter_format']
+        except KeyError:
+            pass
+        if 'format' in request.GET:
+            return request.GET.get('format')
+        if mimeparse and 'HTTP_ACCEPT' in request.META:
+            supported_mime_types = set()
+            emitter_map = {}
+            for name, (klass, content_type) in Emitter.EMITTERS.items():
+                content_type_without_encoding = content_type.split(';')[0]
+                supported_mime_types.add(content_type_without_encoding)
+                emitter_map[content_type_without_encoding] = name
+            preferred_content_type = mimeparse.best_match(
+                list(supported_mime_types),
+                request.META['HTTP_ACCEPT'])
+            return emitter_map.get(preferred_content_type, None)
 
     def form_validation_response(self, e):
         """
         if not meth:
             raise Http404
 
-        # Support emitter both through (?P<emitter_format>) and ?format=emitter.
+        # Support emitter through (?P<emitter_format>) and ?format=emitter
+        # and lastly Accept: header processing
         em_format = self.determine_emitter(request, *args, **kwargs)
+        if not em_format:
+            request_has_accept = 'HTTP_ACCEPT' in request.META
+            if request_has_accept and self.strict_accept:
+                return rc.NOT_ACCEPTABLE
+            em_format = self.default_emitter
 
         kwargs.pop('emitter_format', None)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.