Skip to content

Commit c1e01a3

Browse files
committed
PythonInterpreter: Added code to handle XmlRpc over pipe, but not work yet. Also forgot to update project file for name changes in previous commit
1 parent 7103e11 commit c1e01a3

4 files changed

Lines changed: 71 additions & 10 deletions

File tree

PythonInterpreter/PythonInterpCtrl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,17 +169,18 @@ long PythonInterpCtrl::LaunchProcess(const wxString &processcmd, const wxArraySt
169169
{
170170
if(!IsDead())
171171
return -1;
172-
//wxMessageBox(m_portalloc.GetPorts());
173172
m_port=m_portalloc.RequestPort();
174173
if(m_port<0)
175174
return -1;
176-
//TODO: get the command and working dir from the
175+
//TODO: XmlRpc over pipe doesn't work because of the way interp.py is implemented
176+
// m_port = -1; //Use XmlRpc over pipe
177+
//TODO: get the command and working dir from config
177178
#ifdef __WXMSW__
178179
wxString cmd=_T("cmd /c interp.py ")+wxString::Format(_T(" %i"),m_port); //TODO: this could have process destruction issues on earlier version of wxWidgets (kills cmd, but not python)
179180
wxString python=_T("\\python");
180181
wxString interp=_T("\\interp.py");
181182
#else
182-
wxString cmd=_T("python interp.py ")+wxString::Format(_T(" %i"),m_port);
183+
wxString cmd=_T("python -u interp.py ")+wxString::Format(_T(" %i"),m_port);
183184
wxString python=_T("/python");
184185
wxString interp=_T("/interp.py");
185186
#endif

PythonInterpreter/PythonInterpCtrl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ class PythonInterpCtrl : public ShellCtrlBase
143143

144144
void stdin_append(const wxString &data);
145145
wxString stdin_retrieve();
146-
wxString stdout_retrieve();
147-
wxString stderr_retrieve();
148146

149147
protected:
150148
bool RunCode(const wxString &codestr);

PythonInterpreter/PythonInterpreter-unix.cbp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@
105105
<Add directory="$(#cb)/devel" />
106106
<Add directory="../XmlRpcEmbedder" />
107107
</Linker>
108-
<Unit filename="PyPlugin.cpp" />
109-
<Unit filename="PyPlugin.h" />
110108
<Unit filename="PythonInterpCtrl.cpp">
111109
<Option target="default" />
112110
<Option target="toolspluslink" />
@@ -115,6 +113,8 @@
115113
<Option target="default" />
116114
<Option target="toolspluslink" />
117115
</Unit>
116+
<Unit filename="PythonInterpreter.cpp" />
117+
<Unit filename="PythonInterpreter.h" />
118118
<Unit filename="Resources/dialogs.fbp">
119119
<Option target="&lt;{~None~}&gt;" />
120120
</Unit>

PythonInterpreter/python/interp.py

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,65 @@
44
import time
55
from SimpleXMLRPCServer import SimpleXMLRPCServer
66

7+
import os
8+
import struct
9+
import xmlrpclib
10+
11+
o_stdin = sys.stdin
12+
o_stdout = sys.stdout
13+
14+
isz=struct.calcsize('I')
15+
16+
class XmlRpcPipeServer:
17+
'''
18+
A simple XMLRPC server implementation that uses the stdin, stdout
19+
pipes to communicate with the owner of the process. Implements
20+
most of the features of SimpleXMLRPCServer
21+
'''
22+
def __init__(self):
23+
self.fn_dict={}
24+
self.inpipe=o_stdin
25+
self.outpipe=o_stdout
26+
sys.stdout=open(os.devnull,'wb')
27+
sys.stderr=open(os.devnull,'wb')
28+
29+
def register_function(self,fn,name):
30+
self.fn_dict[name]=fn
31+
32+
def register_introspection_functions(self):
33+
pass
34+
35+
def handle_request(self):
36+
##TODO: Need more error handling!
37+
size_buf = self.inpipe.read(isz)
38+
size = struct.unpack('I',size_buf)[0]
39+
call_xml = self.inpipe.read(size)
40+
self.outpipe.write(struct.pack('c','M'))
41+
name=''
42+
try:
43+
args,name = xmlrpclib.loads(call_xml)
44+
result = self.__call__(name, *args)
45+
if not isinstance(result,tuple):
46+
result=(result,)
47+
except:
48+
import traceback
49+
result ='Error running call '+name+'\n'+call_xml+'\n'
50+
result += '\n'.join(traceback.format_exception(*sys.exc_info()))
51+
result = (result,)
52+
try:
53+
res_xml = bytes(xmlrpclib.dumps(result, methodresponse=True))
54+
except:
55+
res_xml = bytes(xmlrpclib.dumps('Method result of length %i could not be converted to XML'%(len(res_xml)), methodresponse=True))
56+
size = len(res_xml)
57+
self.outpipe.write(struct.pack('I',size))
58+
self.outpipe.write(res_xml)
59+
self.outpipe.flush()
60+
61+
def __call__(self,name,*args):
62+
return self.fn_dict[name](*args)
63+
64+
65+
766
DEBUG=False
867

968
if DEBUG:
@@ -134,7 +193,10 @@ def __init__(self,port):
134193
def start_interp(self):
135194
self.interp.main_loop()
136195
def run(self):
137-
self.server = SimpleXMLRPCServer(("localhost", self.port))
196+
if self.port==-1:
197+
self.server = XmlRpcPipeServer()
198+
else:
199+
self.server = SimpleXMLRPCServer(("localhost", self.port))
138200
self.server.logRequests=0
139201
self.server.register_introspection_functions()
140202
#self.server.socket.settimeout(self.timeout) ##timeouts cause probs
@@ -180,7 +242,7 @@ def cont(self,stdin):
180242
logmsg('returning result ',result)
181243
return result
182244
#return status, stdout, stderr
183-
def break(self):
245+
def break_code(self):
184246
if self.interp._runningeval:
185247
raise KeyboardInterrupt
186248

@@ -197,7 +259,7 @@ def cmd_err():
197259
port = int(sys.argv[1])
198260
except:
199261
cmd_err()
200-
if port<=0:
262+
if port<-1:
201263
cmd_err()
202264

203265
logmsg('starting server on port', port)

0 commit comments

Comments
 (0)