Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. ###########################################################
  2. #
  3. # Daemon configuration
  4. #
  5. ###########################################################
  6. import logging as log
  7. import pickle
  8. import hashlib
  9. import os
  10. import imp
  11. import re
  12. from ConfigParser import ConfigParser
  13. import filters
  14. import statespaces
  15.  
  16.  
  17. class DynamicModuleCfg:
  18.     """Dynamic module manager"""
  19.  
  20.     modSubDir = None
  21.     CHECKSUM_FILE = 'checksums'
  22.     CHECKSUM_SECTION = 'SHA-1_CHECKSUMS'
  23.    
  24.     def __init__(self, modSubDir):
  25.         self.modSubDir = modSubDir
  26.         self.checkSumFile = modSubDir + '/' + self.CHECKSUM_FILE
  27.    
  28.    
  29.     def loadModule(self, className):
  30.         pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
  31.         log.debug('Reading from ' + pFileName)
  32.         fp = open(pFileName, 'r')
  33.         p = pickle.Unpickler(fp)
  34.         loadedMod = p.load()
  35.         fp.close()
  36.         if not self.__verifyCheckSum(className, pFileName):
  37.             print 'Invalid checksum'
  38.             return None
  39.         else:
  40.             return loadedMod
  41.        
  42.        
  43.     def loadModules(self, config = None):
  44.         subDirFiles = os.listdir(os.getcwd() + '/' + self.modSubDir)
  45.         p = re.compile('.p$', re.IGNORECASE)
  46.         modFiles = [elem for elem in subDirFiles if p.search(elem) is not None]
  47.         modNames = []
  48.         for mfName in modFiles:
  49.             modNames.append(mfName.split('.')[0])
  50.         log.debug('Found modules: ' + str(modNames))
  51.         myMods = {}
  52.         for mName in modNames:
  53.             classObj = self.loadModule(mName)
  54.             if classObj is not None:
  55.                 myMods[mName] = classObj
  56.         return myMods
  57.  
  58.    
  59.     def saveModule(self, className, classObj):
  60.         pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
  61.         log.debug('Writing to ' + pFileName)
  62.         fp = open(pFileName, 'w')
  63.         p = pickle.Pickler(fp)
  64.         p.dump(classObj)
  65.         fp.close()
  66.         self.__writeCheckSum(className, pFileName)
  67.    
  68.    
  69.     def __doCheckSum(self, filename):
  70.         f = open(filename, 'r')
  71.         data = f.read()
  72.         f.close()
  73.         hasher = hashlib.sha1()
  74.         hasher.update(data)
  75.         digest = hasher.hexdigest()
  76.         return digest
  77.    
  78.    
  79.     def __writeCheckSum(self, entryname, filename):
  80.         csumsfile = open(self.checkSumFile, 'r+')
  81.         csumcfg = ConfigParser()
  82.         csumcfg.readfp(csumsfile)
  83.         digest = self.__doCheckSum(filename)
  84.         csumcfg.set(self.CHECKSUM_SECTION, entryname, digest)
  85.         csumsfile.seek(0)
  86.         csumcfg.write(csumsfile)
  87.        
  88.        
  89.     def __verifyCheckSum(self, entryname, filename):
  90.         csumsfile = open(self.checkSumFile, 'r')
  91.         csumcfg = ConfigParser()
  92.         csumcfg.readfp(csumsfile)
  93.         digest = csumcfg.get(self.CHECKSUM_SECTION, entryname)
  94.         cur_digest = self.__doCheckSum(filename)
  95.         log.debug('Old checksum ' + digest + '\nNew checksum: ' + cur_digest)
  96.         if cur_digest == digest:
  97.             return True
  98.         return False
  99.    
  100.    
  101.     def importModule(self, className, requiredAttributes):
  102.         """Imports a given class from the module with the same name """
  103.  
  104.         codeFile = os.getcwd() + '/' + self.modSubDir + '/' + className + '.py'
  105.         mod = imp.load_source(self.modSubDir + '.' + className, codeFile)
  106.         newClass = eval('mod.' + className)()
  107.        
  108.         for ra in requiredAttributes:
  109.             if not hasattr(newClass, ra):
  110.                 print className, ': missing required symbol \"' + ra + '\"'
  111.                 return None
  112.        
  113.         self.saveModule(className, newClass)
  114.         return newClass
  115.  
  116.  
  117. class FilterCfg:
  118.     """Filter resource manager"""
  119.    
  120.     REQUIRED_ATTRIBUTES = ['ASSOCIATED_SPACES', 'DESCRIPTIVE_NAME',
  121.                            'attach', 'detach', 'filter']
  122.    
  123.     dynamicModuleCfg = None
  124.     FILTER_SUBDIR = 'filters'
  125.     filterModules = {}
  126.    
  127.     def __init__(self):
  128.         self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
  129.    
  130.     def loadFilter(self, name):
  131.         newFilt = self.dynamicModuleCfg.loadModule(name)
  132.         if newFilt is not None:
  133.             filterModules[name] = newFilt
  134.             return True
  135.         else:
  136.             return False
  137.  
  138.     def loadFilters(self, config = None):
  139.         self.filterModules = self.dynamicModuleCfg.loadModules()
  140.         for fM in self.filterModules:
  141.             log.debug(fM)
  142.  
  143.     def __saveFilter(self, className, classObj):
  144.         self.dynamicModuleCfg.saveModule(className, classObj)
  145.  
  146.     def saveFilters(self):
  147.         for className in self.filterModules:
  148.             self.__saveFilter(className, self.filterModules[className])
  149.        
  150.     def importFilter(self, className):
  151.         """Imports a given filter definition """
  152.         classObj = self.dynamicModuleCfg.importModule(className, self.REQUIRED_ATTRIBUTES)
  153.         if classObj is not None:
  154.             print 'Imported: ' + classObj.DESCRIPTIVE_NAME
  155.             return True
  156.         else:
  157.             return False
  158.        
  159.  
  160. class StateSpaceCfg:
  161.     """State space resource manager"""
  162.    
  163.     REQUIRED_ATTRIBUTES = ['DESCRIPTIVE_NAME',
  164.                            'load', 'reset', 'run', 'unload']
  165.    
  166.     dynamicModuleCfg = None
  167.     FILTER_SUBDIR = 'statespaces'
  168.     spaceModules = {}
  169.    
  170.     def __init__(self):
  171.         self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
  172.    
  173.     def loadSpace(self, name):
  174.         newSpace = self.dynamicModuleCfg.loadModule(name)
  175.         if newSpace is not None:
  176.             spaceModules[name] = newFilt
  177.             return True
  178.         else:
  179.             return False
  180.  
  181.     def loadSpaces(self, config = None):
  182.         self.spaceModules = self.dynamicModuleCfg.loadModules()
  183.         for sM in self.spaceModules:
  184.             log.debug(sM)
  185.  
  186.     def __saveSpace(self, className, classObj):
  187.         self.dynamicModuleCfg.saveModule(className, classObj)
  188.  
  189.     def saveSpaces(self):
  190.         for className in self.spaceModules:
  191.             self.__saveSpace(className, self.spaceModules[className])
  192.    
  193.     def importSpace(self, name):
  194.         """Imports a given state space definition file """
  195.         classObj = self.dynamicModuleCfg.importModule(name, self.REQUIRED_ATTRIBUTES)
  196.         if classObj is not None:
  197.             print 'Imported: ' + classObj.DESCRIPTIVE_NAME
  198.             return True
  199.         else:
  200.             return False
  201.  
  202. class DaemonConfig:
  203.    
  204.     stateSpaceCfg = None
  205.     filterCfg = None
  206.     filterChain = []
  207.    
  208.     def __init__ (self):
  209.         self.filterCfg = FilterCfg()
  210.         self.stateSpaceCfg = StateSpaceCfg()
  211.        
  212.     def setupFilterChain(self):
  213.         self.filterChain = ['DefaultFilter']
  214.    
  215.     def setupFilterBindings(self):
  216.         for f in self.filterCfg.filterModules.values():
  217.             assocSpaces = []
  218.             for s in f.ASSOCIATED_SPACES:
  219.                 if self.stateSpaceCfg.spaceModules.has_key(s):
  220.                     assocSpaces.append(self.stateSpaceCfg.spaceModules[s])
  221.                 else:
  222.                     print 'WARNING: Reference to undefined state space: ' + s
  223.             setattr(f, '__ASSOCIATED_SPACES__', assocSpaces)
  224.    
  225.