diff options
Diffstat (limited to 'pecan/jsonify.py')
-rw-r--r-- | pecan/jsonify.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/pecan/jsonify.py b/pecan/jsonify.py new file mode 100644 index 0000000..128e3bb --- /dev/null +++ b/pecan/jsonify.py @@ -0,0 +1,65 @@ +from simplejson import JSONEncoder, dumps +from datetime import datetime, date +from decimal import Decimal +from webob.multidict import MultiDict +from simplegeneric import generic + + +# +# exceptions +# + +class JsonEncodeError(Exception): + pass + + +# +# encoders +# + +class BaseEncoder(JSONEncoder): + def is_saobject(self, obj): + return hasattr(obj, '_sa_class_manager') + + def jsonify(self, obj): + return dumps(self.encode(obj)) + + def encode(self, obj): + if hasattr(obj, '__json__') and callable(obj.__json__): + return obj.__json__() + elif isinstance(obj, (date, datetime)): + return str(obj) + elif isinstance(obj, Decimal): + return float(obj) + elif self.is_saobject(obj): + props = {} + for key in obj.__dict__: + if not key.startswith('_sa_'): + props[key] = getattr(obj, key) + return props + elif isinstance(obj, MultiDict): + return obj.mixed() + else: + try: + from sqlalchemy.engine.base import ResultProxy, RowProxy + if isinstance(obj, ResultProxy): + return dict(rows=list(obj), count=obj.rowcount) + elif isinstance(obj, RowProxy): + return dict(rows=dict(obj), count=1) + except: + pass + return obj + + +# +# generic function support +# + +encoder = BaseEncoder() + +@generic +def jsonify(obj): + return encoder.encode(obj) + +def encode(obj): + return dumps(jsonify(obj))
\ No newline at end of file |