Source

pythonhk / src / pythonhk / utils.py

try:
    import simplejson as json
except ImportError:
    import json

from datetime import date, time, datetime

import dateutil

from cherrypy import HTTPError

def to_json(instance, includes=None, excludes=None, serialize=False):

    includes = set([includes] if isinstance(includes, basestring) else includes and list(includes) or [])
    excludes = set([excludes] if isinstance(excludes, basestring) else excludes and list(excludes) or [])
    attrs = set(instance.__table__.c.keys())
    attrs = includes | attrs - excludes

    doc = {}
    for k in attrs:
        v = getattr(instance, k)
        if not k.startswith("_") and not isinstance(v, (tuple, list, set, frozenset, dict)):
            if isinstance(v, datetime):
                v = {"datetime": v.isoformat()}
            elif isinstance(v, time):
                v = {"time": v.isoformat()}
            elif isinstance(v, date):
                v = {"date": v.isoformat()}
            doc[k] = v

    if serialize:
        return json.dumps(doc)
    return doc

def from_json(doc, instance, includes=None, excludes=None):

    if isinstance(doc, basestring):
        doc = json.loads(doc)

    if not isinstance(doc, dict):
        raise TypeError(doc, "doc must be a dict")

    includes = set([includes] if isinstance(includes, basestring) else includes and list(includes) or [])
    excludes = set([excludes] if isinstance(excludes, basestring) else excludes and list(excludes) or [])
    attrs = set(instance.__table__.c.keys())
    attrs = includes | attrs - excludes

    for k, v in doc.iteritems():

        if k in attrs:
            if isinstance(v, dict):
                if "date" in v:
                    v = dateutil.parser.parse(v["date"])
                elif "time" in v:
                    v = dateutil.parser.parse(v["time"])
                elif "datetime" in v:
                    v = dateutil.parser.parse(v["datetime"])

            setattr(instance, k, v)
        else:
            raise HTTPError(400)

    return instance