]> SALOME platform Git repositories - modules/paravis.git/blob - src/ENGINE/no_wrap/PARAVIS.py.in
Salome HOME
Merge branch 'master' of ssh://git.salome-platform.org/modules/paravis
[modules/paravis.git] / src / ENGINE / no_wrap / PARAVIS.py.in
1 # Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 #
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.
10 #
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.
15 #
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
19 #
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #
22 # Author : Adrien Bruneton (CEA)
23 #
24
25 import PARAVIS_ORB__POA
26 import SALOME_ComponentPy
27 import SALOME_DriverPy
28 import SALOMEDS
29 import SALOME
30 import PARAVIS_utils
31 import subprocess as subp
32 import socket
33 from time import sleep
34 import os
35 #from SALOME_utilities import MESSAGE
36
37 def MESSAGE(m):
38     pass
39     #os.system("echo \"%s\" >> /tmp/paravis_log.txt" % m)
40
41 class PARAVIS_Impl:
42     """ The core implementation (non CORBA, or Study related).
43         See the IDL for the documentation.
44     """
45     MAX_PVSERVER_PORT_TRIES = 10
46     PARAVIEW_ROOT_DIR = "@PARAVIEW_ROOT_DIR@"
47     PVSERVER_DEFAULT_PORT = 11111
48     
49     def __init__(self):
50         self.pvserverPort = -1
51         self.pvserverPop = None  # Popen object from subprocess module
52         self.lastTrace = ""
53         self.isGUIConnected = False  # whether there is an active connection from the GUI.
54             
55     """
56     Private. Identify a free port to launch the PVServer. 
57     """
58     def __getFreePort(self, startPort):
59         cnt = 0
60         currPort = startPort
61         while cnt < self.MAX_PVSERVER_PORT_TRIES:
62             try:
63                 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
64                 s.bind(('', currPort))
65                 s.close()
66                 return currPort
67             except socket.error as e:
68                 cnt += 1
69                 currPort += 1
70                 pass
71         raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR,
72                             "[PARAVIS] maximum number of tries to retrieve a free port for the PVServer",
73                             "PARAVIS.py", 0))
74                                            
75     def FindOrStartPVServer( self, port ):
76         MESSAGE("[PARAVIS] FindOrStartPVServer ...")
77         host = "localhost"
78         alive = True
79         if self.pvserverPop is None:
80             alive = False
81         else:
82             # Poll active server to check if still alive
83             self.pvserverPop.poll()
84             if not self.pvserverPop.returncode is None:  # server terminated
85                 alive = False
86         
87         if alive:
88             return "cs://%s:%d" % (host, self.pvserverPort)  
89           
90         # (else) Server not alive, start it:
91         pvServerPath = os.path.join(self.PARAVIEW_ROOT_DIR, 'bin', 'pvserver')
92         opt = []
93         if port <= 0:
94             port = self.__getFreePort(self.PVSERVER_DEFAULT_PORT)
95         self.pvserverPop = subp.Popen([pvServerPath, "--multi-clients", "--server-port=%d" % port])
96         sleep(3)  # Give some time to the server to start up to avoid 
97                   # ugly messages on the client side saying that it cannot connect
98         # Is PID still alive? If yes, consider that the launch was successful
99         self.pvserverPop.poll()
100         if self.pvserverPop.returncode is None:
101             success = True
102             self.pvserverPort = port
103             MESSAGE("[PARAVIS] pvserver successfully launched on port %d" % port)
104         else:
105             raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR,
106                             "[PARAVIS] Unable to start PVServer on port %d!" % port,
107                             "PARAVIS.py", 0))
108         return "cs://%s:%d" % (host, self.pvserverPort)
109
110     def StopPVServer( self ):
111         MESSAGE("[PARAVIS] Trying to stop PVServer (sending KILL) ...")
112         if not self.pvserverPop is None:
113             self.pvserverPop.poll()
114             if self.pvserverPop.returncode is None:
115                 # Terminate if still running:
116                 self.pvserverPop.terminate()
117                 MESSAGE("[PARAVIS] KILL signal sent.")
118                 return True
119         MESSAGE("[PARAVIS] Nothing to kill.")
120         return False
121     
122     def PutPythonTraceStringToEngine( self, t ):
123         self.lastTrace = t
124         
125     def GetPythonTraceString(self):
126         return self.lastTrace
127       
128     def SetGUIConnected( self, isConnected ):
129         self.isGUIConnected = isConnected
130         
131     def GetGUIConnected( self ):
132         return self.isGUIConnected
133     
134 class PARAVIS(PARAVIS_ORB__POA.PARAVIS_Gen,
135               SALOME_ComponentPy.SALOME_ComponentPy_i,
136               SALOME_DriverPy.SALOME_DriverPy_i,
137               PARAVIS_Impl):
138     """
139     Construct an instance of PARAVIS module engine.
140     The class PARAVIS implements CORBA interface PARAVIS_Gen (see PARAVIS_Gen.idl).
141     It is inherited from the classes SALOME_ComponentPy_i (implementation of
142     Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i
143     (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine).
144     """
145     def __init__ ( self, orb, poa, contID, containerName, instanceName, 
146                    interfaceName ):
147         SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
148                     contID, containerName, instanceName, interfaceName, 0)
149         SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
150         PARAVIS_Impl.__init__(self)
151         #
152         self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
153         #
154
155     """ Override base class destroy to make sure we try to kill the pvserver
156         before leaving.
157     """
158     def destroy(self):    
159         self.StopPVServer()
160         # Invokes super():
161         SALOME_ComponentPy.destroy(self)
162       
163     """
164     Get version information.
165     """
166     def getVersion( self ):
167         import salome_version
168         return salome_version.getVersion("PARAVIS", True)
169
170     def GetIOR(self):
171         return PARAVIS_utils.getEngineIOR()
172
173     """
174     Create object.
175     """
176     def createObject( self, study, name ):
177         MESSAGE("createObject()")
178         self._createdNew = True # used for getModifiedData method
179         builder = study.NewBuilder()
180         father  = findOrCreateComponent( study )
181         object  = builder.NewObject( father )
182         attr    = builder.FindOrCreateAttribute( object, "AttributeName" )
183         attr.SetValue( name )
184         attr    = builder.FindOrCreateAttribute( object, "AttributeLocalID" )
185         attr.SetValue( PARAVIS_utils.objectID() )
186         pass
187
188     """
189     Dump module data to the Python script.
190     """
191     def DumpPython( self, study, isPublished, isMultiFile ):
192         MESSAGE("dumpPython()") 
193         abuffer = self.GetPythonTraceString().split("\n")
194         if isMultiFile:
195             abuffer       = [ "  " + s for s in abuffer ]
196             abuffer[0:0]  = [ "def RebuildData( theStudy ):" ]
197             abuffer      += [ "  pass" ]
198         abuffer += [ "\0" ]
199         return ("\n".join( abuffer ), 1)
200   
201     """
202     Import file to restore module data
203     """
204     def importData(self, studyId, dataContainer, options):
205       MESSAGE("importData()")
206       # get study by Id
207       obj = self._naming_service.Resolve("myStudyManager")
208       myStudyManager = obj._narrow(SALOMEDS.StudyManager)
209       study = myStudyManager.GetStudyByID(studyId)
210       # create all objects from the imported stream
211       stream = dataContainer.get()
212       for objname in stream.split("\n"):
213         if len(objname) != 0:
214           self.createObject(study, objname)
215       self._createdNew = False # to store the modification of the study information later
216       return ["objects"] # identifier what is in this file
217  
218     def getModifiedData(self, studyId):
219       MESSAGE("getModifiedData()")
220       if self._createdNew:
221         # get study by Id
222         obj = self._naming_service.Resolve("myStudyManager")
223         myStudyManager = obj._narrow(SALOMEDS.StudyManager)
224         study = myStudyManager.GetStudyByID(studyId)
225         # iterate all objects to get their names and store this information in stream
226         stream=""
227         father = study.FindComponent( moduleName() )
228         if father:
229             iter = study.NewChildIterator( father )
230             while iter.More():
231                 name = iter.Value().GetName()
232                 stream += name + "\n"
233                 iter.Next()
234         # store stream to the temporary file to send it in DataContainer
235         dataContainer = SALOME_DataContainerPy_i(stream, "", "objects", False, True)
236         aVar = dataContainer._this()
237         return [aVar]
238       return []