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

95 by mattgiuca
Moved some things out of www into their respective dirs, console and
1
#!/usr/bin/python
2
3
# usage:
4
#   python-console <port> <magic>
5
126 by drtomc
A basic version of the console going!
6
import sys
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
7
import web
8
import md5
9
import codeop
10
import cjson
126 by drtomc
A basic version of the console going!
11
import cgi
12
import cStringIO
13
import signal
212 by drtomc
Gosh, it all looks pretty simple in the end!
14
import Queue
15
from threading import Thread
16
17
class StdinFromWeb(object):
18
    def __init__(self, cmdQ, lineQ):
19
        self.cmdQ = cmdQ
20
        self.lineQ = lineQ
21
22
    def readline(self):
23
        # stop the clock!
128 by drtomc
A couple of bug fixes.
24
        signal.alarm(0)
212 by drtomc
Gosh, it all looks pretty simple in the end!
25
        self.cmdQ.put({"input":None})
26
        l = self.lineQ.get()
27
        # restart the clock:
28
        # Some of our 5 seconds may have elapsed, but
29
        # never mind.
30
        signal.alarm(5)
31
        return l
32
33
class PythonRunner(Thread):
34
    def __init__(self, cmdQ, lineQ):
35
        self.cmdQ = cmdQ
36
        self.lineQ = lineQ
37
        Thread.__init__(self)
38
39
    def run(self):
263 by drtomc
A few little cleanups.
40
        self.init_state()
212 by drtomc
Gosh, it all looks pretty simple in the end!
41
        compiler = codeop.CommandCompiler()
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
42
212 by drtomc
Gosh, it all looks pretty simple in the end!
43
        while True:
44
            l = self.lineQ.get()
263 by drtomc
A few little cleanups.
45
            if self.curr_cmd == '':
46
                self.curr_cmd = l
212 by drtomc
Gosh, it all looks pretty simple in the end!
47
            else:
263 by drtomc
A few little cleanups.
48
                self.curr_cmd = self.curr_cmd + '\n' + l
212 by drtomc
Gosh, it all looks pretty simple in the end!
49
            try:
263 by drtomc
A few little cleanups.
50
                cmd = compiler(self.curr_cmd)
212 by drtomc
Gosh, it all looks pretty simple in the end!
51
                if cmd is None:
52
                    # The command was incomplete,
53
                    # so send back a None, so the
54
                    # client can print a '...'
55
                    self.cmdQ.put({"more":None})
56
                else:
57
                    # The command was complete,
58
                    # so evaluate it!
59
                    sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
60
                    out = cStringIO.StringIO()
61
                    sys.stdout = out
62
                    sys.stderr = out
63
                    signal.alarm(5)
64
                    res = eval(cmd, globs, locls)
65
                    signal.alarm(0)
66
                    self.cmdQ.put({"okay":(out.getvalue(),res)})
67
                    curr_cmd = ''
68
            except Exception, exc:
69
                signal.alarm(0)
70
                self.cmdQ.put({"exc":str(exc)})
71
                curr_cmd = ''
72
263 by drtomc
A few little cleanups.
73
    def init_state(self):
74
        self.globs = {}
75
        self.globs['__builtins__'] = globals()['__builtins__']
76
        self.locls = {}
77
        self.curr_cmd = ''
78
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
79
urls = (
80
    '/',            'index',
126 by drtomc
A basic version of the console going!
81
    '/index.html',  'index',
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
82
    '/(.*\.js)',    'jscript',
83
    '/(.*\.css)',   'style',
84
    '/chat',        'chat')
85
86
# The global 'magic' is the secret that the client and server share
87
# which is used to create and md5 digest to authenticate requests.
88
# It is assigned a real value at startup.
89
magic = ''
90
91
class index:
92
    def GET(self):
93
        inp = web.input()
94
95
        # Authenticate
96
        digest = md5.new('hello' + magic).digest().encode('hex')
97
        if inp.digest != digest:
98
            web.ctx.status = '401 Unauthorized'
99
            return
100
101
        # Okay, so the authentication succeeded,
102
        # so all we need to do is send back the static
103
        # HTML for the console app.
104
        web.output(file("index.html", "r").read())
105
106
class jscript:
107
    def GET(self, name):
108
        web.output(file(name, "r").read())
109
110
class style:
111
    def GET(self, name):
112
        web.output(file(name, "r").read())
113
114
class chat:
212 by drtomc
Gosh, it all looks pretty simple in the end!
115
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
116
    def POST(self):
117
        inp = web.input()
118
119
        # Authenticate
120
        digest = md5.new(inp.text + magic).digest().encode('hex')
121
        if inp.digest != digest:
275 by mattgiuca
python-console: If unauthorized, prints "401 Unauthorized" instead of nothing
122
            web.output("401 Unauthorized")
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
123
            web.ctx.status = '401 Unauthorized'
124
            return
125
126
        # Okay, so the authentication succeeded,
127
        # so now we have the trivial matter of actually
128
        # executing the python....
212 by drtomc
Gosh, it all looks pretty simple in the end!
129
        lineQ.put(inp.text)
130
        r = cmdQ.get()
131
        sys.__stderr__.write(cjson.encode(r) + "\n")
132
        web.output(cjson.encode(r))
133
134
cmdQ = Queue.Queue()
135
lineQ = Queue.Queue()
136
interpThread = PythonRunner(cmdQ, lineQ)
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
137
138
if __name__ == "__main__":
139
    magic = sys.argv[2]
264 by drtomc
Fix the "Aaarrgghh! ^C doesn't work problem". The multiple console process
140
    interpThread.setDaemon(True)
212 by drtomc
Gosh, it all looks pretty simple in the end!
141
    interpThread.start()
95 by mattgiuca
Moved some things out of www into their respective dirs, console and
142
    web.run(urls, globals())