3 # Copyright (C) 2013-2014 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
31 Define a specific exception class to manage exceptions related to SalomeContext
33 class SalomeContextException(Exception):
34 """Report error messages to the user interface of SalomeContext."""
37 def __listDirectory(path):
39 for root, dirs, files in os.walk(path):
40 cfgFiles = glob.glob(os.path.join(root,'*.cfg'))
43 shFiles = glob.glob(os.path.join(root,'*.sh'))
45 no_ext = os.path.splitext(f)[0]
46 if not os.path.isfile(no_ext+".cfg"):
52 def __getConfigFileNamesDefault():
53 absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
54 if not absoluteAppliPath:
57 envdDir = absoluteAppliPath + '/env.d'
58 if not os.path.isdir(envdDir):
61 return __listDirectory(envdDir)
64 def getConfigFileNames(args, checkExistence=False):
65 # special case: configuration files are provided by user
66 # Search for command-line argument(s) --config=file1,file2,..., filen
67 # Search for command-line argument(s) --config=dir1,dir2,..., dirn
68 configOptionPrefix = "--config="
69 configArgs = [ str(x) for x in args if str(x).startswith(configOptionPrefix) ]
71 if len(configArgs) == 0:
72 return __getConfigFileNamesDefault(), args, []
74 args = [ x for x in args if not x.startswith(configOptionPrefix) ]
75 allLists = [ x.replace(configOptionPrefix, '') for x in configArgs ]
79 for currentList in allLists:
80 elements = currentList.split(',')
82 elt = os.path.realpath(os.path.expanduser(elt))
83 if os.path.isdir(elt):
84 configFileNames += __listDirectory(elt)
86 if checkExistence and not os.path.isfile(elt):
89 configFileNames += [elt]
91 return configFileNames, args, unexisting
94 def __getScriptPath(scriptName, searchPathList):
95 scriptName = os.path.expanduser(scriptName)
96 if os.path.isabs(scriptName):
99 if searchPathList is None or len(searchPathList) == 0:
102 for path in searchPathList:
103 fullName = os.path.join(path, scriptName)
104 if os.path.isfile(fullName) or os.path.isfile(fullName+".py"):
111 # script: the command to be run, e.g. python <script.py>
112 # args: its input parameters
113 # out: its output parameters
114 def __init__(self, script = None, args = None, out = None):
120 msg = "\n# Script: %s\n"%self.script
121 msg += " * Input: %s\n"%self.args
122 msg += " * Output: %s\n"%self.out
126 class ScriptAndArgsObjectEncoder(json.JSONEncoder):
127 def default(self, obj):
128 if isinstance(obj, ScriptAndArgs):
129 # to be easily parsed in GUI module (SalomeApp_Application)
130 # Do not export output arguments
131 return {obj.script:obj.args or []}
133 return json.JSONEncoder.default(self, obj)
136 # Return an array of ScriptAndArgs objects
137 def getScriptsAndArgs(args=None, searchPathList=None):
140 if searchPathList is None:
141 searchPathList = sys.path
143 # Syntax of args: script.py [args:a1,a2=val,an] ... script.py [args:a1,a2=val,an]
152 for i in range(len(args)):
153 elt = os.path.expanduser(args[i])
154 isDriver = (elt == "driver") # special case for YACS scheme execution
156 if elt.startswith(argsPrefix):
157 if not currentKey or callPython:
158 raise SalomeContextException("args list must follow corresponding script file in command line.")
159 elt = elt.replace(argsPrefix, '')
160 scriptArgs[len(scriptArgs)-1].args = [os.path.expanduser(x) for x in elt.split(",")]
164 elif elt.startswith(outPrefix):
165 if (not currentKey and not afterArgs) or callPython:
166 raise SalomeContextException("out list must follow both corresponding script file and its args in command line.")
167 elt = elt.replace(outPrefix, '')
168 scriptArgs[len(scriptArgs)-1].out = [os.path.expanduser(x) for x in elt.split(",")]
172 elif elt.startswith("python"):
176 if not os.path.isfile(elt) and not os.path.isfile(elt+".py"):
177 eltInSearchPath = __getScriptPath(elt, searchPathList)
178 if eltInSearchPath is None or (not os.path.isfile(eltInSearchPath) and not os.path.isfile(eltInSearchPath+".py")):
179 if elt[-3:] == ".py":
180 raise SalomeContextException("Script not found: %s"%elt)
182 elt = eltInSearchPath
184 if elt[-4:] != ".hdf":
185 if elt[-3:] == ".py" or isDriver:
186 currentScript = os.path.abspath(elt)
187 elif os.path.isfile(elt+".py"):
188 currentScript = os.path.abspath(elt+".py")
190 currentScript = os.path.abspath(elt) # python script not necessary has .py extension
193 if currentScript and callPython:
194 currentKey = "@PYTHONBIN@ "+currentScript
195 scriptArgs.append(ScriptAndArgs(script=currentKey))
199 currentKey = currentScript
200 scriptArgs.append(ScriptAndArgs(script=currentKey))
202 elif not os.access(currentScript, os.X_OK):
203 currentKey = "@PYTHONBIN@ "+currentScript
204 scriptArgs.append(ScriptAndArgs(script=currentKey))
208 fn = open(currentScript)
209 for i in xrange(10): # read only 10 first lines
211 if re.search("#!.*python"):
218 if not ispython and currentScript[-3:] == ".py":
219 currentKey = "@PYTHONBIN@ "+currentScript
221 currentKey = currentScript
223 scriptArgs.append(ScriptAndArgs(script=currentKey))
224 # CLOSE elif currentScript
230 # Formatting scripts and args as a Bash-like command-line:
231 # script1.py [args] ; script2.py [args] ; ...
232 # scriptArgs is a list of ScriptAndArgs objects; their output parameters are omitted
233 def formatScriptsAndArgs(scriptArgs=None):
234 if scriptArgs is None:
237 for sa_obj in scriptArgs:
240 cmd = " ".join([cmd]+sa_obj.args)
244 if sys.platform == "win32":
246 command = sep.join(["%s"%x for x in commands])
250 # Ensure OMNIORB_USER_PATH is defined. This variable refers to a the folder in which
251 # SALOME will write omniOrb configuration files.
252 # If OMNIORB_USER_PATH is already set, only checks write access to associated directory ;
253 # an exception is raised if check fails. It allows users for choosing a specific folder.
254 # Else the function sets OMNIORB_USER_PATH this way:
255 # - If APPLI environment variable is set, OMNIORB_USER_PATH is set to ${APPLI}/USERS.
256 # The function does not check USERS folder existence or write access. This folder
257 # must exist ; this is the case if SALOME virtual application has been created using
258 # appli_gen.py script.
259 # - Else OMNIORB_USER_PATH is set to user home directory.
260 def setOmniOrbUserPath():
261 omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
263 if not os.access(omniorbUserPath, os.W_OK):
264 raise Exception("Unable to get write access to directory: %s"%omniorbUserPath)
267 homePath = os.path.realpath(os.path.expanduser('~'))
268 #defaultOmniorbUserPath = os.path.join(homePath, ".salomeConfig/USERS")
269 defaultOmniorbUserPath = homePath
270 if os.getenv("APPLI"):
271 defaultOmniorbUserPath = os.path.join(homePath, os.getenv("APPLI"), "USERS")
273 os.environ["OMNIORB_USER_PATH"] = defaultOmniorbUserPath
277 return socket.gethostname().split('.')[0]