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

« back to all changes in this revision

Viewing changes to scripts/python-console

  • Committer: wagrant
  • Date: 2008-07-17 04:28:35 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:906
editor.js: Warn before saving if the open file is an old revision.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
import cjson
7
7
import codeop
8
 
import cPickle
9
 
import cStringIO
10
8
import md5
11
9
import os
12
10
import Queue
15
13
import sys
16
14
import traceback
17
15
from threading import Thread
 
16
from functools import partial
18
17
 
19
18
import common.chat
20
19
 
21
 
# This version must be supported by both the local and remote code
22
 
PICKLEVERSION = 0
23
 
 
24
20
class Interrupt(Exception):
25
21
    def __init__(self):
26
22
        Exception.__init__(self, "Interrupted!")
28
24
class ExpiryTimer(object):
29
25
    def __init__(self, idle):
30
26
        self.idle = idle
31
 
        signal.signal(signal.SIGALRM, self.timeout)
 
27
        signal.signal(signal.SIGALRM, partial(self.timeout))
32
28
 
33
29
    def ping(self):
34
30
        signal.alarm(self.idle)
41
37
 
42
38
    def timeout(self, signum, frame):
43
39
        sys.exit(1)
44
 
 
 
40
        
45
41
class StdinFromWeb(object):
46
42
    def __init__(self, cmdQ, lineQ):
47
43
        self.cmdQ = cmdQ
55
51
            return ln['chat']
56
52
        if 'interrupt' in ln:
57
53
            raise Interrupt()
 
54
        if 'terminate' in ln:
 
55
            sys.exit(0)
 
56
            
58
57
 
59
58
class StdoutToWeb(object):
60
59
    def __init__(self, cmdQ, lineQ):
158
157
            sys.stdout = self.webio
159
158
            sys.stderr = self.webio
160
159
            # We don't expect a return value - 'single' symbol prints it.
161
 
            self.eval(cmd)
 
160
            eval(cmd, self.globs)
162
161
            self.webio.flush()
163
162
            self.cmdQ.put({"okay": None})
164
163
            self.curr_cmd = ''
194
193
                    self.cmdQ.put({"exc": ''.join(tb).decode('utf-8', 'replace')})
195
194
                    self.webio.flush()
196
195
                    self.curr_cmd = ''
197
 
            elif 'block' in ln:
 
196
            if 'block' in ln:
198
197
                # throw away a partial command.
199
198
                try:
200
199
                    cmd = compile(ln['block'], "<web session>", 'exec');
204
203
                    self.webio.flush()
205
204
                    self.cmdQ.put({"exc": ''.join(tb).decode('utf-8', 'replace')})
206
205
                    self.curr_cmd = ''
207
 
            elif 'flush' in ln:
208
 
                # reset the globals
209
 
                self.globs = {}
210
 
                self.globs['__builtins__'] = globals()['__builtins__']
211
 
                self.cmdQ.put({'response': 'okay'})
212
 
                # Unpickle the new space (if provided)
213
 
                if isinstance(ln['flush'],dict):
214
 
                    for g in ln['flush']:
215
 
                        try:
216
 
                            self.globs[g] = cPickle.loads(ln['flush'][g])
217
 
                        except:
218
 
                            pass
219
 
            elif 'call' in ln:
220
 
                if isinstance(ln['call'], dict):
221
 
                    params = ln['call']
222
 
                    try:
223
 
                        # Expand parameters
224
 
                        if isinstance(params['args'], list):
225
 
                            args = map(self.eval, params['args'])
226
 
                        else:
227
 
                            args = []
228
 
                        if isinstance(params['kwargs'], dict):
229
 
                            kwargs = {}
230
 
                            for kwarg in params['kwargs']:
231
 
                                kwargs[kwarg] = self.eval(
232
 
                                    params['kwargs'][kwarg])
233
 
                        else:
234
 
                            kwargs = {}
235
 
 
236
 
                        # Run the fuction
237
 
                        function = self.eval(params['function'])
238
 
                        result = function(*args, **kwargs)
239
 
                        self.cmdQ.put({'output': result})
240
 
                    except Exception, e:
241
 
                        tb = format_exc_start(start=1)
242
 
                        self.cmdQ.put(
243
 
                            {"exc": ''.join(tb).decode('utf-8', 'replace')})
