Subversion Repositories HomeAutomation

Rev

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

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