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

« back to all changes in this revision

Viewing changes to scripts/python-console

  • Committer: mattgiuca
  • Date: 2008-01-20 10:03:06 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:251
setup.py: Worked the "files to copy into jail" out into a separate list
instead of being expressed as code.
Still need to add some more dependencies to get matplotlib working.

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