4
# python-console <port> <magic>
15
from threading import Thread
16
from functools import partial
20
class ExpiryTimer(object):
21
def __init__(self, idle):
23
signal.signal(signal.SIGALRM, partial(self.timeout,self))
26
signal.alarm(self.idle)
28
def start(self, time):
34
def timeout(self, signum, frame):
37
class StdinFromWeb(object):
38
def __init__(self, cmdQ, lineQ):
44
self.cmdQ.put({"input":None})
50
class PythonRunner(Thread):
51
def __init__(self, cmdQ, lineQ):
54
self.out = cStringIO.StringIO()
57
def execCmd(self, cmd):
59
sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
62
res = eval(cmd, self.globs, self.locls)
63
self.cmdQ.put({"okay":(self.out.getvalue(),res)})
65
self.out = cStringIO.StringIO()
66
except Exception, exc:
67
self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
69
self.out = cStringIO.StringIO()
73
compiler = codeop.CommandCompiler()
78
if self.curr_cmd == '':
79
self.curr_cmd = ln['chat']
81
self.curr_cmd = self.curr_cmd + '\n' + ln['chat']
83
cmd = compiler(self.curr_cmd)
85
# The command was incomplete,
86
# so send back a None, so the
87
# client can print a '...'
88
self.cmdQ.put({"more":None})
91
except Exception, exc:
92
self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
94
self.out = cStringIO.StringIO()
96
# throw away a partial command.
98
cmd = compile(ln['block'], "<web session>", 'exec');
100
except Exception, exc:
101
self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
103
self.out = cStringIO.StringIO()
105
def init_state(self):
107
self.globs['__builtins__'] = globals()['__builtins__']
112
if os.fork(): # launch child and...
113
os._exit(0) # kill off parent
115
if os.fork(): # launch child and...
116
os._exit(0) # kill off parent again.
119
# The global 'magic' is the secret that the client and server share
120
# which is used to create and md5 digest to authenticate requests.
121
# It is assigned a real value at startup.
125
lineQ = Queue.Queue()
126
interpThread = PythonRunner(cmdQ, lineQ)
128
# Default expiry time of 15 minutes
129
expiry = ExpiryTimer(15 * 60)
132
interpThread.setDaemon(True)
136
def dispatch_msg(msg):
138
lineQ.put({msg['cmd']:msg['text']})
141
if __name__ == "__main__":
142
port = int(sys.argv[1])
145
common.chat.start_server(port, magic, True, dispatch_msg, initializer)