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 | ||