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
21 ## @package salome_utils
22 # @brief Set of utility functions used by SALOME python scripts.
25 Various utilities for SALOME.
28 # pragma pylint: disable=invalid-name
37 from contextlib import suppress
43 Convert given `arg` to a boolean value.
44 String values like 'True', 'TRUE', 'YES', 'Yes', 'y', 'NO', 'false', 'n', etc.
46 If `arg` does not represent a boolean, an exception is raised.
47 :param arg : value being converted
48 :return result of conversion: `True` or `False`
50 if isinstance(arg, bool):
52 if isinstance(arg, bytes):
53 arg = arg.decode('utf-8', errors='ignore')
54 if isinstance(arg, str):
55 if arg.lower() in ('yes', 'y', 'true', 't'):
57 if arg.lower() in ('no', 'n', 'false', 'f'):
59 raise ValueError('Not a boolean value')
65 Get current omniORB configuration.
67 The information is retrieved from the omniORB configuration file defined
68 by the OMNIORB_CONFIG environment variable.
69 If omniORB configuration file can not be accessed, a tuple of three empty
72 :return tuple of three strings: (orb_version, host_name, port_number)
77 with suppress(Exception), open(os.getenv('OMNIORB_CONFIG')) as forb:
78 regvar = re.compile(r'(ORB)?InitRef.*corbaname::(.*):(\d+)\s*$')
79 for line in forb.readlines():
80 match = regvar.match(line)
82 orb_version = '4' if match.group(1) is None else '3'
83 hostname = match.group(2)
84 port_number = match.group(3)
86 return orb_version, hostname, port_number
90 def getHostFromORBcfg():
92 Get current omniORB host name.
95 return getORBcfgInfo()[1]
99 def getPortFromORBcfg():
101 Get current omniORB port.
104 return getORBcfgInfo()[2]
112 The following procedure is perfomed to deduce user name:
113 1. try USER (USERNAME on Windows) environment variable.
114 2. if (1) fails, try LOGNAME (un*x only).
115 3. if (2) fails, return 'unknown' as default user name
119 return os.getenv('USERNAME', 'unknown') if sys.platform == 'win32' \
120 else os.getenv('USER', os.getenv('LOGNAME', 'unknown'))
128 The following procedure is perfomed to deduce host name:
129 1. try socket python module, gethostname() function
130 2. if (1) fails, try HOSTNAME environment variable
131 3. if (2) fails, try HOST environment variable
132 4. if (3) fails, tries 'unknown' as default host name
133 5. finally, checks that IP is configured for hostname; if not, returns 'localhost'
138 with suppress(Exception):
139 host = socket.gethostname()
141 host = os.getenv('HOSTNAME', os.getenv('HOST', 'unknown'))
143 # the following line just checks that IP is configured for hostname
144 socket.gethostbyname(host)
145 except (TypeError, OSError):
151 def getShortHostName():
153 Get short host name (with domain stripped).
154 See `getHostName()` for more details.
155 :return short host name
157 with suppress(AttributeError, IndexError):
158 return getHostName().split('.')[0]
159 return 'unknown' # default host name
165 Get application name.
166 The following procedure is perfomed to deduce application name:
167 1. try APPNAME environment variable
168 2. if (1) fails, return 'SALOME' as default application name
169 :return application name
171 return os.getenv('APPNAME', 'SALOME') # 'SALOME' is default user name
175 def getPortNumber(use_default=True):
177 Get currently used omniORB port.
178 The following procedure is perfomed to deduce port number:
179 1. try NSPORT environment variable
180 2. if (1) fails, try to parse config file defined by OMNIORB_CONFIG environment variable
181 3. if (2) fails, return 2809 as default port number (if use_default is `True`) or `None`
182 (if use_default is `False`)
185 with suppress(TypeError, ValueError):
186 return int(os.getenv('NSPORT'))
187 with suppress(TypeError, ValueError):
188 port = int(getPortFromORBcfg())
191 return 2809 if use_default else None
198 :return home directory path
200 return osp.realpath(osp.expanduser('~'))
206 Get directory that stores log files.
207 :return path to the log directory
209 return osp.join(getTmpDir(), 'logs', getUserName())
215 Get directory to store temporary files.
216 :return temporary directory path
218 with tempfile.NamedTemporaryFile() as tmp:
219 return osp.dirname(tmp.name)
224 # pragma pylint: disable=too-many-arguments
225 def generateFileName(path, prefix=None, suffix=None, extension=None,
226 unique=False, separator='_', hidden=False, **kwargs):
230 :param path : directory path
231 :param prefix : file name prefix (none by default)
232 :param suffix : file name suffix (none by default)
233 :param extension : file extension (none by default)
234 :param unique : if `True`, function generates unique file name -
235 in this case, if file with the generated name already
236 exists in `path` directory, an integer suffix is appended
237 to the file name (`False` by default)
238 :param separator : words separator ('_' by default)
239 :param hidden : if `True`, file name is prepended with dot symbol
241 :param kwargs : additional keywrods arguments (see below)
242 :return generated file name
244 Additionally supported keyword parameters:
245 - with_username : use user name:
246 - with_hostname : use host name:
247 - with_port : use port number:
248 - with_app : use application name:
250 Any of these keyword arguments can accept either explicit string value,
251 or `True` to automatically deduce value from current configuration.
256 _str = '' if _str is None else str(_str)
258 filename.append(_str)
260 def _with_kwarg(_kwarg, _func):
261 _value = kwargs.get(_kwarg, False)
263 if _try_bool(_value):
264 filename.append(str(_func()))
269 _with_kwarg('with_username', getUserName)
270 _with_kwarg('with_hostname', getShortHostName)
271 _with_kwarg('with_port', getPortNumber)
272 _with_kwarg('with_app', getAppName)
275 # raise an exception if file name is empty
277 raise ValueError('Empty file name')
280 extension = '' if extension is None else str(extension)
281 if extension.startswith('.'):
282 extension = extension[1:]
285 separator = '' if separator is None else str(separator)
287 def _generate(_index=None):
288 # join all components together, add index if necessary
289 if _index is not None:
290 _name = separator.join(filename+[str(_index)])
292 _name = separator.join(filename)
293 # prepend with dot if necessary
296 # append extension if ncessary
298 _name = _name + '.' + extension
300 return osp.join(path, _name)
305 while osp.exists(name):
307 name = _generate(index)
308 return osp.normpath(name)
314 Clear contents of directory.
315 :param path directory path
318 for filename in os.listdir(path):
319 file_path = osp.join(path, filename)
320 with suppress(OSError):
321 if osp.isdir(file_path):
322 shutil.rmtree(file_path)
328 def makeTmpDir(path, mode=0o777):
330 Make temporary directory with the specified path.
331 If the directory exists, clear all its contents.
332 :param path : directory path
333 :param mode : access mode
335 with suppress(OSError):
336 os.makedirs(path, mode=mode, exist_ok=True)
341 def uniteFiles(src_file, dest_file):
343 Join contents of `src_file` and `dest_file` and put result to `dest_file`.
344 File `dest_file` may not exist.
345 :param src_file : source file path
346 :param dest_file : destination file path
348 if not osp.exists(src_file):
351 if osp.exists(dest_file):
352 with suppress(OSError), open(src_file, 'rb') as src, open(dest_file, 'ab') as dest:
354 dest.write(src.read())
356 with suppress(OSError):
357 shutil.copy(src_file, dest_file)
363 Get current verbosity level.
365 Default verbosity level is specified via the environment variable SALOME_VERBOSE,
368 $ export SALOME_VERBOSE=1
370 The function `setVerbose()` can be used to explicitly set verbosity level.
372 :return current verbosity level
374 if not hasattr(verbose, 'verbosity_level'):
375 verbose.verbosity_level = 0 # default value
376 with suppress(TypeError, ValueError):
377 # from SALOME_VERBOSE environment variable
378 verbose.verbosity_level = int(os.getenv('SALOME_VERBOSE', '0'))
379 return verbose.verbosity_level
382 def setVerbose(level):
384 Change verbosity level.
385 The function `verbose()` can be used to get current verbosity level.
386 :param level : verbosity level
388 with suppress(TypeError, ValueError):
389 verbose.verbosity_level = int(level)
392 def killPid(pid, sig=9):
394 Send signal `sig` to the process with given `pid`.
396 :param pid : PID of the process
397 :param sig : signal to send; some of possible values:
399 - 0 : do nothing, just check process existence (see below)
400 NOTE: other values are not processed on Windows
401 :return result of execution:
403 - 0 : fail, no such process
404 - -1 : fail, another reason
409 with suppress(ValueError):
413 ret = 1 if psutil.pid_exists(pid) else 0
416 print("######## killPid pid = ", pid)
418 process = psutil.Process(pid)
420 _, alive = psutil.wait_procs([process], timeout=5)
424 except psutil.NoSuchProcess:
431 def getOmniNamesPid(port):
433 Get PID of omniNames process running on given `port`.
434 :param port : port number
435 :return omniNames process's PID
437 processes = {p.info['pid']: p.info['name'] for p in psutil.process_iter(['pid', 'name'])}
438 return next((c.pid for c in psutil.net_connections(kind='inet') \
439 if c.laddr.port == port and processes.get(c.pid) == 'omniNames'), None)
442 def killOmniNames(port):
444 Kill omniNames process running on given `port`.
445 :param port : port number
447 with suppress(Exception):
448 killPid(getOmniNamesPid(port))