Mini Shell
# HalTree Purpose:
#
# HalTree is a way to organize the mess of data you get from hal. In general,
# if you want to get all the information about every device in the system, you
# end up with a list of dicts, where each dict contains the property name/values
# for a device. This list isn't very useful as the hal data is actually
# organized into a tree. For example, you have the computer as the head, then
# there may be a scsi card plugged in. That in turn will have scsi channels
# and luns, which scsi devices may be connected to. So this module will help
# you reorganize your hal data back to the way they were intended.
#
# HalTree Usage:
#
# The tree gets built one device at a time. Once you've created a HalTree
# object, devices get added to the tree with HalTree.add(hw_dev_dict). The
# devices can be added in any particular order, and the tree gets properly
# structured as the devices get added. But the tree structure isn't likely
# to be ready until all the devices have been added. Those devices without a
# parent get stuck in the no_parent_yet list.
#
# When a device gets added, it is no longer a plain dict. It is stored in a
# HalDevice. The original dict can be found in HalDevice.properties.
try: # python2
from types import StringType, IntType
except ImportError: # python3
StringType = bytes
IntType = int
class HalDevice:
"An object containing its udi, properties and children"
def __init__ (self, properties):
self.udi = properties['info.udi']
self.properties = properties
self.children = []
self.classification = None
if 'info.parent' in properties:
self.parent_udi = properties['info.parent']
else:
self.parent_udi = None
self.parent = None
def print_properties(self):
print(self.udi, ":")
for property, value in self.properties.items():
print(" ", property," ==> ", value)
class HalTree:
def __init__ (self):
self.head = None
self.no_parent_yet = []
def add(self, hal_device):
if hal_device.parent_udi:
parent = self.__find_node(hal_device.parent_udi)
if parent:
parent.children.append(hal_device)
hal_device.parent = parent
else: #parent isn't in the main tree yet, stick it in waiting
self.no_parent_yet.append(hal_device)
else: #if it doesn't have a parent, it must be the head 'computer'
self.head = hal_device
#check to see if there are any children waiting for this dev
self.__get_lost_children(hal_device)
def __get_lost_children(self, hal_device):
found_list = []
indexes = []
no_parent_yet_copy = self.no_parent_yet[:]
for dev in no_parent_yet_copy:
if dev.parent_udi == hal_device.udi:
dev.parent = hal_device
hal_device.children.append(dev)
self.no_parent_yet.remove(dev)
def __find_node(self, udi):
"""
This takes a node in the HalDevice tree and returns the HalDevice with
the given udi.
"""
if self.head:
node = HalTree.__find_node_worker(self.head, udi)
if node:
return node
for node in self.no_parent_yet:
found_node = HalTree.__find_node_worker(node, udi)
if found_node:
return found_node
return None
@staticmethod
def __find_node_worker(node, udi):
if node.udi == udi:
return node
for device in node.children:
res = HalTree.__find_node_worker(device, udi)
if res:
return res
return None
def print_tree(self):
self.__print_dev_tree(self.head, "")
def __print_dev_tree(self, node, indent):
print(indent, node.udi)
print(indent, "CLASS:", node.classification)
for name, property in node.properties.items():
if (type(property) == StringType):
if property.isdigit():
print(indent + " ", "%-20s ==> %s" % (name, hex(int(property))))
else:
print(indent + " ", "%-20s ==> %s" % (name, property))
elif (type(property) == IntType):
print(indent + " ", "%-20s ==> %s" % (name, hex(int(property))))
else:
print(indent + " ", "%-20s ==> %s" % (name, property))
print
for child in node.children:
self.__print_dev_tree(child, indent + " ")
Zerion Mini Shell 1.0