1
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 "Installation" : "~/OpenFOAM",
41 "AdditionalInstallation" : "~/OpenFOAM",
42 "Version" : "1.5",
43 },
44 "MPI": {
45
46
47 "OpenMPI_add_prefix":"False",
48 "options_OPENMPI_pre": '["--mca","pls","rsh","--mca","pls_rsh_agent","rsh"]',
49 "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"]'
50 },
51 "Paths": {
52 "python" : "/usr/bin/python",
53 "bash" : "/bin/bash",
54 "paraview" : "paraview",
55 },
56 "ClusterJob": {
57 "useFoamMPI":'["1.5"]',
58 "path":"/opt/openmpi/bin",
59 "ldpath":"/opt/openmpi/lib",
60 "doAutoReconstruct":"True",
61 },
62 "Debug": {
63
64 },
65 "Execution":{
66 "controlDictRestoreWait":"60.",
67 },
68 "CaseBuilder":{
69 "descriptionPath": eval('["'+path.curdir+'","'+path.join(userDirectory(),"caseBuilderDescriptions")+'","'+path.join(globalDirectory(),"caseBuilderDescriptions")+'"]'),
70 },
71 "Formats":{
72 "error" : "bold,red,standout",
73 "warning" : "under",
74 "source" : "red,bold",
75 "destination" : "blue,bold",
76 "difference" : "green,back_black,bold",
77 "question" : "green,standout",
78 "input" : "cyan,under",
79 },
80 "CommandOptionDefaults":{
81 "sortListCases":"mtime",
82 },
83 "Plotting":{
84 "preferredImplementation":"gnuplot",
85 },
86 "OutfileCollection": {
87 "maximumOpenFiles":"100",
88 },
89 "SolverOutput": {
90 "timeRegExp": "^(Time =|Iteration:) (.+)$",
91 },
92 "Clearing": {
93 "additionalPatterns":"[]",
94 },
95 "postRunHook_WriteMySqlite" : {
96 "enabled":False,
97 "module":"WriteToSqliteDatabase",
98 "createDatabase":False,
99 "database":"~/databaseOfAllMyRuns.db",
100 },
101 "postRunHook_SendToPushover" : {
102 "enabled":False,
103 "minRunTime":600,
104 "useSSL":True,
105 "module":"SendToWebservice",
106 "host":"api.pushover.net:443",
107 "method":"POST",
108 "url":"/1/messages",
109 "param_token":"invalid_get_yourself_one_at_pushover.net",
110 "param_user":"invalid_get_yourself_an_account_at_pushover.net",
111 "param_title":"<!--(if OK)-->Finished<!--(else)-->Failed<!--(end)-->: |-casename-| (|-solver-|)",
112 "param_message":"""Case |-casefullname-| ended after |-wallTime-|s
113 Last timestep: t=|-time-|
114 Machine: |-hostname-|
115 Full command: |-commandLine-|""",
116 "header_Content-type": "application/x-www-form-urlencoded",
117 "templates":"title message"
118 },
119 "postRunHook_mailToMe" : {
120 "enabled":False,
121 "minRunTime":600,
122 "module":"MailToAddress",
123 "to":"nobody@here.there",
124 "from":"a_concerned_user@your.local.machine",
125 "smtpServer":"smtp.server.that.doesnt.need.authentication'",
126 "subject":"<!--(if OK)-->Finished<!--(else)-->Failed<!--(end)-->: |-casename-| (|-solver-|)",
127 "message":"""Case |-casefullname-| ended after |-wallTime-|s
128 Last timestep: t=|-time-|
129 Machine: |-hostname-|
130 Full command: |-commandLine-|""",
131 "mailFields_Reply-To": "nobody@nowhere.com",
132 },
133 "Cloning" : {
134 "addItem":"[]",
135 },
136 }
137
139 """Wraps a Confguration so that the section automatically becomes the
140 first argument"""
141
143 self.conf=conf
144 self.section=section
145
147 f=getattr(self.conf,name)
148 def curried(*args,**kwargs):
149 return f(*((self.section,)+args),**kwargs)
150 return curried
151
153 """Reads the settings from files (if existing). Otherwise uses hardcoded
154 defaults"""
155
157 """Constructs the ConfigParser and fills it with the hardcoded defaults"""
158 configparser.ConfigParser.__init__(self)
159
160 for section,content in iteritems(_defaults):
161 self.add_section(section)
162 for key,value in iteritems(content):
163 self.set(section,key,str(value))
164
165 self.read(self.configFiles())
166
167 self.validSections={}
168 for s in self.sections():
169 minusPos=s.find('-')
170 if minusPos<0:
171 name=s
172 else:
173 name=s[:minusPos]
174 try:
175 self.validSections[name].append(s)
176 except KeyError:
177 self.validSections[name]=[s]
178
179 for name,sections in iteritems(self.validSections):
180 if not name in sections:
181 print("Invalid configuration for",name,"there is no default section for it in",sections)
182
184 """Return a proxy object that makes it possible to avoid the section
185 specification"""
186 return ConfigurationSectionProxy(self,section)
187
189 """Get the best-fitting section that has that option"""
190
191 from PyFoam import foamVersionString
192
193 try:
194 if len(self.validSections[section])==1 or foamVersionString()=="":
195 return section
196 except KeyError:
197 return section
198
199 result=section
200 fullName=section+"-"+foamVersionString()
201
202 for s in self.validSections[section]:
203 if fullName.find(s)==0 and len(s)>len(result):
204 if self.has_option(s,option):
205 result=s
206
207 return result
208
217
219 """Return a list with the configurationfiles that are going to be used"""
220 files=[]
221
222 for t,f in self.configSearchPath():
223 if path.exists(f):
224 if t=="file":
225 files.append(f)
226 elif t=="directory":
227 for ff in glob.glob(path.join(f,"*.cfg")):
228 files.append(ff)
229 else:
230 error("Unknown type",t,"for the search entry",f)
231
232 return files
233
234 - def addFile(self,filename,silent=False):
241
243 """Dumps the contents in INI-Form
244 @return: a string with the contents"""
245 result=""
246 for section in self.sections():
247 result+="[%s]\n" % (section)
248 for key,value in self.items(section):
249 result+="%s: %s\n" % (key,value)
250 result+="\n"
251
252 return result
253
254 - def getList(self,section,option,default="",splitchar=","):
255 """Get a list of strings (in the original they are separated by commas)
256 @param section: the section
257 @param option: the option
258 @param default: if set and the option is not found, then this value is used
259 @param splitchar: the character by which the values are separated"""
260
261 val=self.get(section,option,default=default)
262 if val=="":
263 return []
264 else:
265 return val.split(splitchar)
266
267 - def getboolean(self,section,option,default=None):
268 """Overrides the original implementation from ConfigParser
269 @param section: the section
270 @param option: the option
271 @param default: if set and the option is not found, then this value is used"""
272
273 try:
274 return configparser.ConfigParser.getboolean(self,
275 self.bestSection(section,option),
276 option)
277 except configparser.NoOptionError:
278 if default!=None:
279 return default
280 else:
281 raise
282
283 - def getint(self,section,option,default=None):
284 """Overrides the original implementation from ConfigParser
285 @param section: the section
286 @param option: the option
287 @param default: if set and the option is not found, then this value is used"""
288
289 try:
290 return int(configparser.ConfigParser.get(self,
291 self.bestSection(section,option),
292 option))
293 except configparser.NoOptionError:
294 if default!=None:
295 return default
296 else:
297 raise
298
299 - def getfloat(self,section,option,default=None):
300 """Overrides the original implementation from ConfigParser
301 @param section: the section
302 @param option: the option
303 @param default: if set and the option is not found, then this value is used"""
304
305 try:
306 return float(configparser.ConfigParser.get(self,
307 self.bestSection(section,option),
308 option))
309 except (configparser.NoOptionError,ValueError):
310 if default!=None:
311 return default
312 else:
313 raise
314
316 """Get an entry and interpret it as a regular expression. Subsitute
317 the usual regular expression value for floating point numbers
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 floatRegExp="[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?"
322
323 return re.compile(self.get(section,option).replace("%f%",floatRegExp))
324
325 - def get(self,section,option,default=None):
326 """Overrides the original implementation from ConfigParser
327 @param section: the section
328 @param option: the option
329 @param default: if set and the option is not found, then this value is used"""
330
331 try:
332 return configparser.ConfigParser.get(self,
333 self.bestSection(section,option),
334 option)
335 except configparser.NoOptionError:
336 if default!=None:
337 return default
338 else:
339 raise
340
342 """Gets a debug switch"""
343
344 return self.getboolean("Debug",name,default=False)
345
346
347