1 import simplejson, types
2 from osrf.net_obj import NetworkObject, parse_net_object
3 from osrf.const import OSRF_JSON_PAYLOAD_KEY, OSRF_JSON_CLASS_KEY
7 # if available, use the faster cjson module for encoding/decoding JSON
15 class NetworkEncoder(simplejson.JSONEncoder):
16 ''' Encoder used by simplejson '''
17 def default(self, obj):
19 if isinstance(obj, NetworkObject):
20 reg = obj.get_registry()
23 # re-encode the object as an array if necessary
24 if reg.protocol == 'array':
27 objarray.append(data.get(key))
31 OSRF_JSON_CLASS_KEY: reg.hint,
32 OSRF_JSON_PAYLOAD_KEY: self.default(data)
37 def encode_object(obj):
38 ''' Generic opensrf object encoder, used by cjson '''
40 if isinstance(obj, dict):
42 for k,v in obj.iteritems():
43 newobj[k] = encode_object(v)
46 elif isinstance(obj, list):
47 return [encode_object(v) for v in obj]
49 elif isinstance(obj, NetworkObject):
50 reg = obj.get_registry()
53 if reg.protocol == 'array':
56 objarray.append(data.get(key))
60 OSRF_JSON_CLASS_KEY: reg.hint,
61 OSRF_JSON_PAYLOAD_KEY: encode_object(data)
69 """Turns a python object into a wrapped JSON object"""
71 return cjson.encode(encode_object(obj))
72 return simplejson.dumps(obj, cls=NetworkEncoder)
76 """Turns a JSON string into python objects"""
78 return parse_net_object(cjson.decode(json))
79 return parse_net_object(simplejson.loads(json))
81 def parse_json_raw(json):
82 """Parses JSON the old fashioned way."""
84 return cjson.decode(json)
85 return simplejson.loads(json)
88 """Stringifies an object as JSON with no additional logic."""
90 return cjson.encode(json)
91 return simplejson.dumps(obj)
95 for i in range(depth):
99 def debug_net_object(obj, depth=1):
100 """Returns a debug string for a given object.
102 If it's an NetworkObject and has registered keys, key/value pairs
103 are returned. Otherwise formatted JSON is returned"""
106 if isinstance(obj, NetworkObject):
107 reg = obj.get_registry()
108 keys = list(reg.keys) # clone it, so sorting won't break the original
115 key += '.' # pad the names to make the values line up somewhat
116 val = getattr(obj, k)()
118 subobj = val and not (isinstance(val, unicode) or isinstance(val, str) or \
119 isinstance(val, int) or isinstance(val, float) or isinstance(val, long))
121 debug_str += __tabs(depth) + key + ' = '
125 val = debug_net_object(val, depth+1)
127 debug_str += str(val)
129 if not subobj: debug_str += '\n'
132 osrf.log.log_internal("Pretty-printing NetworkObject")
133 debug_str = pprint(to_json(obj))
137 """JSON pretty-printer"""
147 if eatws and not _use_cjson: # simpljson adds a pesky space after array and object items
153 if (c == '{' or c == '[') and not instring:
155 r += c + '\n' + __tabs(t)
158 if (c == '}' or c == ']') and not instring:
160 r += '\n' + __tabs(t) + c
163 if c == ',' and not instring:
164 r += c + '\n' + __tabs(t)
168 if c == ':' and not instring:
171 if c == '"' and not inescape:
172 instring = not instring