Package PyFoam :: Package Infrastructure :: Module Configuration
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Infrastructure.Configuration

  1  #  ICE Revision: $Id$ 
  2  """Reads configuration-files that define defaults for various PyFoam-Settings 
  3   
  4  Also hardcodes defaults for the settings""" 
  5   
  6  from PyFoam.ThirdParty.six.moves import configparser 
  7  from PyFoam.ThirdParty.six import iteritems,PY3 
  8   
  9  from PyFoam.Infrastructure.Hardcoded import globalConfigFile,userConfigFile,globalDirectory,userDirectory,globalConfigDir,userConfigDir 
 10   
 11  from os import path 
 12  import glob,re 
 13   
 14  _defaults={ 
 15      "Network": { 
 16      "startServerPort"  : "18000", 
 17      "nrServerPorts"    : "100", 
 18      "portWait"         : "1.", 
 19      "socketTimeout"    : "1.", 
 20      "socketRetries"    : "10", 
 21      }, 
 22      "Metaserver": { 
 23      "port"             : "17999", 
 24      "ip"               : "192.168.1.11", 
 25      "checkerSleeping"  : "30.", 
 26      "searchServers"    : "192.168.1.0/24,192.168.0.0/24", 
 27      "webhost"          : "127.0.0.1:9000", 
 28      "doWebsync"        : "True", 
 29      "websyncInterval"  : "300.", 
 30      }, 
 31      "IsAlive": { 
 32      "maxTimeStart"     : "30.", 
 33      "isLivingMargin"   : "1.1" 
 34      }, 
 35      "Logging": { 
 36      "default" : "INFO", 
 37      "server" : "INFO", 
 38      }, 
 39      "OpenFOAM": { 
 40      "Forks" : 'openfoam,extend', 
 41      "DirPatterns-openfoam" : '"^OpenFOAM-([0-9]\.[0-9].*)$","^openfoam([0-9]+)$"', 
 42      "DirPatterns-extend" : '"^foam-extend-([0-9]\.[0-9].*)$"', 
 43      "Installation-openfoam" : "~/OpenFOAM", 
 44      "Installation-extend" : "~/foam", 
 45      "AdditionalInstallation-openfoam" : '"~/OpenFOAM"', 
 46      "Version" : "1.5", 
 47      }, 
 48      "MPI": { 
 49  #    "run_OPENMPI":"mpirun", 
 50  #    "run_LAM":"mpirun", 
 51      "OpenMPI_add_prefix":"False", 
 52      "options_OPENMPI_pre": '["--mca","pls","rsh","--mca","pls_rsh_agent","rsh"]', 
 53      "options_OPENMPI_post":'["-x","PATH","-x","LD_LIBRARY_PATH","-x","WM_PROJECT_DIR","-x","PYTHONPATH","-x","FOAM_MPI_LIBBIN","-x","MPI_BUFFER_SIZE","-x","MPI_ARCH_PATH"]' 
 54      }, 
 55      "Paths": { 
 56      "python" : "/usr/bin/python", 
 57      "bash" : "/bin/bash", 
 58      "paraview" : "paraview", 
 59      }, 
 60      "ClusterJob": { 
 61      "useFoamMPI":'["1.5"]', 
 62      "path":"/opt/openmpi/bin", 
 63      "ldpath":"/opt/openmpi/lib", 
 64      "doAutoReconstruct":"True", 
 65      "useMachineFile":"True", 
 66      }, 
 67      "Debug": { 
 68  #    "ParallelExecution":"True", 
 69      }, 
 70      "Execution":{ 
 71      "controlDictRestoreWait":"60.", 
 72      }, 
 73      "CaseBuilder":{ 
 74      "descriptionPath": eval('["'+path.curdir+'","'+path.join(userDirectory(),"caseBuilderDescriptions")+'","'+path.join(globalDirectory(),"caseBuilderDescriptions")+'"]'), 
 75      }, 
 76      "Formats":{ 
 77      "error"       : "bold,red,standout", 
 78      "warning"     : "under", 
 79      "source"      : "red,bold", 
 80      "destination" : "blue,bold", 
 81      "difference"  : "green,back_black,bold", 
 82      "question"    : "green,standout", 
 83      "input"       : "cyan,under", 
 84      }, 
 85      "CommandOptionDefaults":{ 
 86      "sortListCases":"mtime", 
 87      }, 
 88      "Plotting":{ 
 89      "preferredImplementation":"gnuplot", 
 90      }, 
 91      "OutfileCollection": { 
 92      "maximumOpenFiles":"100", 
 93      }, 
 94      "SolverOutput": { 
 95      "timeRegExp": "^(Time =|Iteration:) (.+)$", 
 96      }, 
 97      "Clearing": { 
 98      "additionalPatterns":"[]", 
 99      }, 
100      "postRunHook_WriteMySqlite" : { 
101          "enabled":False, 
102          "module":"WriteToSqliteDatabase", 
103          "createDatabase":False, 
104          "database":"~/databaseOfAllMyRuns.db", 
105      }, 
106      "postRunHook_SendToPushover" : { 
107          "enabled":False, 
108          "minRunTime":600, 
109          "useSSL":True, 
110          "module":"SendToWebservice", 
111          "host":"api.pushover.net:443", 
112          "method":"POST", 
113          "url":"/1/messages", 
114          "param_token":"invalid_get_yourself_one_at_pushover.net", 
115          "param_user":"invalid_get_yourself_an_account_at_pushover.net", 
116          "param_title":"<!--(if OK)-->Finished<!--(else)-->Failed<!--(end)-->: |-casename-| (|-solver-|)", 
117          "param_message":"""Case |-casefullname-| ended after |-wallTime-|s 
118  Last timestep: t=|-time-| 
119  Machine: |-hostname-| 
120  Full command: |-commandLine-|""", 
121          "header_Content-type": "application/x-www-form-urlencoded", 
122          "templates":"title message" 
123      }, 
124      "postRunHook_mailToMe" : { 
125          "enabled":False, 
126          "minRunTime":600, 
127          "module":"MailToAddress", 
128          "to":"nobody@here.there", 
129          "from":"a_concerned_user@your.local.machine", 
130          "smtpServer":"smtp.server.that.doesnt.need.authentication'", 
131          "subject":"<!--(if OK)-->Finished<!--(else)-->Failed<!--(end)-->: |-casename-| (|-solver-|)", 
132          "message":"""Case |-casefullname-| ended after |-wallTime-|s 
133  Last timestep: t=|-time-| 
134  Machine: |-hostname-| 
135  Full command: |-commandLine-|""", 
136          "mailFields_Reply-To": "nobody@nowhere.com", 
137      }, 
138      "Cloning" : { 
139          "addItem":"[]", 
140          "noForceSymlink":"[]", 
141      }, 
142      "PrepareCase" : { 
143          "MeshCreateScript":"meshCreate.sh", 
144          "CaseSetupScript":"caseSetup.sh", 
145      }, 
146      } 
147   
148 -class ConfigurationSectionProxy(object):
149 """Wraps a Confguration so that the section automatically becomes the 150 first argument""" 151
152 - def __init__(self,conf,section):
153 self.conf=conf 154 self.section=section
155
156 - def __getattr__(self,name):
157 f=getattr(self.conf,name) 158 def curried(*args,**kwargs): 159 return f(*((self.section,)+args),**kwargs)
160 return curried
161
162 -class Configuration(configparser.ConfigParser):
163 """Reads the settings from files (if existing). Otherwise uses hardcoded 164 defaults""" 165
166 - def __init__(self):
167 """Constructs the ConfigParser and fills it with the hardcoded defaults""" 168 configparser.ConfigParser.__init__(self) 169 170 for section,content in iteritems(_defaults): 171 self.add_section(section) 172 for key,value in iteritems(content): 173 self.set(section,key,str(value)) 174 175 self.read(self.configFiles()) 176 177 self.validSections={} 178 for s in self.sections(): 179 minusPos=s.find('-') 180 if minusPos<0: 181 name=s 182 else: 183 name=s[:minusPos] 184 try: 185 self.validSections[name].append(s) 186 except KeyError: 187 self.validSections[name]=[s] 188 189 for name,sections in iteritems(self.validSections): 190 if not name in sections: 191 print("Invalid configuration for",name,"there is no default section for it in",sections)
192
193 - def sectionProxy(self,section):
194 """Return a proxy object that makes it possible to avoid the section 195 specification""" 196 return ConfigurationSectionProxy(self,section)
197
198 - def bestSection(self,section,option):
199 """Get the best-fitting section that has that option""" 200 201 from PyFoam import foamVersionString 202 203 try: 204 if len(self.validSections[section])==1 or foamVersionString()=="": 205 return section 206 except KeyError: 207 return section 208 209 result=section 210 fullName=section+"-"+foamVersionString() 211 212 for s in self.validSections[section]: 213 if fullName.find(s)==0 and len(s)>len(result): 214 if self.has_option(s,option): 215 result=s 216 217 return result
218
219 - def configSearchPath(self):
220 """Defines a search path for the configuration files as a pare of type/name 221 pairs""" 222 files=[("file",globalConfigFile()), 223 ("directory",globalConfigDir()), 224 ("file",userConfigFile()), 225 ("directory",userConfigDir())] 226 return files
227
228 - def configFiles(self):
229 """Return a list with the configurationfiles that are going to be used""" 230 files=[] 231 232 for t,f in self.configSearchPath(): 233 if path.exists(f): 234 if t=="file": 235 files.append(f) 236 elif t=="directory": 237 for ff in glob.glob(path.join(f,"*.cfg")): 238 files.append(ff) 239 else: 240 error("Unknown type",t,"for the search entry",f) 241 242 return files
243
244 - def addFile(self,filename,silent=False):
245 """Add another file to the configuration (if it exists)""" 246 if not path.exists(filename): 247 if not silent: 248 print("The configuration file",filename,"is not there") 249 else: 250 self.read([filename])
251
252 - def dump(self):
253 """Dumps the contents in INI-Form 254 @return: a string with the contents""" 255 result="" 256 for section in self.sections(): 257 result+="[%s]\n" % (section) 258 for key,value in self.items(section): 259 result+="%s: %s\n" % (key,value) 260 result+="\n" 261 262 return result
263
264 - def getList(self,section,option,default="",splitchar=",",stripQuotes=True):
265 """Get a list of strings (in the original they are separated by commas) 266 @param section: the section 267 @param option: the option 268 @param default: if set and the option is not found, then this value is used 269 @param splitchar: the character by which the values are separated 270 @param stripQuotes: remove quotes if present""" 271 272 val=self.get(section,option,default=default) 273 if val=="": 274 return [] 275 else: 276 result=[] 277 for v in val.split(splitchar): 278 if v[0]=='"' and v[-1]=='"': 279 result.append(v[1:-1]) 280 else: 281 result.append(v) 282 return result
283
284 - def getboolean(self,section,option,default=None):
285 """Overrides the original implementation from ConfigParser 286 @param section: the section 287 @param option: the option 288 @param default: if set and the option is not found, then this value is used""" 289 290 try: 291 return configparser.ConfigParser.getboolean(self, 292 self.bestSection(section,option), 293 option) 294 except configparser.NoOptionError: 295 if default!=None: 296 return default 297 else: 298 raise
299
300 - def getint(self,section,option,default=None):
301 """Overrides the original implementation from ConfigParser 302 @param section: the section 303 @param option: the option 304 @param default: if set and the option is not found, then this value is used""" 305 306 try: 307 return int(configparser.ConfigParser.get(self, 308 self.bestSection(section,option), 309 option)) 310 except configparser.NoOptionError: 311 if default!=None: 312 return default 313 else: 314 raise
315
316 - def getfloat(self,section,option,default=None):
317 """Overrides the original implementation from ConfigParser 318 @param section: the section 319 @param option: the option 320 @param default: if set and the option is not found, then this value is used""" 321 322 try: 323 return float(configparser.ConfigParser.get(self, 324 self.bestSection(section,option), 325 option)) 326 except (configparser.NoOptionError,ValueError): 327 if default!=None: 328 return default 329 else: 330 raise
331
332 - def getRegexp(self,section,option):
333 """Get an entry and interpret it as a regular expression. Subsitute 334 the usual regular expression value for floating point numbers 335 @param section: the section 336 @param option: the option 337 @param default: if set and the option is not found, then this value is used""" 338 floatRegExp="[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?" 339 340 return re.compile(self.get(section,option).replace("%f%",floatRegExp))
341
342 - def get(self,section,option,default=None):
343 """Overrides the original implementation from ConfigParser 344 @param section: the section 345 @param option: the option 346 @param default: if set and the option is not found, then this value is used""" 347 348 try: 349 return configparser.ConfigParser.get(self, 350 self.bestSection(section,option), 351 option) 352 except configparser.NoOptionError: 353 if default!=None: 354 return default 355 else: 356 raise
357
358 - def getdebug(self,name):
359 """Gets a debug switch""" 360 361 return self.getboolean("Debug",name,default=False)
362 363 # Should work with Python3 and Python2 364