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

« back to all changes in this revision

Viewing changes to services/python-console

  • Committer: David Coles
  • Date: 2010-08-30 03:26:13 UTC
  • Revision ID: coles.david@gmail.com-20100830032613-d14vng0jkelniu3l
python-console: Fix globals broken with new JSON library.

simplejson always returns unicode strings. cJSON would return ordinary strings 
if possible. cPickle.loads() only accepts strings. At present we use pickle 
version 0 so they should all works as ASCII strings. Higher versions of pickle 
are not plain ASCII and are likely to break this and so this should be fixed 
at some point.

Also replaced unconditional exception with one that catches Pickle errors. Not 
sure the best way to report failures of these functions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
# usage:
4
4
#   python-console <port> <magic> [<working-dir>]
5
5
 
6
 
import cjson
7
6
import codeop
8
7
import cPickle
9
8
import cStringIO
10
9
import md5
11
 
import os
12
10
import Queue
13
11
import signal
14
12
import socket
171
169
 
172
170
    def run(self):
173
171
        # Set up global space and partial command buffer
174
 
        self.globs = {}
 
172
        self.globs = {'__name__': '__main__'}
175
173
        self.curr_cmd = ''
176
174
 
177
175
        # Set up I/O to use web interface
181
179
 
182
180
        # Handlers for each action
183
181
        actions = {
 
182
            'splash': self.handle_splash,
184
183
            'chat': self.handle_chat,
185
184
            'block': self.handle_block,
186
185
            'globals': self.handle_globals,
198
197
                response = {'error': repr(e)}
199
198
            finally:
200
199
                self.cmdQ.put(response)
201
 
                   
 
200
 
 
201
    def handle_splash(self, params):
 
202
        # Initial console splash screen
 
203
        python_version = '.'.join(str(v) for v in sys.version_info[:3])
 
204
        splash_text = ("""IVLE %s Python Console (Python %s)
 
205
Type "help", "copyright", "credits" or "license" for more information.
 
206
""" % (ivle.__version__, python_version))
 
207
        return {'output': splash_text}
 
208
 
202
209
    def handle_chat(self, params):
203
210
        # Set up the partial cmd buffer
204
211
        if self.curr_cmd == '':
208
215
 
209
216
        # Try to execute the buffer
210
217
        try:
211
 
            cmd = self.cc(self.curr_cmd, '<web session>')
 
218
            # A single trailing newline simply indicates that the line is
 
219
            # finished. Two trailing newlines indicate the end of a block.
 
220
            # Unfortunately, codeop.CommandCompiler causes even one to
 
221
            # terminate a block.
 
222
            # Thus we need to remove a trailing newline from the command,
 
223
            # unless there are *two* trailing newlines, or multi-line indented
 
224
            # blocks are impossible. See Google Code issue 105.
 
225
            cmd_text = self.curr_cmd
 
226
            if cmd_text.endswith('\n') and not cmd_text.endswith('\n\n'):
 
227
                cmd_text = cmd_text[:-1]
 
228
            cmd = self.cc(cmd_text, '<web session>')
212
229
            if cmd is None:
213
230
                # The command was incomplete, so send back a None, so the              
214
231
                # client can print a '...'
244
261
    def handle_globals(self, params):
245
262
        # Unpickle the new space (if provided)
246
263
        if isinstance(params, dict):
247
 
            self.globs = {}
 
264
            self.globs = {'__name__': '__main__'}
248
265
            for g in params:
249
266
                try:
250
 
                    self.globs[g] = cPickle.loads(params[g])
251
 
                except:
 
267
                    self.globs[g] = cPickle.loads(str(params[g]))
 
268
                except cPickle.UnpicklingError:
252
269
                    pass
253
270
 
254
271
        # Return the current globals
359
376
    """Handles response from signals"""
360
377
    global terminate
361
378
    if signum == signal.SIGXCPU:
362
 
        terminate = "CPU Time Limit Exceeded"
 
379
        terminate = "CPU time limit exceeded"
363
380
 
364
381
def dispatch_msg(msg):
365
382
    global terminate
366
383
    if msg['cmd'] == 'terminate':
367
 
        terminate = "User requested console be terminated"
 
384
        terminate = "User requested restart"
368
385
    if terminate:
369
386
        raise ivle.chat.Terminate({"terminate":terminate})
370
387
    expiry.ping()
389
406
    for o in object:
390
407
        try:
391
408
            flat[o] = cPickle.dumps(object[o], PICKLEVERSION)
392
 
        except TypeError:
 
409
        except (TypeError, cPickle.PicklingError):
393
410
            try:
394
411
                o_type = type(object[o]).__name__
395
412
                o_name = object[o].__name__
402
419
if __name__ == "__main__":
403
420
    port = int(sys.argv[1])
404
421
    magic = sys.argv[2]
405
 
    
406
 
    # Sanitise the Enviroment
407
 
    os.environ = {}
408
 
    os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin'
409
 
 
410
 
    if len(sys.argv) >= 4:
411
 
        # working_dir
412
 
        os.chdir(sys.argv[3])
413
 
        os.environ['HOME'] = sys.argv[3]
414
422
 
415
423
    # Make python's search path follow the cwd
416
424
    sys.path[0] = ''