-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathqjsonnode.py
173 lines (144 loc) · 4.33 KB
/
qjsonnode.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
"""
The node module is for creating node data structure/class that supports
hierarchical model. Each node object reflects to an abstract node which
has child and parent relationships
"""
class QJsonNode(object):
def __init__(self, parent=None):
"""
Initialization
:param parent: QJsonNode. parent of the current node
"""
self._key = ""
self._value = ""
self._dtype = None
self._parent = parent
self._children = list()
@classmethod
def load(cls, value, parent=None):
"""
Generate the hierarchical node tree using dictionary
:param value: dict. input dictionary
:param parent: QJsonNode. for recursive use only
:return: QJsonNode. the top node
"""
rootNode = cls(parent)
rootNode.key = "root"
rootNode.dtype = type(value)
if isinstance(value, dict):
# TODO: not sort will break things, but why?
nodes = sorted(value.items())
for key, value in nodes:
child = cls.load(value, rootNode)
child.key = key
child.dtype = type(value)
rootNode.addChild(child)
elif isinstance(value, list):
for index, value in enumerate(value):
child = cls.load(value, rootNode)
child.key = 'list[{}]'.format(index)
child.dtype = type(value)
rootNode.addChild(child)
else:
rootNode.value = value
return rootNode
@property
def key(self):
"""
Get key of the current node
"""
return self._key
@key.setter
def key(self, key):
self._key = key
@property
def value(self):
"""
Get value of the current node
"""
return self._value
@value.setter
def value(self, value):
self._value = value
@property
def dtype(self):
"""
Get value data type of the current node
"""
return self._dtype
@dtype.setter
def dtype(self, dtype):
self._dtype = dtype
@property
def parent(self):
"""
Get parent node of the current node
"""
return self._parent
@property
def children(self):
"""
Get the children of the current node
:return: list.
"""
return self._children
@property
def childCount(self):
"""
Get the number of children of the current node
:return: int.
"""
return len(self._children)
def addChild(self, node):
"""
Add a new child to the current node
:param node: QJsonNode. child node
"""
self._children.append(node)
node._parent = self
def removeChild(self, position):
"""
Remove child on row/position of the current node
:param position: int. index of the children
"""
node = self._children.pop(position)
node._parent = None
def child(self, row):
"""
Get the child on row/position of the current node
:param row: int. index of the children
:return: QJsonNode. child node
"""
return self._children[row]
def row(self):
"""
Get the current node's row/position in regards to its parent
:return: int. index of the current node
"""
if self._parent:
return self.parent.children.index(self)
return 0
def asDict(self):
"""
Serialize the hierarchical structure of current node to a dictionary
:return: dict. serialization of the hierarchy
"""
return {self.key: self.getChildrenValue(self)}
def getChildrenValue(self, node):
"""
Query the nested children value (instead of a single value)
:param node: QJsonNode. root node
:return: mixed. value
"""
if node.dtype is dict:
output = dict()
for child in node.children:
output[child.key] = self.getChildrenValue(child)
return output
elif node.dtype == list:
output = list()
for child in node.children:
output.append(self.getChildrenValue(child))
return output
else:
return node.value