Commits

Jesper Nøhr  committed 2ac6494

using proper http status codes for most common operations now, detecting encoding via content-type header, all unittests pass, HttpResponse objects are not serialized, allows for cool stuff

  • Participants
  • Parent commits ac2ebcf

Comments (0)

Files changed (3)

File piston/emitters.py

 from django.utils.xmlutils import SimplerXMLGenerator
 from django.utils.encoding import smart_unicode
 from django.core.serializers.json import DateTimeAwareJSONEncoder
+from django.http import HttpResponse
+from utils import HttpStatusCode
 
 try:
     import cStringIO as StringIO
                 ret = str(thing)
             elif isinstance(thing, Model):
                 ret = _model(thing, fields=fields)
+            elif isinstance(thing, HttpResponse):
+                raise HttpStatusCode(thing.content, code=thing.status_code)
             elif isinstance(thing, types.FunctionType):
                 pass
             else:
         Gets an emitter, returns the class and a content-type.
         """
         if format == 'xml':
-            return XMLEmitter, 'text/plain; charset=utf-8'
+            return XMLEmitter, 'text/xml; charset=utf-8'
         elif format == 'json':
-            return JSONEmitter, 'text/plain; charset=utf-8'
+            return JSONEmitter, 'application/json; charset=utf-8'
         elif format == 'yaml':
-            return YAMLEmitter, 'text/plain; charset=utf-8'
+            return YAMLEmitter, 'application/x-yaml; charset=utf-8'
     
 class XMLEmitter(Emitter):
     def _to_xml(self, xml, data):
         elif data:
             xml.characters(smart_unicode(data))
 
-    def render(self):
+    def render(self, request):
         stream = StringIO.StringIO()
         
         xml = SimplerXMLGenerator(stream, "utf-8")
     """
     JSON emitter, understands timestamps.
     """
-    # TODO: callback functions
-    def render(self):
-        return simplejson.dumps(self.construct(), cls=DateTimeAwareJSONEncoder)
+    def render(self, request):
+        cb = request.GET.get('callback')
+        seria = simplejson.dumps(self.construct(), cls=DateTimeAwareJSONEncoder)
+
+        # Callback
+        if cb:
+            return '%s(%s)' % (cb, seria)
+
+        return seria
     
 class YAMLEmitter(Emitter):
     """
     YAML emitter, uses `safe_dump` to omit the
     specific types when outputting to non-Python.
     """
-    def render(self):
+    def render(self, request):
         return yaml.safe_dump(self.construct())

File piston/resource.py

 from django.views.decorators.vary import vary_on_headers
 from emitters import Emitter
 from handler import typemapper
-from utils import coerce_put_post, FormValidationError
+from utils import coerce_put_post, FormValidationError, HttpStatusCode
 
 class NoAuthentication(object):
     """
         
         emitter, ct = Emitter.get(request.GET.get('format', 'json'))
         srl = emitter(result, typemapper, handler.fields)
-        
-        return HttpResponse(srl.render(), mimetype=ct)
+
+        try:
+            return HttpResponse(srl.render(request), mimetype=ct)
+        except HttpStatusCode, e:
+            return HttpResponse(e.message, status=e.code)
 
     @staticmethod
     def cleanup_request(request):

File piston/utils.py

-from django.http import HttpResponseNotAllowed, HttpResponseForbidden
+from django.http import HttpResponseNotAllowed, HttpResponseForbidden, HttpResponse
 from django.core.urlresolvers import reverse
 
+def create_reply(message, status=200):
+    return HttpResponse(message, status=status)
+
 class rc(object):
     """
     Status codes.
     """
-    ALL_OK = 'ok.'
-    DUPLICATE_ENTRY = 'already exists.'
-
-class HttpForbidden(HttpResponseForbidden):
+    ALL_OK = create_reply('OK', status=200)
+    CREATED = create_reply('Created', status=201)
+    DELETED = create_reply('No Content', status=204)
+    FORBIDDEN = create_reply('Forbidden', status=401)
+    DUPLICATE_ENTRY = create_reply('Conflict', status=409)
+    NOT_HERE = create_reply('Gone', status=410)
+    NOT_IMPLEMENTED = create_reply('Not Implemented', status=501)
+    
+class FormValidationError(Exception):
     pass
 
-class FormValidationError(Exception):
-    pass
+class HttpStatusCode(Exception):
+    def __init__(self, message, code=200):
+        self.message = message
+        self.code = code
 
 def validate(form, operation='POST'):
     def dec(func):