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

« back to all changes in this revision

Viewing changes to scripts/python-console

  • Committer: mattgiuca
  • Date: 2008-03-01 01:59:10 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:630
subjects: Added subjects/subjects.css to correctly style the iframe.
    Added "sample" subject home page with minimal instructions on how to make
    a subject home page.
    Link to subjects.css.
Set svn:ignore on apps/subjects and apps/home (*.pyc).

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