1 # Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 # Author : Adrien Bruneton (CEA)
25 import PARAVIS_ORB__POA
26 import SALOME_ComponentPy
27 import SALOME_DriverPy
31 import subprocess as subp
33 from time import sleep
35 #from SALOME_utilities import MESSAGE
38 os.system("echo \"%s\" >> /tmp/paravis_log.txt" % m)
41 """ The core implementation (non CORBA, or Study related).
42 See the IDL for the documentation.
44 MAX_PVSERVER_PORT_TRIES = 10
45 PARAVIEW_ROOT_DIR = "@PARAVIEW_ROOT_DIR@"
46 PVSERVER_DEFAULT_PORT = 11111
49 self.pvserverPort = -1
50 self.pvserverPop = None # Popen object from subprocess module
52 self.isGUIConnected = False # whether there is an active connection from the GUI.
55 Private. Identify a free port to launch the PVServer.
57 def __getFreePort(self, startPort):
60 while cnt < self.MAX_PVSERVER_PORT_TRIES:
62 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
63 s.bind(('', currPort))
66 except socket.error as e:
70 raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR,
71 "[PARAVIS] maximum number of tries to retrieve a free port for the PVServer",
74 def FindOrStartPVServer( self, port ):
75 MESSAGE("[PARAVIS] FindOrStartPVServer ...")
78 if self.pvserverPop is None:
81 # Poll active server to check if still alive
82 self.pvserverPop.poll()
83 if not self.pvserverPop.returncode is None: # server terminated
87 return "cs://%s:%d" % (host, self.pvserverPort)
89 # (else) Server not alive, start it:
90 pvServerPath = os.path.join(self.PARAVIEW_ROOT_DIR, 'bin', 'pvserver')
93 port = self.__getFreePort(self.PVSERVER_DEFAULT_PORT)
94 self.pvserverPop = subp.Popen([pvServerPath, "--multi-clients", "--server-port=%d" % port])
95 sleep(3) # Give some time to the server to start up to avoid
96 # ugly messages on the client side saying that it cannot connect
97 # Is PID still alive? If yes, consider that the launch was successful
98 self.pvserverPop.poll()
99 if self.pvserverPop.returncode is None:
101 self.pvserverPort = port
102 MESSAGE("[PARAVIS] pvserver successfully launched on port %d" % port)
104 raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR,
105 "[PARAVIS] Unable to start PVServer on port %d!" % port,
107 return "cs://%s:%d" % (host, self.pvserverPort)
109 def StopPVServer( self ):
110 MESSAGE("[PARAVIS] Trying to stop PVServer (sending KILL) ...")
111 if not self.pvserverPop is None:
112 self.pvserverPop.poll()
113 if self.pvserverPop.returncode is None:
114 # Terminate if still running:
115 self.pvserverPop.terminate()
116 MESSAGE("[PARAVIS] KILL signal sent.")
118 MESSAGE("[PARAVIS] Nothing to kill.")
121 def PutPythonTraceStringToEngine( self, t ):
124 def GetPythonTraceString(self):
125 return self.lastTrace
127 def SetGUIConnected( self, isConnected ):
128 self.isGUIConnected = isConnected
130 def GetGUIConnected( self ):
131 return self.isGUIConnected
133 class PARAVIS(PARAVIS_ORB__POA.PARAVIS_Gen,
134 SALOME_ComponentPy.SALOME_ComponentPy_i,
135 SALOME_DriverPy.SALOME_DriverPy_i,
138 Construct an instance of PARAVIS module engine.
139 The class PARAVIS implements CORBA interface PARAVIS_Gen (see PARAVIS_Gen.idl).
140 It is inherited from the classes SALOME_ComponentPy_i (implementation of
141 Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i
142 (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine).
144 def __init__ ( self, orb, poa, contID, containerName, instanceName,
146 SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
147 contID, containerName, instanceName, interfaceName, 0)
148 SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
149 PARAVIS_Impl.__init__(self)
151 self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
154 """ Override base class destroy to make sure we try to kill the pvserver
160 SALOME_ComponentPy.destroy(self)
163 Get version information.
165 def getVersion( self ):
166 import salome_version
167 return salome_version.getVersion("PARAVIS", True)
170 return PARAVIS_utils.getEngineIOR()
175 def createObject( self, study, name ):
176 MESSAGE("createObject()")
177 self._createdNew = True # used for getModifiedData method
178 builder = study.NewBuilder()
179 father = findOrCreateComponent( study )
180 object = builder.NewObject( father )
181 attr = builder.FindOrCreateAttribute( object, "AttributeName" )
182 attr.SetValue( name )
183 attr = builder.FindOrCreateAttribute( object, "AttributeLocalID" )
184 attr.SetValue( PARAVIS_utils.objectID() )
188 Dump module data to the Python script.
190 def DumpPython( self, study, isPublished, isMultiFile ):
191 MESSAGE("dumpPython()")
192 abuffer = self.GetPythonTraceString().split("\n")
194 abuffer = [ " " + s for s in abuffer ]
195 abuffer[0:0] = [ "def RebuildData( theStudy ):" ]
196 abuffer += [ " pass" ]
198 return ("\n".join( abuffer ), 1)
201 Import file to restore module data
203 def importData(self, studyId, dataContainer, options):
204 MESSAGE("importData()")
206 obj = self._naming_service.Resolve("myStudyManager")
207 myStudyManager = obj._narrow(SALOMEDS.StudyManager)
208 study = myStudyManager.GetStudyByID(studyId)
209 # create all objects from the imported stream
210 stream = dataContainer.get()
211 for objname in stream.split("\n"):
212 if len(objname) != 0:
213 self.createObject(study, objname)
214 self._createdNew = False # to store the modification of the study information later
215 return ["objects"] # identifier what is in this file
217 def getModifiedData(self, studyId):
218 MESSAGE("getModifiedData()")
221 obj = self._naming_service.Resolve("myStudyManager")
222 myStudyManager = obj._narrow(SALOMEDS.StudyManager)
223 study = myStudyManager.GetStudyByID(studyId)
224 # iterate all objects to get their names and store this information in stream
226 father = study.FindComponent( moduleName() )
228 iter = study.NewChildIterator( father )
230 name = iter.Value().GetName()
231 stream += name + "\n"
233 # store stream to the temporary file to send it in DataContainer
234 dataContainer = SALOME_DataContainerPy_i(stream, "", "objects", False, True)
235 aVar = dataContainer._this()