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

« back to all changes in this revision

Viewing changes to scripts/python-console

  • Committer: mattgiuca
  • Date: 2008-06-23 11:38:50 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:788
fileservice_lib: Fixed and made consistent the error message if a file already
    exists, across all actions. (Previously 3 different messages).

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
import signal
12
12
import socket
13
13
import sys
14
 
import traceback
15
14
from threading import Thread
16
15
from functools import partial
17
16
 
51
50
            return ln['chat']
52
51
        if 'interrupt' in ln:
53
52
            raise Interrupt()
54
 
        if 'terminate' in ln:
55
 
            sys.exit(0)
56
 
            
57
53
 
58
54
class StdoutToWeb(object):
59
55
    def __init__(self, cmdQ, lineQ):
61
57
        self.lineQ = lineQ
62
58
        self.remainder = ''
63
59
 
64
 
    def _trim_incomplete_final(self, stuff):
65
 
        '''Trim an incomplete UTF-8 character from the end of a string.
66
 
           Returns (trimmed_string, count_of_trimmed_bytes).
67
 
        '''
68
 
        tokill = incomplete_utf8_sequence(stuff)
69
 
        if tokill == 0:
70
 
            return (stuff, tokill)
71
 
        else:
72
 
            return (stuff[:-tokill], tokill)
73
 
 
74
60
    def write(self, stuff):
75
 
        # print will only give a non-file a unicode or str. There's no way
76
 
        # to convince it to encode unicodes, so we have to do it ourselves.
77
 
        # Yay for file special-cases (fileobject.c, PyFile_WriteObject).
78
 
        # If somebody wants to write some other object to here, they do it
79
 
        # at their own peril.
80
 
        if isinstance(stuff, unicode):
81
 
            stuff = stuff.encode('utf-8')
82
61
        self.remainder = self.remainder + stuff
83
62
 
84
63
        # if there's less than 128 bytes, buffer
87
66
 
88
67
        # if there's lots, then send it in 1/2K blocks
89
68
        while len(self.remainder) > 512:
90
 
            # We send things as Unicode inside JSON, so we must only send
91
 
            # complete UTF-8 characters.
92
 
            (blk, count) = self._trim_incomplete_final(self.remainder[:512])
93
 
            self.cmdQ.put({"output":blk.decode('utf-8', 'replace')})
 
69
            blk = self.remainder[0:512]
 
70
            self.cmdQ.put({"output":blk})
94
71
            expiry.ping()
95
72
            ln = self.lineQ.get()
96
 
            self.remainder = self.remainder[512 - count:]
 
73
            self.remainder = self.remainder[512:]
97
74
 
98
75
        # Finally, split the remainder up into lines, and ship all the
99
76
        # completed lines off to the server.
104
81
        if len(lines) > 0:
105
82
            lines.append('')
106
83
            text = "\n".join(lines)
107
 
            self.cmdQ.put({"output":text.decode('utf-8', 'replace')})
 
84
            self.cmdQ.put({"output":text})
108
85
            expiry.ping()
109
86
            ln = self.lineQ.get()
110
87
            if 'interrupt' in ln:
112
89
 
113
90
    def flush(self):
114
91
        if len(self.remainder) > 0:
115
 
            (out, count) = self._trim_incomplete_final(self.remainder)
116
 
            self.cmdQ.put({"output":out.decode('utf-8', 'replace')})
 
92
            self.cmdQ.put({"output":self.remainder})
117
93
            expiry.ping()
118
94
            ln = self.lineQ.get()
119
 
            # Leave incomplete characters in the buffer.
120
 
            # Yes, this does mean that an incomplete character will be left
121
 
            # off the end, but we discussed this and it was deemed best.
122
 
            self.remainder = self.remainder[len(self.remainder)-count:]
 
95
            self.remainder = ''
123
96
            if 'interrupt' in ln:
124
97
                raise Interrupt()
125
98
 
156
129
            sys.stdin = self.webio
157
130
            sys.stdout = self.webio
158
131
            sys.stderr = self.webio
159
 
            # We don't expect a return value - 'single' symbol prints it.
160
 
            eval(cmd, self.globs)
 
132
            res = eval(cmd, self.globs)
161
133
            self.webio.flush()
162
 
            self.cmdQ.put({"okay": None})
 
134
            self.cmdQ.put({"okay":res})
163
135
            self.curr_cmd = ''
164
 
        except:
165
 
            tb = format_exc_start(start=1)
 
136
        except Exception, exc:
166
137
            self.webio.flush()
167
 
            self.cmdQ.put({"exc": ''.join(tb).decode('utf-8', 'replace')})
 
138
            exc_classname = exc.__class__.__name__
 
139
            self.cmdQ.put({"exc": exc_classname + ": " + str(exc)})
168
140
            self.curr_cmd = ''
169
141
 
170
142
    def run(self):
171
143
        self.globs = {}
172
144
        self.globs['__builtins__'] = globals()['__builtins__']
173
145
        self.curr_cmd = ''
 
146
        compiler = codeop.CommandCompiler()
174
147
 
175
148
        while True:
176
149
            ln = self.lineQ.get()
180
153
                else:
181
154
                    self.curr_cmd = self.curr_cmd + '\n' + ln['chat']
