The Assimilation Project  based on Assimilation version 1.1.7.1474836767
assimjson.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # vim: smartindent tabstop=4 shiftwidth=4 expandtab number colorcolumn=100
3 #
4 # This file is part of the Assimilation Project.
5 #
6 # Author: Alan Robertson <alanr@unix.sh>
7 # Copyright (C) 2013 - Assimilation Systems Limited
8 #
9 # Free support is available from the Assimilation Project community - http://assimproj.org
10 # Paid support is available from Assimilation Systems Limited - http://assimilationsystems.com
11 #
12 # The Assimilation software is free software: you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation, either version 3 of the License, or
15 # (at your option) any later version.
16 #
17 # The Assimilation software is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with the Assimilation Project software. If not, see http://www.gnu.org/licenses/
24 #
25 #
26 '''
27 File containing the JSONtree class
28 '''
29 
30 import re
31 from AssimCclasses import pyConfigContext, pyNetAddr
32 from store import Store
33 
34 # R0903: Too few public methods
35 # pylint: disable=R0903
36 class JSONtree(object):
37  "Class to convert things to JSON strings - that's about all"
38  REESC = re.compile('\\\\')
39  REQUOTE = re.compile('"')
40  filterprefixes = ['_', 'JSON__hash__']
41 
42  def __init__(self, tree, expandJSON=False, maxJSON=0, filterprefixes=None):
43  self.filterprefixes = filterprefixes if filterprefixes is not None \
44  else JSONtree.filterprefixes
45  self.tree = tree
46  self.expandJSON = expandJSON
47  self.maxJSON = maxJSON
48 
49  def __str__(self):
50  'Convert our internal tree to JSON.'
51  return self._jsonstr(self.tree)
52 
53  @staticmethod
54  def _jsonesc(stringthing):
55  'Escape this string according to JSON string escaping rules'
56  stringthing = JSONtree.REESC.sub('\\\\\\\\', stringthing)
57  stringthing = JSONtree.REQUOTE.sub('\\\\"', stringthing)
58  return stringthing
59 
60  # R0911 is too many return statements
61  # pylint: disable=R0911
62  def _jsonstr(self, thing):
63  'Recursively convert ("pickle") this thing to JSON'
64 
65  if isinstance(thing, (list, tuple)):
66  ret = ''
67  comma = '['
68  if len(thing) == 0:
69  ret += '['
70  for item in thing:
71  ret += '%s%s' % (comma, self._jsonstr(item))
72  comma = ','
73  ret += ']'
74  return ret
75 
76  if isinstance(thing, dict):
77  ret = '{'
78  comma = ''
79  for key in thing.keys():
80  value = thing[key]
81  ret += '%s"%s":%s' % (comma, JSONtree._jsonesc(key), self._jsonstr(value))
82  comma = ','
83  ret += '}'
84  return ret
85 
86  if isinstance(thing, pyNetAddr):
87  return '"%s"' % (str(thing))
88 
89  if isinstance(thing, bool):
90  if thing:
91  return 'true'
92  return 'false'
93 
94  if isinstance(thing, (int, long, float, pyConfigContext)):
95  return str(thing)
96 
97  if isinstance(thing, unicode) or isinstance(thing, pyNetAddr):
98  return '"%s"' % (JSONtree._jsonesc(str(thing)))
99 
100  if isinstance(thing, str):
101  return '"%s"' % (JSONtree._jsonesc(thing))
102 
103  if thing is None:
104  return 'null'
105 
106  return self._jsonstr_other(thing)
107 
108  def _jsonstr_other(self, thing):
109  'Do our best to make JSON out of a "normal" python object - the final "other" case'
110  ret = '{'
111  comma = ''
112  attrs = thing.__dict__.keys()
113  attrs.sort()
114  if Store.has_node(thing) and Store.id(thing) is not None:
115  ret += '"_id": %s' % str(Store.id(thing))
116  comma = ','
117  for attr in attrs:
118  skip = False
119  for prefix in self.filterprefixes:
120  if attr.startswith(prefix):
121  skip = True
122  continue
123  if skip:
124  continue
125  value = getattr(thing, attr)
126  if self.maxJSON > 0 and attr.startswith('JSON_') and len(value) > self.maxJSON:
127  continue
128  if self.expandJSON and attr.startswith('JSON_') and value.startswith('{'):
129  js = pyConfigContext(value)
130  if js is not None:
131  value = js
132  ret += '%s"%s":%s' % (comma, attr, self._jsonstr(value))
133  comma = ','
134  ret += '}'
135  return ret
def __init__(self, tree, expandJSON=False, maxJSON=0, filterprefixes=None)
Definition: assimjson.py:42
def _jsonstr(self, thing)
Definition: assimjson.py:62
def _jsonstr_other(self, thing)
Definition: assimjson.py:108