Salome HOME
a27009a45e81d300c436e11fd996af1bca51291a
[modules/kernel.git] / bin / salome_utils.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 # ---
22 # File   : salome_utils.py
23 # Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
24 # ---
25
26 ## @package salome_utils
27 # \brief Set of utility functions used by SALOME python scripts.
28
29 #
30 # Exported functions
31 #
32
33 __all__ = [
34     'getORBcfgInfo',
35     'getHostFromORBcfg',
36     'getPortFromORBcfg',
37     'getUserName',
38     'getHostName',
39     'getShortHostName',
40     'getAppName',
41     'getPortNumber',
42     'getTmpDir',
43     'getHomeDir',
44     'generateFileName',
45     'makeTmpDir',
46     'uniteFiles',
47     ]
48
49 # ---
50
51 def _try_bool( arg ):
52     """
53     Check if specified parameter represents boolean value and returns its value.
54     String values like 'True', 'TRUE', 'YES', 'Yes', 'y', 'NO', 'false', 'n', etc
55     are supported.
56     If <arg> does not represent a boolean, an exception is raised.
57     """
58     import types
59     if type( arg ) == types.BooleanType  :
60         return arg
61     elif type( arg ) == types.StringType  :
62         v = str( arg ).lower()
63         if   v in [ "yes", "y", "true"  ]: return True
64         elif v in [ "no",  "n", "false" ]: return False
65         pass
66     raise Exception("Not boolean value")
67
68 # ---
69
70 def getORBcfgInfo():
71     """
72     Get omniORB current configuration.
73     Returns a list of three values: [ orb_version, host_name, port_number ].
74     
75     The information is retrieved from the omniORB configuration file defined
76     by the OMNIORB_CONFIG environment variable.
77     If omniORB configuration file can not be accessed, a list of three empty
78     strings is returned.
79     """
80     import os, re
81     ret = [ "", "", "" ]
82     try:
83         f = open( os.getenv( "OMNIORB_CONFIG" ) )
84         lines = f.readlines()
85         f.close()
86         regvar = re.compile( "(ORB)?InitRef.*corbaname::(.*):(\d+)\s*$" )
87         for l in lines:
88             try:
89                 m = regvar.match( l )
90                 if m:
91                     if m.group(1) is None:
92                         ret[0] = "4"
93                     else:
94                         ret[0] = "3"
95                         pass
96                     ret[1] = m.group(2)
97                     ret[2] = m.group(3)
98                     break
99                 pass
100             except:
101                 pass
102             pass
103         pass
104     except:
105         pass
106     return ret
107
108 # ---
109
110 def getHostFromORBcfg():
111     """
112     Get current omniORB host.
113     """
114     return getORBcfgInfo()[1]
115 # ---
116
117 def getPortFromORBcfg():
118     """
119     Get current omniORB port.
120     """
121     return getORBcfgInfo()[2]
122
123 # ---
124
125 def getUserName():
126     """
127     Get user name:
128     1. try USER environment variable
129     2. if fails, return 'unknown' as default user name
130     """
131     import os
132     return os.getenv( "USER", "unknown" ) # 'unknown' is default user name
133
134 # ---
135
136 def getHostName():
137     """
138     Get host name:
139     1. try socket python module gethostname() function
140     2. if fails, try HOSTNAME environment variable
141     3. if fails, try HOST environment variable
142     4. if fails, return 'unknown' as default host name
143     """
144     import os
145     try:
146         import socket
147         host = socket.gethostname()
148     except:
149         host = None
150         pass
151     if not host: host = os.getenv("HOSTNAME")
152     if not host: host = os.getenv("HOST")
153     if not host: host = "unknown"           # 'unknown' is default host name
154     return host
155
156 # ---
157
158 def getShortHostName():
159     """
160     Get short host name:
161     1. try socket python module gethostname() function
162     2. if fails, try HOSTNAME environment variable
163     3. if fails, try HOST environment variable
164     4. if fails, return 'unknown' as default host name
165     """
166     try:
167         return getHostName().split('.')[0]
168     except:
169         pass
170     return "unknown"           # 'unknown' is default host name
171     
172 # ---
173
174 def getAppName():
175     """
176     Get application name:
177     1. try APPNAME environment variable
178     2. if fails, return 'SALOME' as default application name
179     """
180     import os
181     return os.getenv( "APPNAME", "SALOME" ) # 'SALOME' is default user name
182
183 # ---
184
185 def getPortNumber(use_default=True):
186     """
187     Get current naming server port number:
188     1. try NSPORT environment variable
189     1. if fails, try to parse config file defined by OMNIORB_CONFIG environment variable
190     2. if fails, return 2809 as default port number (if use_default is True) or None (id use_default is False)
191     """
192     import os
193     try:
194         return int( os.getenv( "NSPORT" ) )
195     except:
196         pass
197     try:
198         port = int( getPortFromORBcfg() )
199         if port is not None: return port
200     except:
201         pass
202     if use_default: return 2809 # '2809' is default port number
203     return None
204
205 # ---
206
207 def getHomeDir():
208     """
209     Get home directory.
210     """
211     import os, sys
212     if sys.platform == "win32":
213         # for Windows the home directory is detected in the following way:
214         # 1. try USERPROFILE env variable
215         # 2. try combination of HOMEDRIVE and HOMEPATH env variables
216         # 3. try HOME env variable
217         # TODO: on Windows, also GetUserProfileDirectoryW() system function might be used
218         dir = os.getenv("USERPROFILE")
219         if not dir and os.getenv("HOMEDRIVE") and os.getenv("HOMEPATH"):
220             dir = os.path.join(os.getenv("HOMEDRIVE"), os.getenv("HOMEPATH"))
221         if not dir:
222             dir = os.getenv("HOME")
223         pass
224     else:
225         # for Linux: use HOME variable
226         dir = os.getenv("HOME")
227         pass
228     return dir
229 # ---
230
231 def getTmpDir():
232     """
233     Get directory to be used for the temporary files.
234     """
235     import os, sys
236     if sys.platform == "win32":
237         # for Windows: temporarily using home directory for tmp files;
238         # to be replaced with TEMP environment variable later...
239         dir = os.getenv("HOME")
240     else:
241         # for Linux: use /tmp/logs/{user} folder
242         dir = os.path.join( '/tmp', 'logs', getUserName() )
243         pass
244     return dir
245
246 # ---
247
248 def generateFileName( dir, prefix = None, suffix = None, extension = None,
249                       unique = False, separator = "_", hidden = False, **kwargs ):
250     """
251     Generate file name by sepecified parameters. If necessary, file name
252     can be generated to be unique.
253
254     Parameters:
255     - dir       : directory path
256     - prefix    : file prefix (not added by default)
257     - suffix    : file suffix (not added by default)
258     - extension : file extension (not added by default)
259     - unique    : if this parameter is True, the unique file name is generated:
260     in this case, if the file with the generated name already exists
261     in the <dir> directory, an integer suffix is added to the end of the
262     file name. This parameter is False by default.
263     - separator : separator of the words ('_' by default)
264     - hidden    : if this parameter is True, the file name is prepended by . (dot)
265     symbol. This parameter is False by default.
266
267     Other keyword parameters are:
268     - with_username : 'add user name' flag/option:
269       * boolean value can be passed to determine user name automatically
270       * string value to be used as user name
271     - with_hostname : 'add host name' flag/option:
272       * boolean value can be passed to determine host name automatically
273       * string value to be used as host name
274     - with_port     : 'add port number' flag/option:
275       * boolean value can be passed to determine port number automatically
276       * string value to be used as port number
277     - with_app      : 'add application name' flag/option:
278       * boolean value can be passed to determine application name automatically
279       * string value to be used as application name
280     All <with_...> parameters are optional.
281     """
282     supported = [ 'with_username', 'with_hostname', 'with_port', 'with_app' ]
283     from launchConfigureParser import verbose
284     filename = []
285     # separator
286     if separator is None:
287         separator = ""
288         pass
289     else:
290         separator = str( separator )
291         pass
292     # prefix (if specified)
293     if prefix is not None:
294         filename.append( str( prefix ) )
295         pass
296     # additional keywords
297     ### check unsupported parameters
298     for kw in kwargs:
299         if kw not in supported and verbose():
300             print 'Warning! salome_utilitie.py: generateFileName(): parameter %s is not supported' % kw
301             pass
302         pass
303     ### process supported keywords
304     for kw in supported:
305         if kw not in kwargs: continue
306         ### user name
307         if kw == 'with_username':
308             try:
309                 # auto user name ?
310                 if _try_bool( kwargs[kw] ): filename.append( getUserName() )
311                 pass
312             except:
313                 # user name given as parameter
314                 filename.append( kwargs[kw] )
315                 pass
316             pass
317         ### host name
318         elif kw == 'with_hostname':
319             try:
320                 # auto host name ?
321                 if _try_bool( kwargs[kw] ): filename.append( getShortHostName() )
322                 pass
323             except:
324                 # host name given as parameter
325                 filename.append( kwargs[kw] )
326                 pass
327             pass
328         ### port number
329         elif kw == 'with_port':
330             try:
331                 # auto port number ?
332                 if _try_bool( kwargs[kw] ): filename.append( str( getPortNumber() ) )
333                 pass
334             except:
335                 # port number given as parameter
336                 filename.append( str( kwargs[kw] ) )
337                 pass
338             pass
339         ### application name
340         elif kw == 'with_app':
341             try:
342                 # auto application name ?
343                 if _try_bool( kwargs[kw] ): filename.append( getAppName() )
344                 pass
345             except:
346                 # application name given as parameter
347                 filename.append( kwargs[kw] )
348                 pass
349             pass
350         pass
351     # suffix (if specified)
352     if suffix is not None:
353         filename.append( str( suffix ) )
354         pass
355     # raise an exception if file name is empty
356     if not filename:
357         raise Exception("Empty file name")
358     #
359     if extension is not None and extension.startswith("."): extension = extension[1:]
360     #
361     import os
362     name = separator.join( filename )
363     if hidden: name = "." + name                       # add dot for hidden files
364     if extension: name = name + "." + str( extension ) # add extension if defined
365     name = os.path.join( dir, name )
366     if unique:
367         # create unique file name
368         index = 0
369         while os.path.exists( name ):
370             index = index + 1
371             name = separator.join( filename ) + separator + str( index )
372             if hidden: name = "." + name                       # add dot for hidden files
373             if extension: name = name + "." + str( extension ) # add extension if defined
374             name = os.path.join( dir, name )
375             pass
376         pass
377     return os.path.normpath(name)
378
379 # ---
380
381 def makeTmpDir( path, mode=0777 ):
382     """
383     Make temporary directory with the specified path.
384     If the directory exists then clear its contents.
385
386     Parameters:
387     - path : absolute path to the directory to be created.
388     - mode : access mode
389     """
390     import os
391     if os.path.exists( path ):
392         import sys
393         if sys.platform == "win32":
394             os.system( "rmdir /S /Q " + '"' + path + '"' )
395             os.system( "mkdir " + '"' + path + '"' )
396         else:
397             os.system( "rm -rf " + path + "/*" )
398     else:
399         dirs = path.split("/")
400         shift1 = shift2 = 0
401         if not dirs[0]: shift1 = 1
402         if dirs[-1]: shift2 = 1
403         for i in range(1+shift1,len(dirs)+shift2):
404             p = "/".join(dirs[:i])
405             try:
406                 os.mkdir(p, mode)
407                 os.chmod(p, mode)
408             except:
409                 pass
410
411 # ---
412
413 def uniteFiles( src_file, dest_file ):
414     """
415     Unite contents of the source file with contents of the destination file
416     and put result of the uniting to the destination file.
417     If the destination file does not exist then the source file is simply
418     copied to its path.
419
420     Parameters:
421     - src_file  : absolute path to the source file
422     - dest_file : absolute path to the destination file
423     """
424     import os
425
426     if not os.path.exists( src_file ):
427         return
428         pass
429
430     if os.path.exists( dest_file ):
431         # add a symbol of new line to contents of the destination file (just in case)
432         dest = open( dest_file, 'r' )
433         dest_lines = dest.readlines()
434         dest.close()
435
436         dest_lines.append( "\n" )
437
438         dest = open( dest_file, 'w' )
439         dest.writelines( dest_lines )
440         dest.close()
441
442         import sys
443         if sys.platform == "win32":
444             command = "type " + '"' + src_file + '"' + " >> " + '"' + dest_file + '"'
445         else:
446             command = "cat " + src_file + " >> " + dest_file
447             pass
448         pass
449     else:
450         import sys
451         if sys.platform == "win32":
452             command = "copy " + '"' + src_file + '"' + " " + '"' + dest_file + '"' + " > nul"
453         else:
454             command = "cp " + src_file + " " + dest_file
455             pass
456         pass
457
458     os.system( command )
459
460 # --
461
462 _verbose = None
463
464 def verbose():
465     """
466     Get verbosity level. Default verbosity level is specified via the environment variable
467     SALOME_VERBOSE, e.g.:
468     [bash %] export SALOME_VERBOSE=1
469     The function setVerbose() can be used to change verbosity level explicitly.
470     """
471     global _verbose
472     # verbose has already been called
473     if _verbose is not None:
474         return _verbose
475     # first time
476     try:
477         from os import getenv
478         _verbose = int(getenv('SALOME_VERBOSE'))
479     except:
480         _verbose = 0
481         pass
482     #
483     return _verbose
484
485 def setVerbose(level):
486     """
487     Change verbosity level. The function verbose() can be used to get current verbosity level.
488     """
489     global _verbose
490     _verbose = level
491     return
492