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

« back to all changes in this revision

Viewing changes to scripts/python-console

  • Committer: mattgiuca
  • Date: 2008-02-29 02:07:06 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:622
browser.js: Reinstated upload_callback (previously removed from listing.js).
    This is neccessary to prevent upload making a refresh as soon as the page
    loads, causing unnecessary server usage and currently causing an error as
    well.
__init__.py: Upload callback - changed from refresh() to a call to
    upload_callback() - which is a "smarter" wrapper around refresh().

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)