Salome HOME
Prise en compte de la variable SALOME_OPTIONS
[modules/kernel.git] / bin / runConsole.py
1 #! /usr/bin/env python3
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
4 #
5 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 #
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21 #
22 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #
24
25 from optparse import OptionParser
26 import os
27 import sys
28 import pickle
29
30 # Use to display newlines (\n) in epilog
31 class MyParser(OptionParser):
32   def format_epilog(self, formatter):
33     return self.epilog
34 #
35
36 def __parse_args(args):
37   if args is None:
38     args = []
39
40   usage = "Usage: salome connect [-p port] [ -c command | script | - ]"
41   epilog  = """
42 Connects a Python console to a local SALOME instance.\n
43 If port is given, try to connect to corresponding instance.
44 If port is not given, or does not correspond to a running instance,
45 ask user to select a port from list of available SALOME instances.\n
46
47 The -c option can be used to specify the command to execute in the interpreter.
48 A script can also be used.
49 For example:
50        salome connect -p 2810 -c 'print("Hello")'
51        salome connect -p 2810 hello.py
52 """
53   parser = MyParser(usage=usage, epilog=epilog)
54   parser.add_option("-p", metavar="<port>", default=0,
55                     action="store", type="string", dest="port",
56                     help="The port to connect to."
57                     )
58   parser.add_option('-c', dest="command", default=None,
59                     help="The command to execute in the interpreter."
60                     )
61   try:
62     (options, args) = parser.parse_args(args)
63   except Exception as e:
64     print(e)
65     return {}, []
66
67   return options, args
68 #
69
70 def __show_running_instances(list_of_instances):
71   print('-'*10)
72   print("Running instances:")
73   for i in range(len(list_of_instances)):
74     host, port, _ = list_of_instances[i]
75     print("   [%d] %s:%s"%(i+1, host, port))
76   print('-'*10)
77 #
78
79 def __choose_in(choices):
80   __show_running_instances(choices)
81   rep = input("Please enter the number of instance to use (0 to cancel): ")
82   if rep == '0':
83     return None, None, None
84   elif rep in [str(i) for i in range(1, len(choices)+1)]:
85     return choices[int(rep)-1]
86   else:
87     print("*** Invalid number! ***")
88     return __choose_in(choices)
89 #
90
91 def __get_running_session(requested_port=None, lastInstanceByDefault=False):
92   import glob
93   import salome_utils
94   from ORBConfigFile import readORBConfigFile
95
96   omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
97   files = glob.glob(os.path.join(omniorbUserPath,".omniORB_"+salome_utils.getUserName()+"_*[!last].cfg"))
98   available_connexions = []
99   for filename in files:
100     host, port = readORBConfigFile(filename)
101     available_connexions.append((host, port, filename))
102
103   host, port, filename = None, None, None
104   if requested_port:
105     print("Search for running instance on port %s..."%requested_port)
106     found = [(h,p,f) for h,p,f in available_connexions if int(p) == int(requested_port)]
107     if not found:
108       print("   ...no running instance found")
109     elif len(found) == 1:
110       host, port, filename = found[0]
111       print("   ...found unique instance: %s:%s"%(host,port))
112     else:
113       print("   ...multiple instances found ; please choose one in the following:")
114       host, port, filename = __choose_in(found)
115   else: # no requested port
116     if not available_connexions:
117       print("No running instance found")
118     elif len(available_connexions) == 1:
119       host, port, filename = available_connexions[0]
120       print("Found unique instance: %s:%s"%(host,port))
121     else:
122       print("Multiple instances found ; please choose one in the following:")
123       host, port, filename = __choose_in(available_connexions)
124       pass
125
126   if port:
127     print("Selected instance: %s:%s"%(host, port))
128   else:
129     print("Cancel.")
130
131   return host, port, filename
132 #
133
134 import CORBA
135 import CosNaming
136 import orbmodule
137
138 class client(orbmodule.client):
139   def initNS(self,args):
140     # Obtain a reference to the root naming context
141     obj = self.orb.resolve_initial_references("NameService")
142     try:
143       self.rootContext = obj._narrow(CosNaming.NamingContext)
144       return
145     except (CORBA.TRANSIENT,CORBA.OBJECT_NOT_EXIST,CORBA.COMM_FAILURE):
146       print("It's not a valid naming service")
147       self.rootContext = None
148       sys.stdout.flush()
149       raise
150 #
151
152 def start_client():
153   try:
154     clt = client()
155   except Exception:
156     import traceback
157     traceback.print_exc()
158     sys.exit(1)
159   #
160
161   session_server = clt.Resolve('/Kernel/Session')
162   if session_server:
163     session = clt.waitNS("/Kernel/Session")
164   catalog = clt.waitNS("/Kernel/ModulCatalog")
165   study = clt.waitNS("/Study")
166
167   import salome
168   salome.salome_init()
169   from salome import lcc
170   print("--> now connected to SALOME")
171 #
172
173 def _prompt(environment=None, commands=None, message="Connecting to SALOME"):
174   if environment is None:
175     environment = globals().copy()
176     environment.update(locals())
177   if commands is None:
178     commands = []
179
180   import code
181   import rlcompleter
182   import readline
183   readline.set_completer(rlcompleter.Completer(environment).complete)
184   readline.parse_and_bind("tab: complete")
185   # calling this with globals ensures we can see the environment
186   print(message)
187   shell = code.InteractiveConsole(environment)
188   for cmd in commands:
189     print("Execute command:", cmd)
190     shell.push(cmd)
191     pass
192   shell.interact()
193 #
194
195 def connect(args=None, env=None):
196   if env is not None:
197     os.environ = env
198   options, args = __parse_args(args)
199   host, port, filename = __get_running_session(options.port)
200   if not port:
201     return 1
202
203   cmd = [
204     "os.environ['OMNIORB_CONFIG'] = '%s'"%filename,
205     "start_client()"
206     ]
207   if options.command:
208     cmd.append(options.command)
209   if args: # unprocessed: may be scripts
210     for arg in args:
211       filename = os.path.abspath(os.path.expanduser(arg))
212       pythonLine = "exec(compile(open(%s, \"rb\").read(), %s, 'exec'))"%(filename, filename)
213       cmd.append(pythonLine)
214
215   if port:
216     import subprocess
217     absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
218     env_copy = os.environ.copy()
219     cmdDump = pickle.dumps(cmd, protocol=0)
220     cmdString = cmdDump.decode()
221     proc = subprocess.Popen(['python3', os.path.join(absoluteAppliPath,"bin","salome","runConsole.py"), cmdString], shell=False, close_fds=True, env=env_copy)
222     proc.communicate()
223     return proc.returncode
224 #
225
226 if __name__ == "__main__":
227   if len(sys.argv) == 2:
228     cmdBytes = sys.argv[1].encode()  
229     cmd = pickle.loads(cmdBytes)
230     sys.argv = []
231     _prompt(commands=cmd)
232   else:
233     print("runConsole.py: incorrect usage!")
234 #