182
155
                try:
183
 
                    cmd = codeop.compile_command(self.curr_cmd, '<web session>')
 
156
                    cmd = compiler(self.curr_cmd)
184
157
                    if cmd is None:
185
158
                        # The command was incomplete,
186
159
                        # so send back a None, so the
188
161
                        self.cmdQ.put({"more":None})
189
162
                    else:
190
163
                        self.execCmd(cmd)
191
 
                except:
192
 
                    tb = format_exc_start(start=3)
193
 
                    self.cmdQ.put({"exc": ''.join(tb).decode('utf-8', 'replace')})
 
164
                except Exception, exc:
194
165
                    self.webio.flush()
 
166
                    self.cmdQ.put({"exc":str(exc)})
195
167
                    self.curr_cmd = ''
196
168
            if 'block' in ln:
197
169
                # throw away a partial command.
198
170
                try:
199
171
                    cmd = compile(ln['block'], "<web session>", 'exec');
200
172
                    self.execCmd(cmd)
201
 
                except:
202
 
                    tb = format_exc_start(start=1)
 
173
                except Exception, exc:
203
174
                    self.webio.flush()
204
 
                    self.cmdQ.put({"exc": ''.join(tb).decode('utf-8', 'replace')})
 
175
                    self.cmdQ.put({"exc":str(exc)})
205
176
                    self.curr_cmd = ''
206
177
 
207
178
def daemonize():
234
205
    lineQ.put({msg['cmd']:msg['text']})
235
206
    return cmdQ.get()
236
207
 
237
 
def format_exc_start(start=0):
238
 
    etype, value, tb = sys.exc_info()
239
 
    tbbits = traceback.extract_tb(tb)[start:]
240
 
    list = ['Traceback (most recent call last):\n']
241
 
    list = list + traceback.format_list(tbbits)
242
 
    list = list + traceback.format_exception_only(etype, value)
243
 
    return ''.join(list)
244
 
 
245
 
def incomplete_utf8_sequence(byteseq):
246
 
    """
247
 
    str -> int
248
 
    Given a UTF-8-encoded byte sequence (str), returns the number of bytes at
249
 
    the end of the string which comprise an incomplete UTF-8 character
250
 
    sequence.
251
 
 
252
 
    If the string is empty or ends with a complete character OR INVALID
253
 
    sequence, returns 0.
254
 
    Otherwise, returns 1-3 indicating the number of bytes in the final
255
 
    incomplete (but valid) character sequence.
256
 
 
257
 
    Does not check any bytes before the final sequence for correctness.
258
 
 
259
 
    >>> incomplete_utf8_sequence("")
260
 
    0
261
 
    >>> incomplete_utf8_sequence("xy")
262
 
    0
263
 
    >>> incomplete_utf8_sequence("xy\xc3\xbc")
264
 
    0
265
 
    >>> incomplete_utf8_sequence("\xc3")
266
 
    1
267
 
    >>> incomplete_utf8_sequence("\xbc\xc3")
268
 
    1
269
 
    >>> incomplete_utf8_sequence("xy\xbc\xc3")
270
 
    1
271
 
    >>> incomplete_utf8_sequence("xy\xe0\xa0")
272
 
    2
273
 
    >>> incomplete_utf8_sequence("xy\xf4")
274
 
    1
275
 
    >>> incomplete_utf8_sequence("xy\xf4\x8f")
276
 
    2
277
 
    >>> incomplete_utf8_sequence("xy\xf4\x8f\xa0")
278
 
    3
279
 
    """
280
 
    count = 0
281
 
    expect = None
282
 
    for b in byteseq[::-1]:
283
 
        b = ord(b)
284
 
        count += 1
285
 
        if b & 0x80 == 0x0:
286
 
            # 0xxxxxxx (single-byte character)
287
 
            expect = 1
288
 
            break
289
 
        elif b & 0xc0 == 0x80:
290
 
            # 10xxxxxx (subsequent byte)
291
 
            pass
292
 
        elif b & 0xe0 == 0xc0:
293
 
            # 110xxxxx (start of 2-byte sequence)
294
 
            expect = 2
295
 
            break
296
 
        elif b & 0xf0 == 0xe0:
297
 
            # 1110xxxx (start of 3-byte sequence)
298
 
            expect = 3
299
 
            break
300
 
        elif b & 0xf8 == 0xf0:
301
 
            # 11110xxx (start of 4-byte sequence)
302
 
            expect = 4
303
 
            break
304
 
        else:
305
 
            # Invalid byte
306
 
            return 0
307
 
 
308
 
        if count >= 4:
309
 
            # Seen too many "subsequent bytes", invalid
310
 
            return 0
311
 
 
312
 
    if expect is None:
313
 
        # We never saw a "first byte", invalid
314
 
        return 0
315
 
 
316
 
    # We now know expect and count
317
 
    if count >= expect:
318
 
        # Complete, or we saw an invalid sequence
319
 
        return 0
320
 
    elif count < expect:
321
 
        # Incomplete
322
 
        return count
323
 
 
324
208
if __name__ == "__main__":
325
209
    port = int(sys.argv[1])
326
210
    magic = sys.argv[2]