Salome HOME
Remove use of mutable as default parameter value
[modules/kernel.git] / bin / salomeContextUtils.py.in
1 #! /usr/bin/env python
2
3 # Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21
22 import os
23 import sys
24 import glob
25 import subprocess
26 import re
27
28 """
29 Define a specific exception class to manage exceptions related to SalomeContext
30 """
31 class SalomeContextException(Exception):
32   """Report error messages to the user interface of SalomeContext."""
33 #
34
35 def __listDirectory(path):
36   allFiles = []
37   for root, dirs, files in os.walk(path):
38     cfgFiles = glob.glob(os.path.join(root,'*.cfg'))
39     allFiles += cfgFiles
40
41     shFiles = glob.glob(os.path.join(root,'*.sh'))
42     for f in shFiles:
43       no_ext = os.path.splitext(f)[0]
44       if not os.path.isfile(no_ext+".cfg"):
45         allFiles.append(f)
46
47   return allFiles
48 #
49
50 def __getConfigFileNamesDefault():
51   absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
52   if not absoluteAppliPath:
53     return []
54
55   envdDir = absoluteAppliPath + '/env.d'
56   if not os.path.isdir(envdDir):
57     return []
58
59   return __listDirectory(envdDir)
60 #
61
62 def getConfigFileNames(args, checkExistence=False):
63   # special case: configuration files are provided by user
64   # Search for command-line argument(s) --config=file1,file2,..., filen
65   # Search for command-line argument(s) --config=dir1,dir2,..., dirn
66   configOptionPrefix = "--config="
67   configArgs = [ str(x) for x in args if str(x).startswith(configOptionPrefix) ]
68
69   if len(configArgs) == 0:
70     return __getConfigFileNamesDefault(), args, []
71
72   args = [ x for x in args if not x.startswith(configOptionPrefix) ]
73   allLists = [ x.replace(configOptionPrefix, '') for x in configArgs ]
74
75   configFileNames = []
76   unexisting = []
77   for currentList in allLists:
78     elements = currentList.split(',')
79     for elt in elements:
80       elt = os.path.realpath(os.path.expanduser(elt))
81       if os.path.isdir(elt):
82         configFileNames += __listDirectory(elt)
83       else:
84         if checkExistence and not os.path.isfile(elt):
85           unexisting += [elt]
86         else:
87           configFileNames += [elt]
88
89   return configFileNames, args, unexisting
90 #
91
92 def __getScriptPath(scriptName, searchPathList):
93   if searchPathList is None or len(searchPathList) == 0:
94     return None
95
96   for path in searchPathList:
97     fullName = os.path.join(path, scriptName)
98     if os.path.isfile(fullName) or os.path.isfile(fullName+".py"):
99       return fullName
100
101   return None
102 #
103
104 # Return an array of dictionaries {script_name: [list_of_its_args]}
105 def getScriptsAndArgs(args=None, searchPathList=None):
106   if args is None:
107     args = []
108   if searchPathList is None:
109     searchPathList = sys.path
110
111   # Syntax of args: script.py [args:a1,a2=val,an] ... script.py [args:a1,a2=val,an]
112   scriptArgs = []
113   currentKey = None
114   argsPrefix = "args:"
115   callPython = False
116   currentScript = None
117
118   for i in range(len(args)):
119     elt = args[i]
120
121     if elt.startswith(argsPrefix):
122       if not currentKey or callPython:
123         raise SalomeContextException("args list must follow corresponding script file in command line.")
124       elt = elt.replace(argsPrefix, '')
125       scriptArgs[len(scriptArgs)-1][currentKey] = elt.split(",")
126       currentKey = None
127       callPython = False
128     elif elt.startswith("python"):
129       callPython = True
130     else:
131       if not os.path.isfile(elt) and not os.path.isfile(elt+".py"):
132         eltInSearchPath = __getScriptPath(elt, searchPathList)
133         if eltInSearchPath is None or (not os.path.isfile(eltInSearchPath) and not os.path.isfile(eltInSearchPath+".py")):
134           if elt[-3:] == ".py":
135             raise SalomeContextException("Script not found: %s"%elt)
136           continue
137         elt = eltInSearchPath
138
139       if elt[-4:] != ".hdf":
140         if elt[-3:] == ".py":
141           currentScript = os.path.abspath(elt)
142         elif os.path.isfile(elt+".py"):
143           currentScript = os.path.abspath(elt+".py")
144         else:
145           currentScript = os.path.abspath(elt) # python script not necessary has .py extension
146         pass
147       if currentScript and callPython:
148         currentKey = "@PYTHONBIN@ "+currentScript
149         scriptArgs.append({currentKey:[]})
150         callPython = False
151       elif currentScript:
152         if not os.access(currentScript, os.X_OK):
153           currentKey = "@PYTHONBIN@ "+currentScript
154           scriptArgs.append({currentKey:[]})
155         else:
156           ispython = False
157           try:
158             fn = open(currentScript)
159             for i in xrange(10): # read only 10 first lines
160               ln = fn.readline()
161               if re.search("#!.*python"):
162                 ispython = True
163                 break
164               pass
165             fn.close()
166           except:
167             pass
168           if not ispython and currentScript[-3:] == ".py":
169             currentKey = "@PYTHONBIN@ "+currentScript
170           else:
171             currentKey = currentScript
172             pass
173           scriptArgs.append({currentKey:[]})
174   # end for loop
175   return scriptArgs
176 #
177
178 # Formatting scripts and args as a Bash-like command-line:
179 # script1.py [args] ; script2.py [args] ; ...
180 def formatScriptsAndArgs(scriptArgs=None):
181     if scriptArgs is None:
182       scriptArgs = []
183     commands = []
184     for sc_dict in scriptArgs:
185       for script, sc_args in sc_dict.items(): # single entry
186         cmd = script
187         if sc_args:
188           cmd = cmd + " " + " ".join(sc_args)
189         commands.append(cmd)
190     sep = " ; "
191     if sys.platform == "win32":
192       sep= " & "
193     command = sep.join(["%s"%x for x in commands])
194     return command
195 #
196
197 # Ensure OMNIORB_USER_PATH is defined. This variable refers to a the folder in which
198 # SALOME will write omniOrb configuration files.
199 # If OMNIORB_USER_PATH is already set, only checks write access to associated directory ;
200 # an exception is raised if check fails. It allows users for choosing a specific folder.
201 # Else the function sets OMNIORB_USER_PATH this way:
202 # - If APPLI environment variable is set, OMNIORB_USER_PATH is set to ${APPLI}/USERS.
203 #   The function does not check USERS folder existence or write access. This folder
204 #   must exist ; this is the case if SALOME virtual application has been created using
205 #   appli_gen.py script.
206 # - Else OMNIORB_USER_PATH is set to user home directory.
207 def setOmniOrbUserPath():
208   omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
209   if omniorbUserPath:
210     if not os.access(omniorbUserPath, os.W_OK):
211       raise Exception("Unable to get write access to directory: %s"%omniorbUserPath)
212     pass
213   else:
214     homePath = os.path.realpath(os.path.expanduser('~'))
215     #defaultOmniorbUserPath = os.path.join(homePath, ".salomeConfig/USERS")
216     defaultOmniorbUserPath = homePath
217     if os.getenv("APPLI"):
218       defaultOmniorbUserPath = os.path.join(homePath, os.getenv("APPLI"), "USERS")
219       pass
220     os.environ["OMNIORB_USER_PATH"] = defaultOmniorbUserPath
221 #