1#!/usr/bin/python 2 3import os 4import logging 5import xml.etree.ElementTree as ET 6 7# Default INDI data directory 8INDI_DATA_DIR = "/usr/local/share/indi/" 9 10 11class DeviceDriver: 12 """Device driver container""" 13 14 def __init__(self, name, label, version, binary, family, skel=None, custom=False): 15 self.name = name 16 self.label = label 17 self.skeleton = skel 18 self.version = version 19 self.binary = binary 20 self.family = family 21 self.custom = custom 22 23 24class DriverCollection: 25 """A collection of drivers""" 26 27 def __init__(self, path=INDI_DATA_DIR): 28 self.path = path 29 self.drivers = [] 30 self.files = [] 31 self.parse_drivers() 32 33 def parse_drivers(self): 34 for fname in os.listdir(self.path): 35 # Skip Skeleton files 36 if fname.endswith('.xml') and '_sk' not in fname: 37 self.files.append(os.path.join(self.path, fname)) 38 39 for fname in self.files: 40 try: 41 tree = ET.parse(fname) 42 root = tree.getroot() 43 44 for group in root.findall('devGroup'): 45 family = group.attrib['group'] 46 47 for device in group.findall('device'): 48 label = device.attrib['label'] 49 skel = device.attrib.get('skel', None) 50 drv = device.find('driver') 51 name = drv.attrib['name'] 52 binary = drv.text 53 version = device.findtext('version', '0.0') 54 55 skel_file = os.path.join(self.path, skel) if skel else None 56 driver = DeviceDriver(name, label, version, 57 binary, family, skel_file) 58 self.drivers.append(driver) 59 60 except KeyError as e: 61 logging.error("Error in file %s: attribute %s not found" % (fname, e)) 62 except ET.ParseError as e: 63 logging.error("Error in file %s: %s" % (fname, e)) 64 65 # Sort all drivers by label 66 self.drivers.sort(key=lambda x: x.label) 67 68 def parse_custom_drivers(self, drivers): 69 for custom in drivers: 70 driver = DeviceDriver(custom['name'], custom['label'], custom['version'], custom['exec'], 71 custom['family'], None, True) 72 self.drivers.append(driver) 73 74 def clear_custom_drivers(self): 75 self.drivers = list(filter(lambda driver: driver.custom is not True, self.drivers)) 76 77 def by_label(self, label): 78 for driver in self.drivers: 79 if (driver.label == label): 80 return driver 81 82 return None 83 84 def by_name(self, name): 85 for driver in self.drivers: 86 if (driver.name == name): 87 return driver 88 89 return None 90 91 def by_binary(self, binary): 92 for driver in self.drivers: 93 if (driver.binary == binary): 94 return driver 95 96 return None 97 98 def get_families(self): 99 families = {} 100 for drv in self.drivers: 101 if drv.family in families: 102 families[drv.family].append(drv.label) 103 else: 104 families[drv.family] = [drv.label] 105 return families 106