1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 # File : salome_utils.py
23 # Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 ## @package salome_utils
27 # \brief Set of utility functions used by SALOME python scripts.
54 Check if specified parameter represents boolean value and returns its value.
55 String values like 'True', 'TRUE', 'YES', 'Yes', 'y', 'NO', 'false', 'n', etc
57 If <arg> does not represent a boolean, an exception is raised.
59 if isinstance(arg, bool) :
61 elif isinstance(arg, (str, bytes)):
62 v = str( arg ).lower()
63 if v in [ "yes", "y", "true" ]: return True
64 elif v in [ "no", "n", "false" ]: return False
66 raise Exception("Not boolean value")
72 Get omniORB current configuration.
73 Returns a list of three values: [ orb_version, host_name, port_number ].
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
83 f = open( os.getenv( "OMNIORB_CONFIG" ) )
86 regvar = re.compile( "(ORB)?InitRef.*corbaname::(.*):(\d+)\s*$" )
91 if m.group(1) is None:
110 def getHostFromORBcfg():
112 Get current omniORB host.
114 return getORBcfgInfo()[1]
117 def getPortFromORBcfg():
119 Get current omniORB port.
121 return getORBcfgInfo()[2]
128 1. try USER environment variable (USERNAME on windows)
129 2. if fails, try LOGNAME (un*x)
130 3. if fails return 'unknown' as default user name
133 if sys.platform == "win32":
134 return os.getenv("USERNAME", "unknown")
136 user = os.getenv("USER")
139 return os.getenv("LOGNAME", "unknown")
145 1. try socket python module gethostname() function
146 2. if fails, try HOSTNAME environment variable
147 3. if fails, try HOST environment variable
148 4. if fails, return 'unknown' as default host name
152 host = socket.gethostname()
156 if not host: host = os.getenv("HOSTNAME")
157 if not host: host = os.getenv("HOST")
158 if not host: host = "unknown" # 'unknown' is default host name
160 socket.gethostbyname(host)
168 def getShortHostName():
171 1. try socket python module gethostname() function
172 2. if fails, try HOSTNAME environment variable
173 3. if fails, try HOST environment variable
174 4. if fails, return 'unknown' as default host name
177 return getHostName().split('.')[0]
180 return "unknown" # 'unknown' is default host name
186 Get application name:
187 1. try APPNAME environment variable
188 2. if fails, return 'SALOME' as default application name
191 return os.getenv( "APPNAME", "SALOME" ) # 'SALOME' is default user name
195 def getPortNumber(use_default=True):
197 Get current naming server port number:
198 1. try NSPORT environment variable
199 1. if fails, try to parse config file defined by OMNIORB_CONFIG environment variable
200 2. if fails, return 2809 as default port number (if use_default is True) or None (id use_default is False)
204 return int( os.getenv( "NSPORT" ) )
208 port = int( getPortFromORBcfg() )
209 if port is not None: return port
212 if use_default: return 2809 # '2809' is default port number
222 return os.path.realpath(os.path.expanduser('~'))
227 Get directory to be used for the log files.
230 return os.path.join(getTmpDir(), "logs", getUserName())
235 Get directory to be used for the temporary files.
238 f = tempfile.NamedTemporaryFile()
239 tmpdir = os.path.dirname(f.name)
244 def generateFileName( dir, prefix = None, suffix = None, extension = None,
245 unique = False, separator = "_", hidden = False, **kwargs ):
247 Generate file name by specified parameters. If necessary, file name
248 can be generated to be unique.
251 - dir : directory path
252 - prefix : file prefix (not added by default)
253 - suffix : file suffix (not added by default)
254 - extension : file extension (not added by default)
255 - unique : if this parameter is True, the unique file name is generated:
256 in this case, if the file with the generated name already exists
257 in the <dir> directory, an integer suffix is added to the end of the
258 file name. This parameter is False by default.
259 - separator : separator of the words ('_' by default)
260 - hidden : if this parameter is True, the file name is prepended by . (dot)
261 symbol. This parameter is False by default.
263 Other keyword parameters are:
264 - with_username : 'add user name' flag/option:
265 * boolean value can be passed to determine user name automatically
266 * string value to be used as user name
267 - with_hostname : 'add host name' flag/option:
268 * boolean value can be passed to determine host name automatically
269 * string value to be used as host name
270 - with_port : 'add port number' flag/option:
271 * boolean value can be passed to determine port number automatically
272 * string value to be used as port number
273 - with_app : 'add application name' flag/option:
274 * boolean value can be passed to determine application name automatically
275 * string value to be used as application name
276 All <with_...> parameters are optional.
278 supported = [ 'with_username', 'with_hostname', 'with_port', 'with_app' ]
279 from launchConfigureParser import verbose
282 if separator is None:
286 separator = str( separator )
288 # prefix (if specified)
289 if prefix is not None:
290 filename.append( str( prefix ) )
292 # additional keywords
293 ### check unsupported parameters
295 if kw not in supported and verbose():
296 print('Warning! salome_utilitie.py: generateFileName(): parameter %s is not supported' % kw)
299 ### process supported keywords
301 if kw not in kwargs: continue
303 if kw == 'with_username':
306 if _try_bool( kwargs[kw] ): filename.append( getUserName() )
309 # user name given as parameter
310 filename.append( kwargs[kw] )
314 elif kw == 'with_hostname':
317 if _try_bool( kwargs[kw] ): filename.append( getShortHostName() )
320 # host name given as parameter
321 filename.append( kwargs[kw] )
325 elif kw == 'with_port':
328 if _try_bool( kwargs[kw] ): filename.append( str( getPortNumber() ) )
331 # port number given as parameter
332 filename.append( str( kwargs[kw] ) )
336 elif kw == 'with_app':
338 # auto application name ?
339 if _try_bool( kwargs[kw] ): filename.append( getAppName() )
342 # application name given as parameter
343 filename.append( kwargs[kw] )
347 # suffix (if specified)
348 if suffix is not None:
349 filename.append( str( suffix ) )
351 # raise an exception if file name is empty
353 raise Exception("Empty file name")
355 if extension is not None and extension.startswith("."): extension = extension[1:]
358 name = separator.join( filename )
359 if hidden: name = "." + name # add dot for hidden files
360 if extension: name = name + "." + str( extension ) # add extension if defined
361 name = os.path.join( dir, name )
363 # create unique file name
365 while os.path.exists( name ):
367 name = separator.join( filename ) + separator + str( index )
368 if hidden: name = "." + name # add dot for hidden files
369 if extension: name = name + "." + str( extension ) # add extension if defined
370 name = os.path.join( dir, name )
373 return os.path.normpath(name)
377 def makeTmpDir( path, mode=0o777 ):
379 Make temporary directory with the specified path.
380 If the directory exists then clear its contents.
383 - path : absolute path to the directory to be created.
387 if os.path.exists( path ):
389 if sys.platform == "win32":
390 os.system( "rmdir /S /Q " + '"' + path + '"' )
391 os.system( "mkdir " + '"' + path + '"' )
393 os.system( "rm -rf " + path + "/*" )
395 dirs = path.split("/")
397 if not dirs[0]: shift1 = 1
398 if dirs[-1]: shift2 = 1
399 for i in range(1+shift1,len(dirs)+shift2):
400 p = "/".join(dirs[:i])
409 def uniteFiles( src_file, dest_file ):
411 Unite contents of the source file with contents of the destination file
412 and put result of the uniting to the destination file.
413 If the destination file does not exist then the source file is simply
417 - src_file : absolute path to the source file
418 - dest_file : absolute path to the destination file
422 if not os.path.exists( src_file ):
426 if os.path.exists( dest_file ):
427 # add a symbol of new line to contents of the destination file (just in case)
428 dest = open( dest_file, 'r' )
429 dest_lines = dest.readlines()
432 dest_lines.append( "\n" )
434 dest = open( dest_file, 'w' )
435 dest.writelines( dest_lines )
439 if sys.platform == "win32":
440 command = "type " + '"' + src_file + '"' + " >> " + '"' + dest_file + '"'
442 command = "cat " + src_file + " >> " + dest_file
447 if sys.platform == "win32":
448 command = "copy " + '"' + src_file + '"' + " " + '"' + dest_file + '"' + " > nul"
450 command = "cp " + src_file + " " + dest_file
462 Get verbosity level. Default verbosity level is specified via the environment variable
463 SALOME_VERBOSE, e.g.:
464 [bash %] export SALOME_VERBOSE=1
465 The function setVerbose() can be used to change verbosity level explicitly.
468 # verbose has already been called
469 if _verbose is not None:
473 from os import getenv
474 _verbose = int(getenv('SALOME_VERBOSE'))
482 def setVerbose(level):
484 Change verbosity level. The function verbose() can be used to get current verbosity level.
492 def killpid(pid, sig = 9):
494 Send signal sig to the process by pid.
497 - pid : PID of process
498 - sig : signal for sending
499 Possible values of signals:
500 9 means kill the process
501 0 only check existing of the process
502 NOTE: Other values are not processed on Windows
505 0 Fail, no such process
506 -1 Fail, another reason
512 if verbose(): print("######## killpid pid = ", pid)
514 if sys.platform == "win32":
517 # PROCESS_QUERY_INFORMATION (0x0400) Required to retrieve certain information about a process
518 SYNCHRONIZE = 0x100000
519 handle = ctypes.windll.kernel32.OpenProcess(SYNCHRONIZE, False, int(pid))
520 waitObj = ctypes.windll.kernel32.WaitForSingleObject(handle, 0)
523 ctypes.windll.kernel32.CloseHandle(handle)
527 # PROCESS_TERMINATE (0x0001) Required to terminate a process using TerminateProcess.
528 handle = ctypes.windll.kernel32.OpenProcess(0x0001, False, int(pid))
529 ret = ctypes.windll.kernel32.TerminateProcess(handle, -1)
530 ctypes.windll.kernel32.CloseHandle(handle)
534 # Default: signal.SIGKILL = 9
535 os.kill(int(pid),sig)
540 # errno.ESRCH == 3 is 'No such process'
550 def getOmniNamesPid(port):
552 Return OmniNames pid by port number.
554 import sys,subprocess,re
555 if sys.platform == "win32":
556 # Get process list by WMI Command Line Utility(WMIC)
557 # Output is formatted with each value listed on a separate line and with the name of the property:
560 # CommandLine=<commandline0>
561 # ProcessId=<processid0>
566 # CommandLine=<commandline1>
567 # ProcessId=<processid1>
569 cmd = 'WMIC PROCESS get Caption,Commandline,Processid /VALUE'
570 proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
572 allProc = proc.communicate()[0].decode()
573 # find Pid of omniNames
574 pid = re.findall(r'Caption=.*omniNames.*\n?CommandLine=.*omniNames.*\D%s\D.*\n?ProcessId=(\d*)'%(port),allProc)[0]
576 cmd = "ps -eo pid,command | grep -v grep | grep -E \"omniNames.*%s\" | awk '{print $1}'"%(port)
577 proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
578 pid = proc.communicate()[0]
584 def killOmniNames(port):
586 Kill OmniNames process by port number.
589 pid = getOmniNamesPid(port)