Salome HOME
Some Python refactoring and use argparse instead of optparse
[modules/yacs.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
212     return os.path.realpath(os.path.expanduser('~'))
213 # ---
214
215 def getTmpDir():
216     """
217     Get directory to be used for the temporary files.
218     """
219     import os, sys
220     if sys.platform == "win32":
221         # for Windows: temporarily using home directory for tmp files;
222         # to be replaced with TEMP environment variable later...
223         dir = os.getenv("HOME")
224     else:
225         # for Linux: use /tmp/logs/{user} folder
226         dir = os.path.join( '/tmp', 'logs', getUserName() )
227         pass
228     return dir
229
230 # ---
231
232 def generateFileName( dir, prefix = None, suffix = None, extension = None,
233                       unique = False, separator = "_", hidden = False, **kwargs ):
234     """
235     Generate file name by sepecified parameters. If necessary, file name
236     can be generated to be unique.
237
238     Parameters:
239     - dir       : directory path
240     - prefix    : file prefix (not added by default)
241     - suffix    : file suffix (not added by default)
242     - extension : file extension (not added by default)
243     - unique    : if this parameter is True, the unique file name is generated:
244     in this case, if the file with the generated name already exists
245     in the <dir> directory, an integer suffix is added to the end of the
246     file name. This parameter is False by default.
247     - separator : separator of the words ('_' by default)
248     - hidden    : if this parameter is True, the file name is prepended by . (dot)
249     symbol. This parameter is False by default.
250
251     Other keyword parameters are:
252     - with_username : 'add user name' flag/option:
253       * boolean value can be passed to determine user name automatically
254       * string value to be used as user name
255     - with_hostname : 'add host name' flag/option:
256       * boolean value can be passed to determine host name automatically
257       * string value to be used as host name
258     - with_port     : 'add port number' flag/option:
259       * boolean value can be passed to determine port number automatically
260       * string value to be used as port number
261     - with_app      : 'add application name' flag/option:
262       * boolean value can be passed to determine application name automatically
263       * string value to be used as application name
264     All <with_...> parameters are optional.
265     """
266     supported = [ 'with_username', 'with_hostname', 'with_port', 'with_app' ]
267     from launchConfigureParser import verbose
268     filename = []
269     # separator
270     if separator is None:
271         separator = ""
272         pass
273     else:
274         separator = str( separator )
275         pass
276     # prefix (if specified)
277     if prefix is not None:
278         filename.append( str( prefix ) )
279         pass
280     # additional keywords
281     ### check unsupported parameters
282     for kw in kwargs:
283         if kw not in supported and verbose():
284             print 'Warning! salome_utilitie.py: generateFileName(): parameter %s is not supported' % kw
285             pass
286         pass
287     ### process supported keywords
288     for kw in supported:
289         if kw not in kwargs: continue
290         ### user name
291         if kw == 'with_username':
292             try:
293                 # auto user name ?
294                 if _try_bool( kwargs[kw] ): filename.append( getUserName() )
295                 pass
296             except:
297                 # user name given as parameter
298                 filename.append( kwargs[kw] )
299                 pass
300             pass
301         ### host name
302         elif kw == 'with_hostname':
303             try:
304                 # auto host name ?
305                 if _try_bool( kwargs[kw] ): filename.append( getShortHostName() )
306                 pass
307             except:
308                 # host name given as parameter
309                 filename.append( kwargs[kw] )
310                 pass
311             pass
312         ### port number
313         elif kw == 'with_port':
314             try:
315                 # auto port number ?
316                 if _try_bool( kwargs[kw] ): filename.append( str( getPortNumber() ) )
317                 pass
318             except:
319                 # port number given as parameter
320                 filename.append( str( kwargs[kw] ) )
321                 pass
322             pass
323         ### application name
324         elif kw == 'with_app':
325             try:
326                 # auto application name ?
327                 if _try_bool( kwargs[kw] ): filename.append( getAppName() )
328                 pass
329             except:
330                 # application name given as parameter
331                 filename.append( kwargs[kw] )
332                 pass
333             pass
334         pass
335     # suffix (if specified)
336     if suffix is not None:
337         filename.append( str( suffix ) )
338         pass
339     # raise an exception if file name is empty
340     if not filename:
341         raise Exception("Empty file name")
342     #
343     if extension is not None and extension.startswith("."): extension = extension[1:]
344     #
345     import os
346     name = separator.join( filename )
347     if hidden: name = "." + name                       # add dot for hidden files
348     if extension: name = name + "." + str( extension ) # add extension if defined
349     name = os.path.join( dir, name )
350     if unique:
351         # create unique file name
352         index = 0
353         while os.path.exists( name ):
354             index = index + 1
355             name = separator.join( filename ) + separator + str( index )
356             if hidden: name = "." + name                       # add dot for hidden files
357             if extension: name = name + "." + str( extension ) # add extension if defined
358             name = os.path.join( dir, name )
359             pass
360         pass
361     return os.path.normpath(name)
362
363 # ---
364
365 def makeTmpDir( path, mode=0777 ):
366     """
367     Make temporary directory with the specified path.
368     If the directory exists then clear its contents.
369
370     Parameters:
371     - path : absolute path to the directory to be created.
372     - mode : access mode
373     """
374     import os
375     if os.path.exists( path ):
376         import sys
377         if sys.platform == "win32":
378             os.system( "rmdir /S /Q " + '"' + path + '"' )
379             os.system( "mkdir " + '"' + path + '"' )
380         else:
381             os.system( "rm -rf " + path + "/*" )
382     else:
383         dirs = path.split("/")
384         shift1 = shift2 = 0
385         if not dirs[0]: shift1 = 1
386         if dirs[-1]: shift2 = 1
387         for i in range(1+shift1,len(dirs)+shift2):
388             p = "/".join(dirs[:i])
389             try:
390                 os.mkdir(p, mode)
391                 os.chmod(p, mode)
392             except:
393                 pass
394
395 # ---
396
397 def uniteFiles( src_file, dest_file ):
398     """
399     Unite contents of the source file with contents of the destination file
400     and put result of the uniting to the destination file.
401     If the destination file does not exist then the source file is simply
402     copied to its path.
403
404     Parameters:
405     - src_file  : absolute path to the source file
406     - dest_file : absolute path to the destination file
407     """
408     import os
409
410     if not os.path.exists( src_file ):
411         return
412         pass
413
414     if os.path.exists( dest_file ):
415         # add a symbol of new line to contents of the destination file (just in case)
416         dest = open( dest_file, 'r' )
417         dest_lines = dest.readlines()
418         dest.close()
419
420         dest_lines.append( "\n" )
421
422         dest = open( dest_file, 'w' )
423         dest.writelines( dest_lines )
424         dest.close()
425
426         import sys
427         if sys.platform == "win32":
428             command = "type " + '"' + src_file + '"' + " >> " + '"' + dest_file + '"'
429         else:
430             command = "cat " + src_file + " >> " + dest_file
431             pass
432         pass
433     else:
434         import sys
435         if sys.platform == "win32":
436             command = "copy " + '"' + src_file + '"' + " " + '"' + dest_file + '"' + " > nul"
437         else:
438             command = "cp " + src_file + " " + dest_file
439             pass
440         pass
441
442     os.system( command )
443
444 # --
445
446 _verbose = None
447
448 def verbose():
449     """
450     Get verbosity level. Default verbosity level is specified via the environment variable
451     SALOME_VERBOSE, e.g.:
452     [bash %] export SALOME_VERBOSE=1
453     The function setVerbose() can be used to change verbosity level explicitly.
454     """
455     global _verbose
456     # verbose has already been called
457     if _verbose is not None:
458         return _verbose
459     # first time
460     try:
461         from os import getenv
462         _verbose = int(getenv('SALOME_VERBOSE'))
463     except:
464         _verbose = 0
465         pass
466     #
467     return _verbose
468
469 def setVerbose(level):
470     """
471     Change verbosity level. The function verbose() can be used to get current verbosity level.
472     """
473     global _verbose
474     _verbose = level
475     return
476