244
 
                else:
245
 
                    self.cmdQ.put({'response': 'failure'})
246
 
            elif 'inspect' in ln:
247
 
                # Like block but return a serialization of the state
248
 
                # throw away partial command
249
 
                inspection = {}
250
 
                stdout = cStringIO.StringIO()
251
 
                stderr = cStringIO.StringIO()
252
 
                try:
253
 
                    cmd = compile(ln['inspect'], "<web session>", 'exec');
254
 
                    sys.stdin = None
255
 
                    sys.stdout = stdout
256
 
                    sys.stderr = stderr
257
 
                    # We don't expect a return value - 'single' symbol prints 
258
 
                    # it.
259
 
                    self.eval(cmd)
260
 
                except Exception, e:
261
 
                    exception = {}
262
 
                    tb = format_exc_start(start=1)
263
 
                    exception['traceback'] = \
264
 
                        ''.join(tb).decode('utf-8', 'replace')
265
 
                    exception['except'] = cPickle.dumps(e, PICKLEVERSION)
266
 
                    inspection['exception'] = exception                
267
 
                
268
 
                # Write out the inspection object
269
 
                inspection['stdout'] = stdout.getvalue()
270
 
                inspection['stderr'] = stderr.getvalue()
271
 
                inspection['globals'] = flatten(self.globs)
272
 
                self.cmdQ.put(inspection)
273
 
                stdout.close()
274
 
                stderr.close()
275
 
                self.curr_cmd = ''
276
 
            else:
277
 
                raise Exception, "Invalid Command"
278
 
 
279
 
    def eval(self, source):
280
 
        """ Evaluates a string in the private global space """
281
 
        return eval(source, self.globs)
282
206
 
283
207
def daemonize():
284
208
    if os.fork():   # launch child and...
296
220
cmdQ = Queue.Queue()
297
221
lineQ = Queue.Queue()
298
222
interpThread = PythonRunner(cmdQ, lineQ)
299
 
terminate = None
300
223
 
301
224
# Default expiry time of 15 minutes
302
225
expiry = ExpiryTimer(15 * 60)
304
227
def initializer():
305
228
    interpThread.setDaemon(True)
306
229
    interpThread.start()
307
 
    signal.signal(signal.SIGXCPU, sig_handler)
308
230
    expiry.ping()
309
231
 
310
 
def sig_handler(signum, frame):
311
 
    """Handles response from signals"""
312
 
    global terminate
313
 
    if signum == signal.SIGXCPU:
314
 
        terminate = "CPU Time Limit Exceeded"
315
 
 
316
232
def dispatch_msg(msg):
317
 
    global terminate
318
 
    if msg['cmd'] == 'restart':
319
 
        terminate = "User requested console be reset"
320
 
    if terminate:
321
 
        raise common.chat.Terminate({"restart":terminate})
322
233
    expiry.ping()
323
234
    lineQ.put({msg['cmd']:msg['text']})
324
 
    if terminate:
325
 
        raise common.chat.Terminate({"restart":terminate})
326
235
    return cmdQ.get()
327
236
 
328
237
def format_exc_start(start=0):
412
321
        # Incomplete
413
322
        return count
414
323
 
415
 
# Takes an object and returns a flattened version suitable for JSON
416
 
def flatten(object):
417
 
    flat = {}
418
 
    for o in object:
419
 
        try:
420
 
            flat[o] = cPickle.dumps(object[o], PICKLEVERSION)
421
 
        except:
422
 
            pass
423
 
    return flat
424
 
 
425
324
if __name__ == "__main__":
426
325
    port = int(sys.argv[1])
427
326
    magic = sys.argv[2]
428
 
    
429
 
    # Sanitise the Enviroment
430
 
    os.environ = {}
431
 
    os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin'
432
 
 
433
327
    if len(sys.argv) >= 4:
434
328
        # working_dir
435
329
        os.chdir(sys.argv[3])
 
330
        # Make python's search path follow the cwd
 
331
        sys.path[0] = ''
436
332
        os.environ['HOME'] = sys.argv[3]
437
333
 
438
 
    # Make python's search path follow the cwd
439
 
    sys.path[0] = ''
440
 
 
441
334
    common.chat.start_server(port, magic, True, dispatch_msg, initializer)