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

« back to all changes in this revision

Viewing changes to scripts/python-console

  • Committer: dcoles
  • Date: 2008-03-04 11:38:02 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:642
makeuser.py: Needs to import random

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