Brad Bishop | 732c6db | 2015-10-19 14:49:21 -0400 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | # Contributors Listed Below - COPYRIGHT 2015 |
| 4 | # [+] International Business Machines Corp. |
| 5 | # |
| 6 | # |
| 7 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | # you may not use this file except in compliance with the License. |
| 9 | # You may obtain a copy of the License at |
| 10 | # |
| 11 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | # |
| 13 | # Unless required by applicable law or agreed to in writing, software |
| 14 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| 16 | # implied. See the License for the specific language governing |
| 17 | # permissions and limitations under the License. |
| 18 | |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 19 | from xml.etree import ElementTree |
| 20 | import dbus |
| 21 | |
Brad Bishop | 732c6db | 2015-10-19 14:49:21 -0400 | [diff] [blame] | 22 | MAPPER_NAME = 'org.openbmc.objectmapper' |
| 23 | MAPPER_IFACE = MAPPER_NAME + '.ObjectMapper' |
| 24 | MAPPER_PATH = '/org/openbmc/objectmapper/objectmapper' |
Brad Bishop | d4a1b93 | 2015-11-03 14:43:35 -0500 | [diff] [blame] | 25 | ENUMERATE_IFACE = 'org.openbmc.Object.Enumerate' |
Brad Bishop | ae0c0af | 2015-11-09 18:41:28 -0500 | [diff] [blame] | 26 | MAPPER_NOT_FOUND = 'org.openbmc.objectmapper.Error.NotFound' |
Brad Bishop | 3640ecd | 2015-11-03 14:46:10 -0500 | [diff] [blame] | 27 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 28 | |
Brad Bishop | 732c6db | 2015-10-19 14:49:21 -0400 | [diff] [blame] | 29 | class Path: |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 30 | def __init__(self, path): |
| 31 | self.parts = filter(bool, path.split('/')) |
Brad Bishop | 732c6db | 2015-10-19 14:49:21 -0400 | [diff] [blame] | 32 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 33 | def rel(self, first=None, last=None): |
| 34 | # relative |
| 35 | return self.get('', first, last) |
Brad Bishop | 732c6db | 2015-10-19 14:49:21 -0400 | [diff] [blame] | 36 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 37 | def fq(self, first=None, last=None): |
| 38 | # fully qualified |
| 39 | return self.get('/', first, last) |
Brad Bishop | 732c6db | 2015-10-19 14:49:21 -0400 | [diff] [blame] | 40 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 41 | def depth(self): |
| 42 | return len(self.parts) |
Brad Bishop | 732c6db | 2015-10-19 14:49:21 -0400 | [diff] [blame] | 43 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 44 | def get(self, prefix='/', first=None, last=None): |
| 45 | if not first: |
| 46 | first = 0 |
| 47 | if not last: |
| 48 | last = self.depth() |
| 49 | return prefix + '/'.join(self.parts[first:last]) |
| 50 | |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 51 | |
Brad Bishop | 6fb8461 | 2015-11-01 00:06:24 -0400 | [diff] [blame] | 52 | def org_dot_openbmc_match(name): |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 53 | return 'org.openbmc' in name |
| 54 | |
Brad Bishop | 6fb8461 | 2015-11-01 00:06:24 -0400 | [diff] [blame] | 55 | |
Brad Bishop | a8e752f | 2015-11-03 09:24:48 -0500 | [diff] [blame] | 56 | class ListMatch(object): |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 57 | def __init__(self, l): |
| 58 | self.l = l |
Brad Bishop | 6fb8461 | 2015-11-01 00:06:24 -0400 | [diff] [blame] | 59 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 60 | def __call__(self, match): |
| 61 | return match in self.l |
| 62 | |
Brad Bishop | 6fb8461 | 2015-11-01 00:06:24 -0400 | [diff] [blame] | 63 | |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 64 | class IntrospectionNodeParser: |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 65 | def __init__(self, data, tag_match=bool, intf_match=bool): |
| 66 | self.data = data |
| 67 | self.cache = {} |
| 68 | self.tag_match = tag_match |
| 69 | self.intf_match = intf_match |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 70 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 71 | def parse_args(self): |
| 72 | return [x.attrib for x in self.data.findall('arg')] |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 73 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 74 | def parse_children(self): |
| 75 | return [x.attrib['name'] for x in self.data.findall('node')] |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 76 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 77 | def parse_method_or_signal(self): |
| 78 | name = self.data.attrib['name'] |
| 79 | return name, self.parse_args() |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 80 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 81 | def parse_interface(self): |
| 82 | iface = {} |
| 83 | iface['method'] = {} |
| 84 | iface['signal'] = {} |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 85 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 86 | for node in self.data: |
| 87 | if node.tag not in ['method', 'signal']: |
| 88 | continue |
| 89 | if not self.tag_match(node.tag): |
| 90 | continue |
| 91 | p = IntrospectionNodeParser( |
| 92 | node, self.tag_match, self.intf_match) |
| 93 | n, element = p.parse_method_or_signal() |
| 94 | iface[node.tag][n] = element |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 95 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 96 | return iface |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 97 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 98 | def parse_node(self): |
| 99 | if self.cache: |
| 100 | return self.cache |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 101 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 102 | self.cache['interfaces'] = {} |
| 103 | self.cache['children'] = [] |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 104 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 105 | for node in self.data: |
| 106 | if node.tag == 'interface': |
| 107 | p = IntrospectionNodeParser( |
| 108 | node, self.tag_match, self.intf_match) |
| 109 | name = p.data.attrib['name'] |
| 110 | if not self.intf_match(name): |
| 111 | continue |
| 112 | self.cache['interfaces'][name] = p.parse_interface() |
| 113 | elif node.tag == 'node': |
| 114 | self.cache['children'] = self.parse_children() |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 115 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 116 | return self.cache |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 117 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 118 | def get_interfaces(self): |
| 119 | return self.parse_node()['interfaces'] |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 120 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 121 | def get_children(self): |
| 122 | return self.parse_node()['children'] |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 123 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 124 | def recursive_binding(self): |
| 125 | return any('/' in s for s in self.get_children()) |
| 126 | |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 127 | |
| 128 | class IntrospectionParser: |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 129 | def __init__(self, name, bus, tag_match=bool, intf_match=bool): |
| 130 | self.name = name |
| 131 | self.bus = bus |
| 132 | self.tag_match = tag_match |
| 133 | self.intf_match = intf_match |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 134 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 135 | def _introspect(self, path): |
| 136 | try: |
| 137 | obj = self.bus.get_object(self.name, path, introspect=False) |
| 138 | iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE) |
| 139 | data = iface.Introspect() |
| 140 | except dbus.DBusException: |
| 141 | return None |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 142 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 143 | return IntrospectionNodeParser( |
| 144 | ElementTree.fromstring(data), |
| 145 | self.tag_match, |
| 146 | self.intf_match) |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 147 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 148 | def _discover_flat(self, path, parser): |
| 149 | items = {} |
| 150 | interfaces = parser.get_interfaces().keys() |
| 151 | if interfaces: |
| 152 | items[path] = {} |
| 153 | items[path]['interfaces'] = interfaces |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 154 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 155 | return items |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 156 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 157 | def introspect(self, path='/', parser=None): |
| 158 | items = {} |
| 159 | if not parser: |
| 160 | parser = self._introspect(path) |
| 161 | if not parser: |
| 162 | return {} |
| 163 | items.update(self._discover_flat(path, parser)) |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 164 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 165 | if path != '/': |
| 166 | path += '/' |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 167 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 168 | if parser.recursive_binding(): |
| 169 | callback = self._discover_flat |
| 170 | else: |
| 171 | callback = self.introspect |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 172 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 173 | for k in parser.get_children(): |
| 174 | parser = self._introspect(path + k) |
| 175 | if not parser: |
| 176 | continue |
| 177 | items.update(callback(path + k, parser)) |
Brad Bishop | 3f43cdb | 2015-10-28 22:02:09 -0400 | [diff] [blame] | 178 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 179 | return items |
| 180 | |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 181 | |
| 182 | class PathTreeItemIterator(object): |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 183 | def __init__(self, path_tree, subtree, depth): |
| 184 | self.path_tree = path_tree |
| 185 | self.path = [] |
| 186 | self.itlist = [] |
| 187 | self.subtree = ['/'] + filter(bool, subtree.split('/')) |
| 188 | self.depth = depth |
| 189 | d = path_tree.root |
| 190 | for k in self.subtree: |
| 191 | try: |
| 192 | d = d[k]['children'] |
| 193 | except KeyError: |
| 194 | raise KeyError(subtree) |
| 195 | self.it = d.iteritems() |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 196 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 197 | def __iter__(self): |
| 198 | return self |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 199 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 200 | def __next__(self): |
| 201 | return super(PathTreeItemIterator, self).next() |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 202 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 203 | def next(self): |
| 204 | key, value = self._next() |
| 205 | path = self.subtree[0] + '/'.join(self.subtree[1:] + self.path) |
| 206 | return path, value.get('data') |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 207 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 208 | def _next(self): |
| 209 | try: |
| 210 | while True: |
| 211 | x = self.it.next() |
| 212 | depth_exceeded = len(self.path) + 1 > self.depth |
| 213 | if self.depth and depth_exceeded: |
| 214 | continue |
| 215 | self.itlist.append(self.it) |
| 216 | self.path.append(x[0]) |
| 217 | self.it = x[1]['children'].iteritems() |
| 218 | break |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 219 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 220 | except StopIteration: |
| 221 | if not self.itlist: |
| 222 | raise StopIteration |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 223 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 224 | self.it = self.itlist.pop() |
| 225 | self.path.pop() |
| 226 | x = self._next() |
| 227 | |
| 228 | return x |
| 229 | |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 230 | |
| 231 | class PathTreeKeyIterator(PathTreeItemIterator): |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 232 | def __init__(self, path_tree, subtree, depth): |
| 233 | super(PathTreeKeyIterator, self).__init__(path_tree, subtree, depth) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 234 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 235 | def next(self): |
| 236 | return super(PathTreeKeyIterator, self).next()[0] |
| 237 | |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 238 | |
| 239 | class PathTree: |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 240 | def __init__(self): |
| 241 | self.root = {} |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 242 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 243 | def _try_delete_parent(self, elements): |
| 244 | if len(elements) == 1: |
| 245 | return False |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 246 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 247 | kids = 'children' |
| 248 | elements.pop() |
| 249 | d = self.root |
| 250 | for k in elements[:-1]: |
| 251 | d = d[k][kids] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 252 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 253 | if 'data' not in d[elements[-1]] and not d[elements[-1]][kids]: |
| 254 | del d[elements[-1]] |
| 255 | self._try_delete_parent(elements) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 256 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 257 | def _get_node(self, key): |
| 258 | kids = 'children' |
| 259 | elements = ['/'] + filter(bool, key.split('/')) |
| 260 | d = self.root |
| 261 | for k in elements[:-1]: |
| 262 | try: |
| 263 | d = d[k][kids] |
| 264 | except KeyError: |
| 265 | raise KeyError(key) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 266 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 267 | return d[elements[-1]] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 268 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 269 | def __iter__(self): |
| 270 | return self |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 271 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 272 | def __missing__(self, key): |
| 273 | for x in self.iterkeys(): |
| 274 | if key == x: |
| 275 | return False |
| 276 | return True |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 277 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 278 | def __delitem__(self, key): |
| 279 | kids = 'children' |
| 280 | elements = ['/'] + filter(bool, key.split('/')) |
| 281 | d = self.root |
| 282 | for k in elements[:-1]: |
| 283 | try: |
| 284 | d = d[k][kids] |
| 285 | except KeyError: |
| 286 | raise KeyError(key) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 287 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 288 | del d[elements[-1]] |
| 289 | self._try_delete_parent(elements) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 290 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 291 | def __setitem__(self, key, value): |
| 292 | kids = 'children' |
| 293 | elements = ['/'] + filter(bool, key.split('/')) |
| 294 | d = self.root |
| 295 | for k in elements[:-1]: |
| 296 | d = d.setdefault(k, {kids: {}})[kids] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 297 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 298 | children = d.setdefault(elements[-1], {kids: {}})[kids] |
| 299 | d[elements[-1]].update({kids: children, 'data': value}) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 300 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 301 | def __getitem__(self, key): |
| 302 | return self._get_node(key).get('data') |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 303 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 304 | def setdefault(self, key, default): |
| 305 | if not self.get(key): |
| 306 | self.__setitem__(key, default) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 307 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 308 | return self.__getitem__(key) |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 309 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 310 | def get(self, key, default=None): |
| 311 | try: |
| 312 | x = self.__getitem__(key) |
| 313 | except KeyError: |
| 314 | x = default |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 315 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 316 | return x |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 317 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 318 | def get_children(self, key): |
| 319 | return [x for x in self._get_node(key)['children'].iterkeys()] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 320 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 321 | def demote(self, key): |
| 322 | n = self._get_node(key) |
| 323 | if 'data' in n: |
| 324 | del n['data'] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 325 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 326 | def keys(self, subtree='/', depth=None): |
| 327 | return [x for x in self.iterkeys(subtree, depth)] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 328 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 329 | def values(self, subtree='/', depth=None): |
| 330 | return [x[1] for x in self.iteritems(subtree, depth)] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 331 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 332 | def items(self, subtree='/', depth=None): |
| 333 | return [x for x in self.iteritems(subtree, depth)] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 334 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 335 | def dataitems(self, subtree='/', depth=None): |
| 336 | return [x for x in self.iteritems(subtree, depth) |
| 337 | if x[1] is not None] |
Brad Bishop | e318ec2 | 2015-11-03 09:12:52 -0500 | [diff] [blame] | 338 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 339 | def iterkeys(self, subtree='/', depth=None): |
| 340 | if not self.root: |
| 341 | return {}.iterkeys() |
| 342 | return PathTreeKeyIterator(self, subtree, depth) |
| 343 | |
| 344 | def iteritems(self, subtree='/', depth=None): |
| 345 | if not self.root: |
| 346 | return {}.iteritems() |
| 347 | return PathTreeItemIterator(self, subtree, depth) |
| 348 | |
Brad Bishop | 77fc9df | 2015-11-03 14:45:07 -0500 | [diff] [blame] | 349 | |
| 350 | class Mapper: |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 351 | def __init__(self, bus): |
| 352 | self.bus = bus |
| 353 | obj = bus.get_object(MAPPER_NAME, MAPPER_PATH, introspect=False) |
| 354 | self.iface = dbus.Interface( |
| 355 | obj, dbus_interface=MAPPER_IFACE) |
Brad Bishop | 77fc9df | 2015-11-03 14:45:07 -0500 | [diff] [blame] | 356 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 357 | def get_object(self, path): |
| 358 | return self.iface.GetObject(path) |
Brad Bishop | 77fc9df | 2015-11-03 14:45:07 -0500 | [diff] [blame] | 359 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 360 | def get_subtree_paths(self, path='/', depth=0): |
| 361 | return self.iface.GetSubTreePaths(path, depth) |
Brad Bishop | 77fc9df | 2015-11-03 14:45:07 -0500 | [diff] [blame] | 362 | |
Brad Bishop | 4b84941 | 2016-02-04 15:40:26 -0500 | [diff] [blame] | 363 | def get_subtree(self, path='/', depth=0): |
| 364 | return self.iface.GetSubTree(path, depth) |