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

« back to all changes in this revision

Viewing changes to scripts/python-console

  • Committer: drtomc
  • Date: 2008-03-06 02:32:37 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:659
Add a little script for stuffing exercises into the database.

Add an identifier field to the problem table.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
# usage:
 
4
#   python-console <port> <magic> [<working-dir>]
 
5
 
 
6
import cjson
 
7
import codeop
 
8
import md5
 
9
import os
 
10
import Queue
 
11
import signal
 
12
import socket
 
13
import sys
 
14
from threading import Thread
 
15
from functools import partial
 
16
 
 
17
import common.chat
 
18
 
 
19
class Interrupt(Exception):
 
20
    def __init__(self):
 
21
        Exception.__init__(self, "Interrupted!")
 
22
 
 
23
class ExpiryTimer(object):
 
24
    def __init__(self, idle):
 
25
        self.idle = idle
 
26
        signal.signal(signal.SIGALRM, partial(self.timeout))
 
27
 
 
28
    def ping(self):
 
29
        signal.alarm(self.idle)
 
30
 
 
31
    def start(self, time):
 
32
        signal.alarm(time)
 
33
 
 
34
    def stop(self):
 
35
        self.ping()
 
36
 
 
37
    def timeout(self, signum, frame):
 
38
        sys.exit(1)
 
39
        
 
40
class StdinFromWeb(object):
 
41
    def __init__(self, cmdQ, lineQ):
 
42
        self.cmdQ = cmdQ
 
43
        self.lineQ = lineQ
 
44
 
 
45
    def readline(self):
 
46
        self.cmdQ.put({"input":None})
 
47
        expiry.ping()
 
48
        ln = self.lineQ.get()
 
49
        if 'chat' in ln:
 
50
            return ln['chat']
 
51
        if 'interrupt' in ln:
 
52
            raise Interrupt()
 
53
 
 
54
class StdoutToWeb(object):
 
55
    def __init__(self, cmdQ, lineQ):
 
56
        self.cmdQ = cmdQ
 
57
        self.lineQ = lineQ
 
58
        self.remainder = ''
 
59
 
 
60
    def write(self, stuff):
 
61
        # if there's less than 1K, buffer
 
62
        if len(self.remainder) + len(stuff) < 128:
 
63
            self.remainder = self.remainder + stuff
 
64
            return
 
65
 
 
66
        # Split the content up into lines, and ship all the completed
 
67
        # lines off to the server.
 
68
        lines = stuff.split("\n")
 
69
        lines[0] = self.remainder + lines[0]
 
70
        self.remainder = lines[-1]
 
71
        del lines[-1]
 
72
 
 
73
        if len(lines) > 0:
 
74
            lines.append('')
 
75
            text = "\n".join(lines)
 
76
            self.cmdQ.put({"output":text})
 
77
            expiry.ping()
 
78
            ln = self.lineQ.get()
 
79
            if 'interrupt' in ln:
 
80
                raise Interrupt()
 
81
 
 
82
    def flush(self):
 
83
        if len(self.remainder) > 0:
 
84
            self.cmdQ.put({"output":self.remainder})
 
85
            expiry.ping()
 
86
            ln = self.lineQ.get()
 
87
            self.remainder = ''
 
88
            if 'interrupt' in ln:
 
89
                raise Interrupt()
 
90
 
 
91
class PythonRunner(Thread):
 
92
    def __init__(self, cmdQ, lineQ):
 
93
        self.cmdQ = cmdQ
 
94
        self.lineQ = lineQ
 
95
        self.stdout = StdoutToWeb(self.cmdQ, self.lineQ)
 
96
        Thread.__init__(self)
 
97
 
 
98
    def execCmd(self, cmd):
 
99
        try:
 
100
            sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
 
101
            sys.stdout = self.stdout
 
102
            sys.stderr = self.stdout
 
103
            res = eval(cmd, self.globs, self.locls)
 
104
            self.stdout.flush()
 
105
            self.cmdQ.put({"okay":res})
 
106
            self.curr_cmd = ''
 
107
        except Exception, exc:
 
108
            self.stdout.flush()
 
109
            self.cmdQ.put({"exc":str(exc)})
 
110
            self.curr_cmd = ''
 
111
 
 
112
    def run(self):
 
113
        self.globs = {}
 
114
        self.globs['__builtins__'] = globals()['__builtins__']
 
115
        self.locls = {}
 
116
        self.curr_cmd = ''
 
117
        compiler = codeop.CommandCompiler()
 
118
 
 
119
        while True:
 
120
            ln = self.lineQ.get()
 
121
            if 'chat' in ln:
 
122
                if self.curr_cmd == '':
 
123
                    self.curr_cmd = ln['chat']
 
124
                else:
 
125
                    self.curr_cmd = self.curr_cmd + '\n' + ln['chat']
 
126
                try:
 
127
                    cmd = compiler(self.curr_cmd)
 
128
                    if cmd is None:
 
129
                        # The command was incomplete,
 
130
                        # so send back a None, so the
 
131
                        # client can print a '...'
 
132
                        self.cmdQ.put({"more":None})
 
133
                    else:
 
134
                        self.execCmd(cmd)
 
135
                except Exception, exc:
 
136
                    self.stdout.flush()
 
137
                    self.cmdQ.put({"exc":str(exc)})
 
138
                    self.curr_cmd = ''
 
139
            if 'block' in ln:
 
140
                # throw away a partial command.
 
141
                try:
 
142
                    cmd = compile(ln['block'], "<web session>", 'exec');
 
143
                    self.execCmd(cmd)
 
144
                except Exception, exc:
 
145
                    self.stdout.flush()
 
146
                    self.cmdQ.put({"exc":str(exc)})
 
147
                    self.curr_cmd = ''
 
148
 
 
149
def daemonize():
 
150
    if os.fork():   # launch child and...
 
151
        os._exit(0) # kill off parent
 
152
    os.setsid()
 
153
    if os.fork():   # launch child and...
 
154
        os._exit(0) # kill off parent again.
 
155
    os.umask(077)
 
156
 
 
157
# The global 'magic' is the secret that the client and server share
 
158
# which is used to create and md5 digest to authenticate requests.
 
159
# It is assigned a real value at startup.
 
160
magic = ''
 
161
 
 
162
cmdQ = Queue.Queue()
 
163
lineQ = Queue.Queue()
 
164
interpThread = PythonRunner(cmdQ, lineQ)
 
165
 
 
166
# Default expiry time of 15 minutes
 
167
expiry = ExpiryTimer(15 * 60)
 
168
 
 
169
def initializer():
 
170
    interpThread.setDaemon(True)
 
171
    interpThread.start()
 
172
    expiry.ping()
 
173
 
 
174
def dispatch_msg(msg):
 
175
    expiry.ping()
 
176
    lineQ.put({msg['cmd']:msg['text']})
 
177
    return cmdQ.get()
 
178
 
 
179
if __name__ == "__main__":
 
180
    port = int(sys.argv[1])
 
181
    magic = sys.argv[2]
 
182
    if len(sys.argv) >= 4:
 
183
        # working_dir
 
184
        os.chdir(sys.argv[3])
 
185
 
 
186
    common.chat.start_server(port, magic, True, dispatch_msg, initializer)