~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to console/python-console

  • Committer: mattgiuca
  • Date: 2008-01-25 00:53:12 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:298
tutorial: Problem files are now given relative to the subjects base directory,
    not the directory for this subject. This allows problem files to be shared
    across subjects and offerings.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
# usage:
 
4
#   python-console <port> <magic>
 
5
 
 
6
import sys
 
7
import web
 
8
import md5
 
9
import codeop
 
10
import cjson
 
11
import cgi
 
12
import cStringIO
 
13
import signal
 
14
import Queue
 
15
from threading import Thread
 
16
 
 
17
class StdinFromWeb(object):
 
18
    def __init__(self, cmdQ, lineQ):
 
19
        self.cmdQ = cmdQ
 
20
        self.lineQ = lineQ
 
21
 
 
22
    def readline(self):
 
23
        # stop the clock!
 
24
        signal.alarm(0)
 
25
        self.cmdQ.put({"input":None})
 
26
        l = self.lineQ.get()
 
27
        # restart the clock:
 
28
        # Some of our 5 seconds may have elapsed, but
 
29
        # never mind.
 
30
        signal.alarm(5)
 
31
        return l
 
32
 
 
33
class PythonRunner(Thread):
 
34
    def __init__(self, cmdQ, lineQ):
 
35
        self.cmdQ = cmdQ
 
36
        self.lineQ = lineQ
 
37
        Thread.__init__(self)
 
38
 
 
39
    def run(self):
 
40
        self.init_state()
 
41
        compiler = codeop.CommandCompiler()
 
42
 
 
43
        while True:
 
44
            l = self.lineQ.get()
 
45
            if self.curr_cmd == '':
 
46
                self.curr_cmd = l
 
47
            else:
 
48
                self.curr_cmd = self.curr_cmd + '\n' + l
 
49
            try:
 
50
                cmd = compiler(self.curr_cmd)
 
51
                if cmd is None:
 
52
                    # The command was incomplete,
 
53
                    # so send back a None, so the
 
54
                    # client can print a '...'
 
55
                    self.cmdQ.put({"more":None})
 
56
                else:
 
57
                    # The command was complete,
 
58
                    # so evaluate it!
 
59
                    sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
 
60
                    out = cStringIO.StringIO()
 
61
                    sys.stdout = out
 
62
                    sys.stderr = out
 
63
                    signal.alarm(5)
 
64
                    res = eval(cmd, globs, locls)
 
65
                    signal.alarm(0)
 
66
                    self.cmdQ.put({"okay":(out.getvalue(),res)})
 
67
                    curr_cmd = ''
 
68
            except Exception, exc:
 
69
                signal.alarm(0)
 
70
                self.cmdQ.put({"exc":str(exc)})
 
71
                curr_cmd = ''
 
72
 
 
73
    def init_state(self):
 
74
        self.globs = {}
 
75
        self.globs['__builtins__'] = globals()['__builtins__']
 
76
        self.locls = {}
 
77
        self.curr_cmd = ''
 
78
 
 
79
urls = (
 
80
    '/',            'index',
 
81
    '/index.html',  'index',
 
82
    '/(.*\.js)',    'jscript',
 
83
    '/(.*\.css)',   'style',
 
84
    '/chat',        'chat')
 
85
 
 
86
# The global 'magic' is the secret that the client and server share
 
87
# which is used to create and md5 digest to authenticate requests.
 
88
# It is assigned a real value at startup.
 
89
magic = ''
 
90
 
 
91
class index:
 
92
    def GET(self):
 
93
        inp = web.input()
 
94
 
 
95
        # Authenticate
 
96
        digest = md5.new('hello' + magic).digest().encode('hex')
 
97
        if inp.digest != digest:
 
98
            web.ctx.status = '401 Unauthorized'
 
99
            return
 
100
 
 
101
        # Okay, so the authentication succeeded,
 
102
        # so all we need to do is send back the static
 
103
        # HTML for the console app.
 
104
        web.output(file("index.html", "r").read())
 
105
 
 
106
class jscript:
 
107
    def GET(self, name):
 
108
        web.output(file(name, "r").read())
 
109
 
 
110
class style:
 
111
    def GET(self, name):
 
112
        web.output(file(name, "r").read())
 
113
 
 
114
class chat:
 
115
 
 
116
    def POST(self):
 
117
        inp = web.input()
 
118
 
 
119
        # Authenticate
 
120
        digest = md5.new(inp.text + magic).digest().encode('hex')
 
121
        if inp.digest != digest:
 
122
            web.output("401 Unauthorized")
 
123
            web.ctx.status = '401 Unauthorized'
 
124
            return
 
125
 
 
126
        # Okay, so the authentication succeeded,
 
127
        # so now we have the trivial matter of actually
 
128
        # executing the python....
 
129
        lineQ.put(inp.text)
 
130
        r = cmdQ.get()
 
131
        sys.__stderr__.write(cjson.encode(r) + "\n")
 
132
        web.output(cjson.encode(r))
 
133
 
 
134
cmdQ = Queue.Queue()
 
135
lineQ = Queue.Queue()
 
136
interpThread = PythonRunner(cmdQ, lineQ)
 
137
 
 
138
if __name__ == "__main__":
 
139
    magic = sys.argv[2]
 
140
    interpThread.setDaemon(True)
 
141
    interpThread.start()
 
142
    web.run(urls, globals())