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 "Cloning" : {
120 "addItem":"[]",
121 },
122 }
123
125 """Wraps a Confguration so that the section automatically becomes the
126 first argument"""
127
129 self.conf=conf
130 self.section=section
131
133 f=getattr(self.conf,name)
134 def curried(*args,**kwargs):
135 return f(*((self.section,)+args),**kwargs)
136 return curried
137
139 """Reads the settings from files (if existing). Otherwise uses hardcoded
140 defaults"""
141
143 """Constructs the ConfigParser and fills it with the hardcoded defaults"""
144 configparser.ConfigParser.__init__(self)
145
146 for section,content in iteritems(_defaults):
147 self.add_section(section)
148 for key,value in iteritems(content):
149 self.set(section,key,str(value))
150
151 self.read(self.configFiles())
152
153 self.validSections={}
154 for s in self.sections():
155 minusPos=s.find('-')
156 if minusPos<0:
157 name=s
158 else:
159 name=s[:minusPos]
160 try:
161 self.validSections[name].append(s)
162 except KeyError:
163 self.validSections[name]=[s]
164
165 for name,sections in iteritems(self.validSections):
166 if not name in sections:
167 print("Invalid configuration for",name,"there is no default section for it in",sections)
168
170 """Return a proxy object that makes it possible to avoid the section
171 specification"""
172 return ConfigurationSectionProxy(self,section)
173
175 """Get the best-fitting section that has that option"""
176
177 from PyFoam import foamVersionString
178
179 try:
180 if len(self.validSections[section])==1 or foamVersionString()=="":
181 return section
182 except KeyError:
183 return section
184
185 result=section
186 fullName=section+"-"+foamVersionString()
187
188 for s in self.validSections[section]:
189 if fullName.find(s)==0 and len(s)>len(result):
190 if self.has_option(s,option):
191 result=s
192
193 return result
194
203
205 """Return a list with the configurationfiles that are going to be used"""
206 files=[]
207
208 for t,f in self.configSearchPath():
209 if path.exists(f):
210 if t=="file":
211 files.append(f)
212 elif t=="directory":
213 for ff in glob.glob(path.join(f,"*.cfg")):
214 files.append(ff)
215 else:
216 error("Unknown type",t,"for the search entry",f)
217
218 return files
219
220 - def addFile(self,filename,silent=False):
227
229 """Dumps the contents in INI-Form
230 @return: a string with the contents"""
231 result=""
232 for section in self.sections():
233 result+="[%s]\n" % (section)
234 for key,value in self.items(section):
235 result+="%s: %s\n" % (key,value)
236 result+="\n"
237
238 return result
239
240 - def getList(self,section,option,default="",splitchar=","):
241 """Get a list of strings (in the original they are separated by commas)
242 @param section: the section
243 @param option: the option
244 @param default: if set and the option is not found, then this value is used
245 @param splitchar: the character by which the values are separated"""
246
247 val=self.get(section,option,default=default)
248 if val=="":
249 return []
250 else:
251 return val.split(splitchar)
252
253 - def getboolean(self,section,option,default=None):
254 """Overrides the original implementation from ConfigParser
255 @param section: the section
256 @param option: the option
257 @param default: if set and the option is not found, then this value is used"""
258
259 try:
260 return configparser.ConfigParser.getboolean(self,
261 self.bestSection(section,option),
262 option)
263 except configparser.NoOptionError:
264 if default!=None:
265 return default
266 else:
267 raise
268
269 - def getint(self,section,option,default=None):
270 """Overrides the original implementation from ConfigParser
271 @param section: the section
272 @param option: the option
273 @param default: if set and the option is not found, then this value is used"""
274
275 try:
276 return int(configparser.ConfigParser.get(self,
277 self.bestSection(section,option),
278 option))
279 except configparser.NoOptionError:
280 if default!=None:
281 return default
282 else:
283 raise
284
285 - def getfloat(self,section,option,default=None):
286 """Overrides the original implementation from ConfigParser
287 @param section: the section
288 @param option: the option
289 @param default: if set and the option is not found, then this value is used"""
290
291 try:
292 return float(configparser.ConfigParser.get(self,
293 self.bestSection(section,option),
294 option))
295 except (configparser.NoOptionError,ValueError):
296 if default!=None:
297 return default
298 else:
299 raise
300
302 """Get an entry and interpret it as a regular expression. Subsitute
303 the usual regular expression value for floating point numbers
304 @param section: the section
305 @param option: the option
306 @param default: if set and the option is not found, then this value is used"""
307 floatRegExp="[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?"
308
309 return re.compile(self.get(section,option).replace("%f%",floatRegExp))
310
311 - def get(self,section,option,default=None):
312 """Overrides the original implementation from ConfigParser
313 @param section: the section
314 @param option: the option
315 @param default: if set and the option is not found, then this value is used"""
316
317 try:
318 return configparser.ConfigParser.get(self,
319 self.bestSection(section,option),
320 option)
321 except configparser.NoOptionError:
322 if default!=None:
323 return default
324 else:
325 raise
326
328 """Gets a debug switch"""
329
330 return self.getboolean("Debug",name,default=False)
331
332
333