4
# Script to generate a nice PNG file of the currently running unity introspection tree.
5
from argparse import ArgumentParser
7
from os.path import splitext
11
from autopilot.emulators.unity import get_state_by_path
12
except ImportError, e:
13
print "Error: could not import the autopilot python module."
14
print "Make sure the autopilot module is in your $PYTHONPATH."
20
print "Error: the 'pydot' module is required to run this script."
21
print "Try installing the 'python-pydot' package."
25
NODE_BLACKLIST=["Result"]
27
def string_rep(dbus_type):
28
"""Get a string representation of various dbus types."""
29
if type(dbus_type) == dbus.Boolean:
30
return repr(bool(dbus_type))
31
if type(dbus_type) == dbus.String:
32
return dbus_type.encode('ascii', errors='ignore')
33
if type(dbus_type) in (dbus.Int16, dbus.UInt16, dbus.Int32, dbus.UInt32, dbus.Int64, dbus.UInt64):
34
return repr(int(dbus_type))
35
if type(dbus_type) == dbus.Double:
36
return repr(float(dbus_type))
37
if type(dbus_type) == dbus.Array:
38
return ', '.join([string_rep(i) for i in dbus_type])
40
return repr(dbus_type)
44
"""Escape a string so it can be use in a dot label."""
45
return pydot.quote_if_necessary(s).replace('<','\\<').replace('>', '\\>').replace("'", "\\'")
48
def traverse_tree(state, parent, graph):
49
"""Recursively traverse state tree, building dot graph as we go."""
51
lbl = parent.get_comment() + "|"
52
# first, set labels for this node:
53
bits = ["%s=%s" % (k, string_rep(state[k])) for k in sorted(state.keys()) if k != 'Children']
54
lbl += "\l".join(bits)
55
parent.set_label(escape('"{' + lbl + '}"'))
56
if state.has_key('Children'):
57
# Add all array nodes as children of this node.
58
for child_name, child_state in state['Children']:
59
if child_name in NODE_BLACKLIST:
61
child = pydot.Node(str(NEXT_NODE_ID))
63
child.set_comment(child_name)
65
graph.add_edge(pydot.Edge(parent, child))
67
traverse_tree(child_state, child, graph)
70
if __name__ == '__main__':
71
parser = ArgumentParser()
72
mg = parser.add_mutually_exclusive_group(required=True)
73
mg.add_argument('-o', '--output', nargs=1,
74
help='Store output in specified file on disk.')
75
mg.add_argument('-d','--display', action='store_true',
76
help='Display output in image viewer.')
78
args = parser.parse_args()
80
introspection_tree = get_state_by_path('/')
82
graph.set_simplify(False)
83
graph.set_node_defaults(shape='Mrecord')
84
graph.set_fontname('Ubuntu')
85
graph.set_fontsize('10')
87
gnode_unity = pydot.Node("Unity")
88
gnode_unity.set_comment("Unity")
89
traverse_tree(introspection_tree[0], gnode_unity, graph)
92
base, extension = splitext(args.output[0])
93
write_method_name = 'write_' + extension[1:]
94
if hasattr(graph, write_method_name):
95
getattr(graph, write_method_name)(args.output[0])
97
print "Error: unsupported format: '%s'" % (extension)
99
from tempfile import NamedTemporaryFile
100
from subprocess import call
101
tf = NamedTemporaryFile(suffix='.png', delete=False)
102
tf.write(graph.create_png())
104
call(["eog", tf.name])
107
print 'unknown output mode!'