]> SALOME platform Git repositories - modules/kernel.git/blob - bin/salomeContext.py
Salome HOME
SSL mode by default mode
[modules/kernel.git] / bin / salomeContext.py
1 #! /usr/bin/env python3
2 # Copyright (C) 2013-2021  CEA/DEN, EDF R&D, OPEN CASCADE
3 #
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.
8 #
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.
13 #
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
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 import os
22 import sys
23 import logging
24 import configparser
25
26 from parseConfigFile import parseConfigFile
27
28 import tempfile
29 import pickle
30 import subprocess
31 import sys
32 import platform
33
34 from salomeContextUtils import SalomeContextException
35 from addToKillList import killList
36
37 def usage():
38   msg = '''\
39 Usage: salome [command] [options] [--config=<file,folder,...>]
40
41 Commands:
42 =========
43     start           Start a new SALOME instance. Start a single SALOME_Session_Server_No_Server
44                     process with environment relevant to the application and hosting all servants in it.
45     context         Initialize SALOME context. Current environment is extended.
46     shell           Initialize SALOME context, attached to the last created SALOME
47                     instance if any, and executes scripts passed as command arguments.
48                     User works in a Shell terminal. SALOME environment is set but
49                     application is not started.
50     test            Run SALOME tests.
51     info            Display some information about SALOME.
52     doc <module(s)> Show online module documentation (if available).
53                     Module names must be separated by blank characters.
54     help            Show this message.
55     remote          run command in SALOME environment from remote call, ssh or rsh.
56     withsession     Start a new SWS SALOME instance with multiple servers hosting all servants.
57     connect         In SWS context, Connect a Python console to the active SALOME instance.
58     kill <port(s)>  In SWS context, Terminate SALOME instances running on given ports for current user.
59                     Port numbers must be separated by blank characters.
60     killall         Terminate *all* SALOME running SWS instances for current user.
61                     Do not start a new one.
62
63 If no command is given, default is start.
64
65 Command options:
66 ================
67     Use salome <command> --help to show help on command. Available for the
68     following commands: start, shell, connect, test, info.
69
70 --config=<file,folder,...>
71 ==========================
72     Initialize SALOME context from a list of context files and/or a list
73     of folders containing context files. The list is comma-separated, without
74     any blank characters.
75 '''
76
77   print(msg)
78 #
79
80 """
81 The SalomeContext class in an API to configure SALOME context then
82 start SALOME using a single python command.
83
84 """
85 class SalomeContext:
86   """
87   Initialize context from a list of configuration files
88   identified by their names.
89   These files should be in appropriate .cfg format.
90   """
91   def __init__(self, configFileNames=0):
92     self.getLogger().setLevel(logging.INFO)
93     #it could be None explicitly (if user use multiples setVariable...for standalone)
94     if configFileNames is None:
95        return
96     configFileNames = configFileNames or []
97     if len(configFileNames) == 0:
98       raise SalomeContextException("No configuration files given")
99
100     reserved=['PATH', 'DYLD_FALLBACK_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'MANPATH', 'PV_PLUGIN_PATH', 'INCLUDE', 'LIBPATH', 'SALOME_PLUGINS_PATH', 'LIBRARY_PATH', 'QT_PLUGIN_PATH']
101     for filename in configFileNames:
102       basename, extension = os.path.splitext(filename)
103       if extension == ".cfg":
104         self.__setContextFromConfigFile(filename, reserved)
105       else:
106         self.getLogger().error("Unrecognized extension for configuration file: %s", filename)
107   #
108
109   def __loadEnvModules(self, env_modules):
110     modulecmd = os.getenv('LMOD_CMD')
111     if not modulecmd:
112       raise SalomeContextException("Module environment not present")
113       return
114     try:
115       out, err = subprocess.Popen([modulecmd, "python", "load"] + env_modules, stdout=subprocess.PIPE).communicate()
116       exec(out)  # define specific environment variables
117     except Exception:
118       raise SalomeContextException("Failed to load env modules: %s ..." % ' '.join(env_modules))
119       pass
120   #
121
122   def runSalome(self, args):
123     import os
124     # Run this module as a script, in order to use appropriate Python interpreter
125     # according to current path (initialized from context files).
126     env_modules_option = "--with-env-modules="
127     env_modules_l = [x for x in args if x.startswith(env_modules_option)]
128     if env_modules_l:
129       env_modules = env_modules_l[-1][len(env_modules_option):].split(',')
130       self.__loadEnvModules(env_modules)
131       args = [x for x in args if not x.startswith(env_modules_option)]
132     else:
133       env_modules = os.getenv("SALOME_ENV_MODULES", None)
134       if env_modules:
135         self.__loadEnvModules(env_modules.split(','))
136
137     absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
138     env_copy = os.environ.copy()
139     selfBytes= pickle.dumps(self, protocol=0)
140     argsBytes= pickle.dumps(args, protocol=0)
141     proc = subprocess.Popen(['python3', os.path.join(absoluteAppliPath,"bin","salome","salomeContext.py"), selfBytes.decode('latin1'), argsBytes.decode('latin1')], shell=False, close_fds=True, env=env_copy)
142     out, err = proc.communicate()
143     return out, err, proc.returncode
144   #
145
146   """Append value to PATH environment variable"""
147   def addToPath(self, value):
148     self.addToVariable('PATH', value)
149   #
150
151   """Append value to LD_LIBRARY_PATH environment variable"""
152   def addToLdLibraryPath(self, value):
153     if sys.platform == 'win32':
154       self.addToVariable('PATH', value)
155     elif  sys.platform == 'darwin':
156       if "LAPACK" in value:
157         self.addToVariable('DYLD_FALLBACK_LIBRARY_PATH', value)
158       else:
159         self.addToVariable('DYLD_LIBRARY_PATH', value)
160     else:
161       self.addToVariable('LD_LIBRARY_PATH', value)
162   #
163
164   """Append value to DYLD_LIBRARY_PATH environment variable"""
165   def addToDyldLibraryPath(self, value):
166     self.addToVariable('DYLD_LIBRARY_PATH', value)
167   #
168
169   """Append value to PYTHONPATH environment variable"""
170   def addToPythonPath(self, value):
171     self.addToVariable('PYTHONPATH', value)
172   #
173
174   """Set environment variable to value"""
175   def setVariable(self, name, value, overwrite=False):
176     env = os.getenv(name, '')
177     if env and not overwrite:
178       self.getLogger().error("Environment variable already existing (and not overwritten): %s=%s", name, value)
179       return
180
181     if env:
182       self.getLogger().debug("Overwriting environment variable: %s=%s", name, value)
183
184     value = os.path.expandvars(value) # expand environment variables
185     self.getLogger().debug("Set environment variable: %s=%s", name, value)
186     os.environ[name] = value
187   #
188
189   def setDefaultValue(self, name, value):
190     """ Set environment variable only if it is undefined."""
191     env = os.getenv(name, '')
192     if not env:
193       value = os.path.expandvars(value) # expand environment variables
194       self.getLogger().debug("Set environment variable: %s=%s", name, value)
195       os.environ[name] = value
196
197   """Unset environment variable"""
198   def unsetVariable(self, name):
199     if os.environ.has_key(name):
200       del os.environ[name]
201   #
202
203   """Append value to environment variable"""
204   def addToVariable(self, name, value, separator=os.pathsep):
205     if value == '':
206       return
207
208     value = os.path.expandvars(value) # expand environment variables
209     self.getLogger().debug("Add to %s: %s", name, value)
210     env = os.getenv(name, None)
211     if env is None:
212       os.environ[name] = value
213     else:
214       os.environ[name] = value + separator + env
215   #
216
217   ###################################
218   # This begins the private section #
219   ###################################
220
221   def __parseArguments(self, args):
222     if len(args) == 0 or args[0].startswith("-"):
223       return None, args
224
225     command = args[0]
226     options = args[1:]
227
228     availableCommands = {
229       'start'   : '_sessionless',
230       'withsession' : '_runAppli',
231       'context' : '_setContext',
232       'shell'   : '_runSession',
233       'remote'  : '_runRemote',
234       'connect' : '_runConsole',
235       'kill'    : '_kill',
236       'killall' : '_killAll',
237       'test'    : '_runTests',
238       'info'    : '_showInfo',
239       'doc'     : '_showDoc',
240       'help'    : '_usage',
241       'coffee'  : '_makeCoffee',
242       'car'     : '_getCar',
243       }
244
245     if command not in availableCommands:
246       command = "start"
247       options = args
248
249     return availableCommands[command], options
250   #
251
252   """
253   Run SALOME!
254   Args consist in a mandatory command followed by optional parameters.
255   See usage for details on commands.
256   """
257   def _startSalome(self, args):
258     import os
259     import sys
260     try:
261       from setenv import add_path
262       absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH')
263       path = os.path.realpath(os.path.join(absoluteAppliPath, "bin", "salome"))
264       add_path(path, "PYTHONPATH")
265       path = os.path.realpath(os.path.join(absoluteAppliPath, "bin", "salome", "appliskel"))
266       add_path(path, "PYTHONPATH")
267
268     except Exception:
269       pass
270
271     command, options = self.__parseArguments(args)
272     sys.argv = options
273
274     if command is None:
275       if args and args[0] in ["-h","--help","help"]:
276         usage()
277         return 0
278       # try to default to "start" command
279       command = "_sessionless"
280
281     try:
282       res = getattr(self, command)(options) # run appropriate method
283       return res or 0
284     except SystemExit as ex:
285       if ex.code != 0:
286         self.getLogger().error("SystemExit %s in method %s.", ex.code, command)
287       return ex.code
288     except SalomeContextException as e:
289       self.getLogger().error(e)
290       return 1
291     except Exception:
292       self.getLogger().error("Unexpected error:")
293       import traceback
294       traceback.print_exc()
295       return 1
296   #
297
298   def __setContextFromConfigFile(self, filename, reserved=None):
299     mesa_root_dir = "MESA_ROOT_DIR"
300     if reserved is None:
301       reserved = []
302     try:
303       configInfo = parseConfigFile(filename, reserved)
304       unsetVars = configInfo.unsetVariables
305       configVars = configInfo.outputVariables
306       reservedDict = configInfo.reservedValues
307       defaultValues = configInfo.defaultValues
308     except SalomeContextException as e:
309       msg = "%s"%e
310       self.getLogger().error(msg)
311       return 1
312
313     # unset variables
314     for var in unsetVars:
315       self.unsetVariable(var)
316
317     # mesa stuff
318     if "MESA_GL_VERSION_OVERRIDE" in os.environ:
319       configVarsDict = {k:v for (k,v) in configVars}
320       if mesa_root_dir in configVarsDict:
321         path_to_mesa_lib = os.path.join(configVarsDict[mesa_root_dir],"lib")
322         if os.name == "posix":
323           self.addToVariable("LD_LIBRARY_PATH",path_to_mesa_lib)
324         else:
325           self.addToVariable("PATH",path_to_mesa_lib)
326
327     # set context
328     for reserved in reservedDict:
329       a = [_f for _f in reservedDict[reserved] if _f] # remove empty elements
330       a = [ os.path.realpath(x) for x in a ]
331       reformattedVals = os.pathsep.join(a)
332       if reserved in ["INCLUDE", "LIBPATH"]:
333         self.addToVariable(reserved, reformattedVals, separator=' ')
334       else:
335         self.addToVariable(reserved, reformattedVals)
336       pass
337
338
339     for key,val in configVars:
340       self.setVariable(key, val, overwrite=True)
341       pass
342
343     for key,val in defaultValues:
344       self.setDefaultValue(key, val)
345       pass
346
347     pythonpath = os.getenv('PYTHONPATH','').split(os.pathsep)
348     pythonpath = [ os.path.realpath(x) for x in pythonpath ]
349     sys.path[:0] = pythonpath
350   #
351
352   def _runAppli(self, args=None):
353     if args is None:
354       args = []
355     # Initialize SALOME environment
356     sys.argv = ['runSalomeOld'] + args
357     import setenv
358     setenv.main(True, exeName="salome withsession")
359
360     import runSalomeOld
361     runSalomeOld.runSalome()
362     return 0
363   #
364
365   def _sessionless(self, args=None):
366     if args is None:
367       args = []
368     sys.argv = ['runSalome'] + args
369     import runSalomeNoServer
370     runSalomeNoServer.main()
371   #
372
373   def _setContext(self, args=None):
374     salome_context_set = os.getenv("SALOME_CONTEXT_SET")
375     if salome_context_set:
376       print("***")
377       print("*** SALOME context has already been set.")
378       print("*** Enter 'exit' (only once!) to leave SALOME context.")
379       print("***")
380       return 0
381
382     os.environ["SALOME_CONTEXT_SET"] = "yes"
383     print("***")
384     print("*** SALOME context is now set.")
385     print("*** Enter 'exit' (only once!) to leave SALOME context.")
386     print("***")
387
388     if sys.platform == 'win32':
389       cmd = ['cmd.exe']
390     else:
391       cmd = ["/bin/bash"]
392     proc = subprocess.Popen(cmd, shell=False, close_fds=True)
393     proc.communicate()
394     return proc.returncode
395   #
396
397   def _runSession(self, args=None):
398     if args is None:
399       args = []
400     sys.argv = ['runSession'] + args
401     import runSession
402     params, args = runSession.configureSession(args, exe="salome shell")
403
404     sys.argv = ['runSession'] + args
405     import setenv
406     setenv.main(True)
407
408     return runSession.runSession(params, args)
409   #
410
411   def _runRemote(self, args=None):
412     if args is None:
413       args = []
414 #   complete salome environment 
415     sys.argv = ['runRemote']
416     import setenv
417     setenv.main(True)
418
419     import runRemote
420     return runRemote.runRemote(args)
421   #
422
423   def _runConsole(self, args=None):
424     if args is None:
425       args = []
426     # Initialize SALOME environment
427     sys.argv = ['runConsole']
428     import setenv
429     setenv.main(True)
430
431     import runConsole
432     return runConsole.connect(args)
433   #
434
435   def _kill(self, args=None):
436     if args is None:
437       args = []
438     ports = args
439     if not ports:
440       print("Port number(s) not provided to command: salome kill <port(s)>")
441       return 1
442
443     import subprocess
444     sys.argv = ['kill']
445     import setenv
446     setenv.main(True)
447     if os.getenv("NSHOST") == "no_host":
448       os.unsetenv("NSHOST")
449     for port in ports:
450       if sys.platform == "win32":
451         proc = subprocess.Popen([os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", str(port)])
452       else:
453         proc = subprocess.Popen(["killSalomeWithPort.py", str(port)])
454       proc.communicate()
455     return 0
456   #
457
458   def _killAll(self, unused=None):
459     sys.argv = ['killAll']
460     import setenv
461     setenv.main(True)
462     if os.getenv("NSHOST") == "no_host":
463       os.unsetenv("NSHOST")
464     try:
465       import PortManager # mandatory
466       import subprocess
467       ports = PortManager.getBusyPorts()['this']
468
469       if ports:
470         for port in ports:
471           if sys.platform == "win32":
472             proc = subprocess.Popen([os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", str(port)])
473           else:
474             proc = subprocess.Popen(["killSalomeWithPort.py", str(port)])
475           proc.communicate()
476     except ImportError:
477       # :TODO: should be declared obsolete
478       from killSalome import killAllPorts
479       killAllPorts()
480       pass
481     killList()
482     return 0
483   #
484
485   def _runTests(self, args=None):
486     if args is None:
487       args = []
488     sys.argv = ['runTests']
489     import setenv
490     setenv.main(True)
491
492     import runTests
493     return runTests.runTests(args, exe="salome test")
494   #
495
496   def _showSoftwareVersions(self, softwares=None):
497     config = configparser.SafeConfigParser()
498     absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH')
499     filename = os.path.join(absoluteAppliPath, "sha1_collections.txt")
500     versions = {}
501     max_len = 0
502     with open(filename) as f:
503       for line in f:
504         try:
505           software, version, sha1 = line.split()
506           versions[software.upper()] = version
507           if len(software) > max_len:
508             max_len = len(software)
509         except Exception:
510           pass
511         pass
512       pass
513     if softwares:
514       for soft in softwares:
515         if soft.upper() in versions:
516           print(soft.upper().rjust(max_len), versions[soft.upper()])
517     else:
518       import collections
519       od = collections.OrderedDict(sorted(versions.items()))
520       for name, version in od.items():
521         print(name.rjust(max_len), versions[name])
522     pass
523
524   def _showInfo(self, args=None):
525     if args is None:
526       args = []
527
528     usage = "Usage: salome info [options]"
529     epilog  = """\n
530 Display some information about SALOME.\n
531 Available options are:
532     -p,--ports                     Show the list of busy ports (running SALOME instances).
533     -s,--softwares [software(s)]   Show the list and versions of SALOME softwares.
534                                    Software names must be separated by blank characters.
535                                    If no software is given, show version of all softwares.
536     -v,--version                   Show running SALOME version.
537     -h,--help                      Show this message.
538 """
539     if not args:
540       args = ["--version"]
541
542     if "-h" in args or "--help" in args:
543       print(usage + epilog)
544       return 0
545
546     if "-p" in args or "--ports" in args:
547       import PortManager
548       ports = PortManager.getBusyPorts()
549       this_ports = ports['this']
550       other_ports = ports['other']
551       if this_ports or other_ports:
552           print("SALOME instances are running on the following ports:")
553           if this_ports:
554               print("   This application:", this_ports)
555           else:
556               print("   No SALOME instances of this application")
557           if other_ports:
558               print("   Other applications:", other_ports)
559           else:
560               print("   No SALOME instances of other applications")
561       else:
562           print("No SALOME instances are running")
563
564     if "-s" in args or "--softwares" in args:
565       if "-s" in args:
566         index = args.index("-s")
567       else:
568         index = args.index("--softwares")
569       indexEnd=index+1
570       while indexEnd < len(args) and args[indexEnd][0] != "-":
571         indexEnd = indexEnd + 1
572       self._showSoftwareVersions(softwares=args[index+1:indexEnd])
573
574     if "-v" in args or "--version" in args:
575       print("Running with python", platform.python_version())
576       return self._sessionless(["--version"])
577
578     return 0
579   #
580
581   def _showDoc(self, args=None):
582     if args is None:
583       args = []
584
585     modules = args
586     if not modules:
587       print("Module(s) not provided to command: salome doc <module(s)>")
588       return 1
589
590     appliPath = os.getenv("ABSOLUTE_APPLI_PATH")
591     if not appliPath:
592       raise SalomeContextException("Unable to find application path. Please check that the variable ABSOLUTE_APPLI_PATH is set.")
593     baseDir = os.path.join(appliPath, "share", "doc", "salome")
594     for module in modules:
595       docfile = os.path.join(baseDir, "gui", module.upper(), "index.html")
596       if not os.path.isfile(docfile):
597         docfile = os.path.join(baseDir, "tui", module.upper(), "index.html")
598       if not os.path.isfile(docfile):
599         docfile = os.path.join(baseDir, "dev", module.upper(), "index.html")
600       if os.path.isfile(docfile):
601         out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
602       else:
603         print("Online documentation is not accessible for module:", module)
604
605   def _usage(self, unused=None):
606     usage()
607   #
608
609   def _makeCoffee(self, unused=None):
610     print("                        (")
611     print("                          )     (")
612     print("                   ___...(-------)-....___")
613     print("               .-\"\"       )    (          \"\"-.")
614     print("         .-\'``\'|-._             )         _.-|")
615     print("        /  .--.|   `\"\"---...........---\"\"`   |")
616     print("       /  /    |                             |")
617     print("       |  |    |                             |")
618     print("        \\  \\   |                             |")
619     print("         `\\ `\\ |                             |")
620     print("           `\\ `|            SALOME           |")
621     print("           _/ /\\            4 EVER           /")
622     print("          (__/  \\             <3            /")
623     print("       _..---\"\"` \\                         /`\"\"---.._")
624     print("    .-\'           \\                       /          \'-.")
625     print("   :               `-.__             __.-\'              :")
626     print("   :                  ) \"\"---...---\"\" (                 :")
627     print("    \'._               `\"--...___...--\"`              _.\'")
628     print("      \\\"\"--..__                              __..--\"\"/")
629     print("       \'._     \"\"\"----.....______.....----\"\"\"     _.\'")
630     print("          `\"\"--..,,_____            _____,,..--\"\"`")
631     print("                        `\"\"\"----\"\"\"`")
632     print("")
633     print("                    SALOME is working for you; what else?")
634     print("")
635   #
636
637   def _getCar(self, unused=None):
638     print("                                              _____________")
639     print("                                  ..---:::::::-----------. ::::;;.")
640     print("                               .\'\"\"\"\"\"\"                  ;;   \\  \":.")
641     print("                            .\'\'                          ;     \\   \"\\__.")
642     print("                          .\'                            ;;      ;   \\\\\";")
643     print("                        .\'                              ;   _____;   \\\\/")
644     print("                      .\'                               :; ;\"     \\ ___:\'.")
645     print("                    .\'--...........................    : =   ____:\"    \\ \\")
646     print("               ..-\"\"                               \"\"\"\'  o\"\"\"     ;     ; :")
647     print("          .--\"\"  .----- ..----...    _.-    --.  ..-\"     ;       ;     ; ;")
648     print("       .\"\"_-     \"--\"\"-----\'\"\"    _-\"        .-\"\"         ;        ;    .-.")
649     print("    .\'  .\'   SALOME             .\"         .\"              ;       ;   /. |")
650     print("   /-./\'         4 EVER <3    .\"          /           _..  ;       ;   ;;;|")
651     print("  :  ;-.______               /       _________==.    /_  \\ ;       ;   ;;;;")
652     print("  ;  / |      \"\"\"\"\"\"\"\"\"\"\".---.\"\"\"\"\"\"\"          :    /\" \". |;       ; _; ;;;")
653     print(" /\"-/  |                /   /                  /   /     ;|;      ;-\" | ;\';")
654     print(":-  :   \"\"\"----______  /   /              ____.   .  .\"\'. ;;   .-\"..T\"   .")
655     print("\'. \"  ___            \"\":   \'\"\"\"\"\"\"\"\"\"\"\"\"\"\"    .   ; ;    ;; ;.\" .\"   \'--\"")
656     print(" \",   __ \"\"\"  \"\"---... :- - - - - - - - - \' \'  ; ;  ;    ;;\"  .\"")
657     print("  /. ;  \"\"\"---___                             ;  ; ;     ;|.\"\"")
658     print(" :  \":           \"\"\"----.    .-------.       ;   ; ;     ;:")
659     print("  \\  \'--__               \\   \\        \\     /    | ;     ;;")
660     print("   \'-..   \"\"\"\"---___      :   .______..\\ __/..-\"\"|  ;   ; ;")
661     print("       \"\"--..       \"\"\"--\"        m l s         .   \". . ;")
662     print("             \"\"------...                  ..--\"\"      \" :")
663     print("                        \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"    \\        /")
664     print("                                               \"------\"")
665     print("")
666     print("                                Drive your simulation properly with SALOME!")
667     print("")
668   #
669
670   # Add the following two methods since logger is not pickable
671   # Ref: http://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python
672   def __getstate__(self):
673     d = dict(self.__dict__)
674     if hasattr(self, '_logger'):
675       del d['_logger']
676     return d
677   #
678   def __setstate__(self, d):
679     self.__dict__.update(d) # I *think* this is a safe way to do it
680   #
681   # Excluding self._logger from pickle operation imply using the following method to access logger
682   def getLogger(self):
683     if not hasattr(self, '_logger'):
684       self._logger = logging.getLogger(__name__)
685       #self._logger.setLevel(logging.DEBUG)
686       #self._logger.setLevel(logging.WARNING)
687       self._logger.setLevel(logging.ERROR)
688     return self._logger
689   #
690
691 if __name__ == "__main__":
692   if len(sys.argv) == 3:
693     context = pickle.loads(sys.argv[1].encode('latin1'))
694     args = pickle.loads(sys.argv[2].encode('latin1'))
695
696     status = context._startSalome(args)
697     sys.exit(status)
698   else:
699     usage()
700 #