4
# python-console <port> <magic>
15
from threading import Thread
17
class StdinFromWeb(object):
18
def __init__(self, cmdQ, lineQ):
25
self.cmdQ.put({"input":None})
28
# Some of our 5 seconds may have elapsed, but
33
class PythonRunner(Thread):
34
def __init__(self, cmdQ, lineQ):
41
globs['__builtins__'] = globals()['__builtins__']
43
compiler = codeop.CommandCompiler()
51
curr_cmd = curr_cmd + '\n' + l
53
cmd = compiler(curr_cmd)
55
# The command was incomplete,
56
# so send back a None, so the
57
# client can print a '...'
58
self.cmdQ.put({"more":None})
60
# The command was complete,
62
sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
63
out = cStringIO.StringIO()
67
res = eval(cmd, globs, locls)
69
self.cmdQ.put({"okay":(out.getvalue(),res)})
71
except Exception, exc:
73
self.cmdQ.put({"exc":str(exc)})
78
'/index.html', 'index',
79
'/(.*\.js)', 'jscript',
80
'/(.*\.css)', 'style',
83
# The global 'magic' is the secret that the client and server share
84
# which is used to create and md5 digest to authenticate requests.
85
# It is assigned a real value at startup.
93
digest = md5.new('hello' + magic).digest().encode('hex')
94
if inp.digest != digest:
95
web.ctx.status = '401 Unauthorized'
98
# Okay, so the authentication succeeded,
99
# so all we need to do is send back the static
100
# HTML for the console app.
101
web.output(file("index.html", "r").read())
105
web.output(file(name, "r").read())
109
web.output(file(name, "r").read())
117
digest = md5.new(inp.text + magic).digest().encode('hex')
118
if inp.digest != digest:
119
web.ctx.status = '401 Unauthorized'
122
# Okay, so the authentication succeeded,
123
# so now we have the trivial matter of actually
124
# executing the python....
127
sys.__stderr__.write(cjson.encode(r) + "\n")
128
web.output(cjson.encode(r))
131
lineQ = Queue.Queue()
132
interpThread = PythonRunner(cmdQ, lineQ)
134
if __name__ == "__main__":
138
web.run(urls, globals())