+#! /usr/bin/env python3
# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
#
# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
-def __prompt(environment = None, commands=[], message = "Connecting to SALOME"):
+from optparse import OptionParser
+import os
+import sys
+import pickle
+
+# Use to display newlines (\n) in epilog
+class MyParser(OptionParser):
+ def format_epilog(self, formatter):
+ return self.epilog
+#
+
+def __parse_args(args):
+ if args is None:
+ args = []
+
+ usage = "Usage: salome connect [-p port] [ -c command | script | - ]"
+ epilog = """
+Connects a Python console to a local SALOME instance.\n
+If port is given, try to connect to corresponding instance.
+If port is not given, or does not correspond to a running instance,
+ask user to select a port from list of available SALOME instances.\n
+
+The -c option can be used to specify the command to execute in the interpreter.
+A script can also be used.
+For example:
+ salome connect -p 2810 -c 'print("Hello")'
+ salome connect -p 2810 hello.py
+"""
+ parser = MyParser(usage=usage, epilog=epilog)
+ parser.add_option("-p", metavar="<port>", default=0,
+ action="store", type="string", dest="port",
+ help="The port to connect to."
+ )
+ parser.add_option('-c', dest="command", default=None,
+ help="The command to execute in the interpreter."
+ )
+ try:
+ (options, args) = parser.parse_args(args)
+ except Exception as e:
+ print(e)
+ return {}, []
+
+ return options, args
+#
+
+def __show_running_instances(list_of_instances):
+ print('-'*10)
+ print("Running instances:")
+ for i in range(len(list_of_instances)):
+ host, port, _ = list_of_instances[i]
+ print(" [%d] %s:%s"%(i+1, host, port))
+ print('-'*10)
+#
+
+def __choose_in(choices):
+ __show_running_instances(choices)
+ rep = input("Please enter the number of instance to use (0 to cancel): ")
+ if rep == '0':
+ return None, None, None
+ elif rep in [str(i) for i in range(1, len(choices)+1)]:
+ return choices[int(rep)-1]
+ else:
+ print("*** Invalid number! ***")
+ return __choose_in(choices)
+#
+
+def __get_running_session(requested_port=None, lastInstanceByDefault=False):
+ import glob
+ import salome_utils
+ from ORBConfigFile import readORBConfigFile
+
+ omniorbUserPath = os.getenv("OMNIORB_USER_PATH")
+ files = glob.glob(os.path.join(omniorbUserPath,".omniORB_"+salome_utils.getUserName()+"_*[!last].cfg"))
+ available_connexions = []
+ for filename in files:
+ host, port = readORBConfigFile(filename)
+ available_connexions.append((host, port, filename))
+
+ host, port, filename = None, None, None
+ if requested_port:
+ print("Search for running instance on port %s..."%requested_port)
+ found = [(h,p,f) for h,p,f in available_connexions if int(p) == int(requested_port)]
+ if not found:
+ print(" ...no running instance found")
+ elif len(found) == 1:
+ host, port, filename = found[0]
+ print(" ...found unique instance: %s:%s"%(host,port))
+ else:
+ print(" ...multiple instances found ; please choose one in the following:")
+ host, port, filename = __choose_in(found)
+ else: # no requested port
+ if not available_connexions:
+ print("No running instance found")
+ elif len(available_connexions) == 1:
+ host, port, filename = available_connexions[0]
+ print("Found unique instance: %s:%s"%(host,port))
+ else:
+ print("Multiple instances found ; please choose one in the following:")
+ host, port, filename = __choose_in(available_connexions)
+ pass
+
+ if port:
+ print("Selected instance: %s:%s"%(host, port))
+ else:
+ print("Cancel.")
+
+ return host, port, filename
+#
+
+import CORBA
+import CosNaming
+import orbmodule
+
+class client(orbmodule.client):
+ def initNS(self,args):
+ # Obtain a reference to the root naming context
+ obj = self.orb.resolve_initial_references("NameService")
+ try:
+ self.rootContext = obj._narrow(CosNaming.NamingContext)
+ return
+ except (CORBA.TRANSIENT,CORBA.OBJECT_NOT_EXIST,CORBA.COMM_FAILURE):
+ print("It's not a valid naming service")
+ self.rootContext = None
+ sys.stdout.flush()
+ raise
+#
+
+def start_client():
+ try:
+ clt = client()
+ except Exception:
+ import traceback
+ traceback.print_exc()
+ sys.exit(1)
+ #
+
+ session_server = clt.Resolve('/Kernel/Session')
+ if session_server:
+ session = clt.waitNS("/Kernel/Session")
+ catalog = clt.waitNS("/Kernel/ModulCatalog")
+ study = clt.waitNS("/Study")
+
+ import salome
+ salome.salome_init()
+ from salome import lcc
+ print("--> now connected to SALOME")
+#
+
+def _prompt(environment=None, commands=None, message="Connecting to SALOME"):
if environment is None:
environment = globals().copy()
environment.update(locals())
+ if commands is None:
+ commands = []
import code
import rlcompleter
import readline
+ readline.set_completer(rlcompleter.Completer(environment).complete)
readline.parse_and_bind("tab: complete")
# calling this with globals ensures we can see the environment
- print message
+ print(message)
shell = code.InteractiveConsole(environment)
for cmd in commands:
+ print("Execute command:", cmd)
shell.push(cmd)
- return shell.interact
+ pass
+ shell.interact()
+#
+
+def connect(args=None, env=None):
+ if env is not None:
+ os.environ = env
+ options, args = __parse_args(args)
+ host, port, filename = __get_running_session(options.port)
+ if not port:
+ return 1
+
+ cmd = [
+ "os.environ['OMNIORB_CONFIG'] = '%s'"%filename,
+ "start_client()"
+ ]
+ if options.command:
+ cmd.append(options.command)
+ if args: # unprocessed: may be scripts
+ for arg in args:
+ filename = os.path.abspath(os.path.expanduser(arg))
+ pythonLine = "exec(compile(open(%s, \"rb\").read(), %s, 'exec'))"%(filename, filename)
+ cmd.append(pythonLine)
+
+ if port:
+ import subprocess
+ absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
+ env_copy = os.environ.copy()
+ cmdDump = pickle.dumps(cmd, protocol=0)
+ cmdString = cmdDump.decode()
+ proc = subprocess.Popen(['python3', os.path.join(absoluteAppliPath,"bin","salome","runConsole.py"), cmdString], shell=False, close_fds=True, env=env_copy)
+ proc.communicate()
+ return proc.returncode
#
-def connect(args=[]):
- p = __prompt(commands=["import salomeConsole"])
- p()
+if __name__ == "__main__":
+ if len(sys.argv) == 2:
+ cmdBytes = sys.argv[1].encode()
+ cmd = pickle.loads(cmdBytes)
+ sys.argv = []
+ _prompt(commands=cmd)
+ else:
+ print("runConsole.py: incorrect usage!")
#