include dateutil and some cleaning

This commit is contained in:
Juan Riaza 2013-01-05 23:28:15 +01:00
parent c360433de7
commit 0234b6161b
5 changed files with 30 additions and 38 deletions

View File

@ -1,4 +1,5 @@
markdown>=2.1.0 markdown>=2.1.0
PyYAML>=3.10 PyYAML>=3.10
django-filter>=0.5.4 django-filter>=0.5.4
msgpack-python==0.3.0dev1 msgpack-python>=0.2.4
python-dateutil==2.1

View File

@ -397,6 +397,12 @@ try:
except ImportError: except ImportError:
msgpack = None msgpack = None
# dateutil is optional
try:
from dateutil import parser as dateutil_parser
except ImportError:
dateutil_parser = None
# xml.etree.parse only throws ParseError for python >= 2.7 # xml.etree.parse only throws ParseError for python >= 2.7
try: try:

View File

@ -8,7 +8,7 @@ on the request, such as form content or json encoded data.
from django.http import QueryDict from django.http import QueryDict
from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser
from django.http.multipartparser import MultiPartParserError from django.http.multipartparser import MultiPartParserError
from rest_framework.compat import yaml, msgpack, ETParseError from rest_framework.compat import yaml, msgpack, dateutil_parser, ETParseError
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
from xml.parsers.expat import ExpatError from xml.parsers.expat import ExpatError
@ -101,18 +101,17 @@ class MessagePackParser(BaseParser):
except Exception, exc: except Exception, exc:
raise ParseError('MessagePack parse error - %s' % unicode(exc)) raise ParseError('MessagePack parse error - %s' % unicode(exc))
def _decode_object(self, o): def _decode_object(self, obj):
# TODO(juanriaza): decode objects if '__datetime__' in obj:
if b'__datetime__' in o: return dateutil_parser.parse(obj['as_str'])
return o['as_str'] elif b'__date__' in obj:
elif b'__date__' in o: return dateutil_parser.parse(obj['as_str']).date()
return o['as_str'] elif b'__time__' in obj:
elif b'__time__' in o: return dateutil_parser.parse(obj['as_str']).time()
return o['as_str'] elif b'__decimal__' in obj:
elif b'__decimal__' in o: return decimal.Decimal(obj['as_str'])
return o['as_str']
else: else:
return o return obj
class FormParser(BaseParser): class FormParser(BaseParser):

View File

@ -146,7 +146,6 @@ class MessagePackRenderer(BaseRenderer):
media_type = 'application/msgpack' media_type = 'application/msgpack'
format = 'msgpack' format = 'msgpack'
encoder = encoders.msgpack_encoder
def render(self, data, accepted_media_type=None, renderer_context=None): def render(self, data, accepted_media_type=None, renderer_context=None):
""" """
@ -154,7 +153,7 @@ class MessagePackRenderer(BaseRenderer):
""" """
if data is None: if data is None:
return '' return ''
return msgpack.packb(data, default=self.encoder) return msgpack.packb(data, default=encoders.msgpack_encoder)
class TemplateHTMLRenderer(BaseRenderer): class TemplateHTMLRenderer(BaseRenderer):

View File

@ -92,29 +92,16 @@ else:
if msgpack: if msgpack:
def msgpack_encoder(o): def msgpack_encoder(obj):
# For Date Time string spec, see ECMA 262 if isinstance(obj, datetime.datetime):
# http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 return {'__datetime__': True, 'as_str': obj.isoformat()}
if isinstance(o, datetime.datetime): elif isinstance(obj, datetime.date):
r = o.isoformat() return {'__date__': True, 'as_str': obj.isoformat()}
if o.microsecond: elif isinstance(obj, datetime.time):
r = r[:23] + r[26:] return {'__time__': True, 'as_str': obj.isoformat()}
if r.endswith('+00:00'): elif isinstance(obj, decimal.Decimal):
r = r[:-6] + 'Z' return {'__decimal__': True, 'as_str': str(obj)}
return {'__datetime__': True, 'as_str': r}
elif isinstance(o, datetime.date):
r = o.isoformat()
return {'__date__': True, 'as_str': r}
elif isinstance(o, datetime.time):
if timezone and timezone.is_aware(o):
raise ValueError("MessagePack can't represent timezone-aware times.")
r = o.isoformat()
if o.microsecond:
r = r[:12]
return {'__time__': True, 'as_str': r}
elif isinstance(o, decimal.Decimal):
return {'__decimal__': True, 'as_str': str(o)}
else: else:
return o return obj
else: else:
msgpack_encoder = None msgpack_encoder = None