Subversion Repositories HomeAutomation

Rev

Rev 736 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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