~marten-de-vries/justforlearning/test-code

« back to all changes in this revision

Viewing changes to server.py

  • Committer: Marten de Vries
  • Date: 2011-07-17 11:40:43 UTC
  • Revision ID: marten94@gmail.com-20110717114043-alhqvsdgmg3057zd
De-prototyped the code, added a user rights system, socketpolicy server is now started automatically.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
import tornado.ioloop
24
24
import tornado.iostream
25
25
import tornado.auth
26
 
import tornado.autoreload
 
26
 
 
27
import launchpadlib.launchpad
27
28
 
28
29
import socket
29
30
import os
30
31
import uuid
 
32
import subprocess
31
33
 
 
34
#IRC settings
32
35
SERVER = "irc.freenode.net"
33
36
PORT = 6667
34
37
NICK = "JFLbot-dev"
35
38
PASSWORD = ""
36
 
CLASSROOM = "#PyTest-klas"
37
 
CHATROOM = "#PyTest"
 
39
CLASSROOM = "##PyTest-klas"
 
40
CHATROOM = "##PyTest"
 
41
 
 
42
#Launchpad settings
 
43
ADMIN_TEAM = "ubuntu-nl-mwanzo-team"
 
44
 
 
45
#Other settings
 
46
SOURCE = "http://is.gd/1fdrpR" # https://code.launchpad.net/~jfl-developers/justforlearning/Development; short because of max length real name IRC
 
47
LOG_FILE = "log.txt"
 
48
 
 
49
WEB_INTERFACE = "org.justforlearning.webinterface"
 
50
IRC_INTERFACE = "org.justforlearning.ircinterface"
 
51
 
 
52
class Event(object):
 
53
        def __init__(self, *args, **kwargs):
 
54
                super(Event, self).__init__(*args, **kwargs)
 
55
 
 
56
                self._handlers = set()
 
57
 
 
58
        def handle(self, handler):
 
59
                self._handlers.add(handler)
 
60
 
 
61
        def unhandle(self, handler):
 
62
                self._handlers.remove(handler)
 
63
 
 
64
        def emit(self, *args, **kwargs):
 
65
                for handler in self._handlers:
 
66
                        handler(*args, **kwargs)
38
67
 
39
68
class ChatHandler(object):
40
69
        def __init__(self, *args, **kwargs):
41
70
                super(ChatHandler, self).__init__(*args, **kwargs)
42
71
 
43
 
                self._counter = 0
 
72
                self.userUpdated = Event()
 
73
 
 
74
                self._questionCounter = 1
 
75
                self._userCounter = 1
44
76
 
45
77
                self._clients = set()
46
 
                self._logFile = open("log.txt", "a")
 
78
                self._logFile = open(LOG_FILE, "a")
 
79
                self._users = {}
47
80
 
48
81
        def _log(self, *args):
49
 
                args = list(args)
 
82
                args = map(unicode, args)
50
83
                args.append("---\n")
51
84
                text = u"\n".join(args)
52
85
                self._logFile.write(text.encode("UTF-8"))
53
86
 
54
 
        def sendChatMessage(self, poster, message):
55
 
                self._log(poster, message)
56
 
 
57
 
                for client in self._clients:
58
 
                        client.sendChatMessage(poster, message)
59
 
 
60
 
        def sendClassMessage(self, message):
61
 
                self._log(message)
62
 
 
63
 
                for client in self._clients:
64
 
                        client.sendClassMessage(message)
65
 
 
66
 
        def sendQuestion(self, poster, question):
67
 
                self._log(poster, question)
68
 
 
69
 
                for client in self._clients:
70
 
                        client.sendQuestion(self._counter, poster, question)
71
 
                self._counter += 1
72
 
 
73
 
        def answerQuestion(self, id, answer):
74
 
                self._log(id, answer)
75
 
                
76
 
                for client in self._clients:
77
 
                        client.answerQuestion(id, answer)
78
 
 
79
 
        def sendLink(self, link):
80
 
                self._log(link)
81
 
 
82
 
                for client in self._clients:
83
 
                        client.sendLink(id, answer)
 
87
        def sendLog(self, client):
 
88
                self._logFile.flush()
 
89
                first = True
 
90
                args = []
 
91
                for line in open(LOG_FILE):
 
92
                        line = line.strip()
 
93
                        if first:
 
94
                                methodName = line
 
95
                                first = False
 
96
                        elif line == "---":
 
97
                                self._sendClient(client, methodName, *args)
 
98
                                args = []
 
99
                                first = True
 
100
                        else:
 
101
                                args.append(line)
 
102
 
 
103
        def _sendClient(self, client, methodName, *args):
 
104
                getattr(client, methodName)(*args)
 
105
 
 
106
        def _send(self, methodName, *args):
 
107
                self._log(methodName, *args)
 
108
 
 
109
                for client in self._clients:
 
110
                        self._sendClient(client, methodName, *args)
 
111
 
 
112
        def sendChatMessage(self, *args):
 
113
                self._send("sendChatMessage", *args)
 
114
 
 
115
        def sendClassMessage(self, *args):
 
116
                self._send("sendClassMessage", *args)
 
117
 
 
118
        def askQuestion(self, *args):
 
119
                args = list(args)
 
120
                args.insert(1, self._questionCounter)
 
121
                self._send("askQuestion", *args)
 
122
                self._questionCounter += 1
 
123
 
 
124
        def answerQuestion(self, *args):
 
125
                self._send("answerQuestion", *args)
 
126
 
 
127
        def sendLink(self, *args):
 
128
                self._send("sendLink", *args)
 
129
 
 
130
        def addUser(self, clientName, nickname, role):
 
131
                userId = self._userCounter
 
132
                self._users[userId] = {
 
133
                        "client": clientName,
 
134
                        "nickname": nickname,
 
135
                        "role": role
 
136
                }
 
137
                self._userCounter += 1
 
138
                return userId
 
139
 
 
140
        def updateUser(self, userId, **kwargs):
 
141
                self._users[userId].update(kwargs)
 
142
                self.userUpdated.emit(userId, kwargs.keys())
 
143
 
 
144
        def removeUser(self, userId):
 
145
                del self._users[userId]
 
146
 
 
147
        def getUser(self, userId):
 
148
                return self._users[userId]
84
149
 
85
150
        def addClient(self, client):
86
 
#               try:
87
 
#                       file = open("log.txt")
88
 
#               except IOError:
89
 
#                       pass
90
 
#               else:
91
 
#                       for line in file:
92
 
#                               client.send(unicode(line.strip(), "UTF-8"))
93
151
                self._clients.add(client)
 
152
                self._users[client] = set()
94
153
 
95
154
        def removeClient(self, client):
96
155
                self._clients.remove(client)
 
156
                del self._users[client]
97
157
 
98
158
class IrcSocketStream(tornado.iostream.IOStream):
99
 
        def __init__(self, chatHandler, *args, **kwargs):
 
159
        def __init__(self, chatHandler, authorisationHandler, *args, **kwargs):
100
160
                s = socket.socket()
101
161
                super(IrcSocketStream, self).__init__(s, *args, **kwargs)
102
 
                
 
162
 
103
163
                self.chatHandler = chatHandler
104
 
 
105
 
                self.connect((SERVER, PORT), self.connectToIrc)
106
 
 
107
 
        def connectToIrc(self):
108
 
                text = "".join([
109
 
                        "PASS %s\r\n" % PASSWORD,
110
 
                        "NICK %s\r\n" % NICK,
111
 
                        "USER %s irc.freenode.net %s: %s\r\n" % (NICK.lower(), NICK, NICK),
 
164
                self.authorisationHandler = authorisationHandler
 
165
                
 
166
                self._activeNicks = {}
 
167
 
 
168
                self._chatroomOp = False
 
169
                self._classroomOp = False
 
170
 
 
171
                self.connect((SERVER, PORT), self._connectToIrc)
 
172
 
 
173
        def _connectToIrc(self):
 
174
                self.chatHandler.userUpdated.handle(self._updateUser)
 
175
                text = "\r\n".join([
 
176
                        "PASS %s" % PASSWORD,
 
177
                        "NICK %s" % NICK,
 
178
                        "USER %s 0 * :Source: %s" % (NICK, SOURCE),
 
179
                        "JOIN %s" % CLASSROOM,
 
180
                        "JOIN %s" % CHATROOM,
 
181
                        "", #last \r\n
112
182
                ])
113
183
                self.write(text)
114
 
                #FIXME: something nicer?
115
 
                self.read_until(" MODE ", self.join)
116
 
 
117
 
        def join(self, data):
118
 
                self.write("JOIN %s\r\n" % CLASSROOM)
119
 
                self.write("JOIN %s\r\n" % CHATROOM)
120
 
                self.read_until("\n", self.handleLine)
121
184
                self.chatHandler.addClient(self)
 
185
                self.read_until("\n", self._handleLine)
122
186
 
123
 
        def handleLine(self, line):
 
187
        def _handleLine(self, line):
124
188
                line = line.strip().split()
125
189
                if line[0] == "PING":
126
 
                        self.write("PONG %s\r\n" % line[0])
127
 
                if line[1] == "PRIVMSG" and line[2] in (CLASSROOM, CHATROOM):
128
 
                        data = " ".join(line[3:])
129
 
                        data = unicode(data[1:], "UTF-8") #[1:] strips the ':'
130
 
                        if line[2] == CLASSROOM:
131
 
                                self.parseClass(data)
132
 
                        else:
133
 
                                self.parseChat(data)
134
 
                self.read_until("\n", self.handleLine)
135
 
 
136
 
        def parseChat(self, line):
 
190
                        self._handlePing(line)
 
191
                elif line[1] == "MODE":
 
192
                        self._handleMode(line)
 
193
                elif line[1] == "JOIN":
 
194
                        self._handleJoin(line)
 
195
                elif line[1] == "PRIVMSG":
 
196
                        self._handlePrivMsg(line)
 
197
                self.read_until("\n", self._handleLine)
 
198
 
 
199
        def _handlePing(self, line):
 
200
                self.write("PONG %s\r\n" % line[0])
 
201
 
 
202
        def _handleMode(self, line):
 
203
                aboutOp = (
 
204
                        line[2] in (CHATROOM, CLASSROOM) and
 
205
                        "o" in line[3] and
 
206
                        line[4] == NICK
 
207
                )
 
208
                if aboutOp and "+" in line[3]:
 
209
                        if line[2] == CLASSROOM:
 
210
                                self._classroomOp = True
 
211
                                self._setupClassroom()
 
212
                        elif line[2] == CHATROOM:
 
213
                                self._chatroomOp = True
 
214
                elif aboutOp and "-" in line[3]:
 
215
                        if line[2] == CLASSROOM:
 
216
                                self._classroomOp = False
 
217
                        elif line[2] == CHATROOM:
 
218
                                self._chatroomOp = False
 
219
 
 
220
        @property
 
221
        def _op(self):
 
222
                return self._classroomOp and self._chatroomOp
 
223
 
 
224
        def _handleJoin(self, line):
 
225
                nick = line[0].split("!")[0][1:] #[1:] to strip ':'
 
226
                if self._op and nick in self.authorisationHandler.adminIRCNicks:
 
227
                        self._voiceNewNick(nick)
 
228
 
 
229
        def _setupClassroom(self):
 
230
                for nick in self.authorisationHandler.adminIRCNicks:
 
231
                        self._voiceNewNick(nick)
 
232
 
 
233
                self.write("MODE %s +m\r\n" % CLASSROOM)
 
234
 
 
235
        def _voiceNewNick(self, nick):
 
236
                userId = self._userId(nick)
 
237
                self.chatHandler.updateUser(userId, role="admin")
 
238
 
 
239
        def _userId(self, nick):
 
240
                if nick not in self._activeNicks:
 
241
                        userId = self.chatHandler.addUser(IRC_INTERFACE, nick, "user")
 
242
                        self._activeNicks[nick] = userId
 
243
                else:
 
244
                        userId = self._activeNicks[nick]
 
245
                return userId
 
246
 
 
247
        def _handlePrivMsg(self, line):
 
248
                if not self._op:
 
249
                        return
 
250
                nick = line[0].split("!")[0][1:] #[1:] to strip ':'
 
251
                data = " ".join(line[3:])
 
252
                data = unicode(data[1:], "UTF-8") #[1:] strips the ':'
 
253
                
 
254
                userId = self._userId(nick)
 
255
 
 
256
                if line[2] == CLASSROOM:
 
257
                        self._parseClass(userId, data)
 
258
                elif line[2] == CHATROOM:
 
259
                        self._parseChat(userId, data)
 
260
                elif line[2] == NICK:
 
261
                        self._parsePrivate(userId, data)
 
262
 
 
263
        def _parsePrivate(self, userId, line):
 
264
                nick = self.chatHandler.getUser(userId)["nickname"]
 
265
                if line == "help":
 
266
                        message = "No documentation yet!"
 
267
                        data = u"PRIVMSG %s :%s\r\n" % (nick, message)
 
268
                        self.write(data.encode("UTF-8"))
 
269
 
 
270
        def _updateUser(self, userId, keys):
 
271
                user = self.chatHandler.getUser(userId)
 
272
                if not user["client"] == IRC_INTERFACE:
 
273
                        return
 
274
                if "role" in keys:
 
275
                        if user["role"] == "silenced":
 
276
                                text = (2 * u"MODE %s +q %s\r\n") % (CLASSROOM, user["nickname"], CHATROOM, user["nickname"])
 
277
                        elif user["role"] == "user":
 
278
                                text = (2 * u"MODE %s -q %s\r\n") % (CLASSROOM, user["nickname"], CHATROOM, user["nickname"])
 
279
                                text += u"MODE %s -v %s\r\n" % (CLASSROOM, user["nickname"])
 
280
                        elif user["role"] == "admin":
 
281
                                text = u"MODE %s +v %s\r\n" % (CLASSROOM, user["nickname"])
 
282
                        self.write(text.encode("UTF-8"))
 
283
 
 
284
        def _parseChat(self, userId, line):
137
285
                try:
138
 
                        type, message = line.split(":")
 
286
                        type, message = line.split(":", 1)
139
287
                except ValueError:
140
288
                        pass
141
289
                else:
142
290
                        if type == "QUESTION":
143
 
                                self.chatHandler.sendQuestion("FIXNICK", message)
144
 
                                return
145
 
                self.chatHandler.sendChatMessage("FIXNICK", line)
146
 
 
147
 
        def parseClass(self, line):
148
 
                self.chatHandler.sendClassMessage(line)
149
 
 
150
 
        def _send(self, text):
151
 
                self.write(text.encode("UTF-8"))
152
 
 
153
 
        def sendClassMessage(self, message):
154
 
                data = u"PRIVMSG %s :%s\r\n" % (CLASSROOM, message)
155
 
                self._send(data)
156
 
 
157
 
        def sendChatMessage(self, poster, message):
158
 
                data = u"PRIVMSG %s :%s wrote: %s\r\n" % (CHATROOM, poster, message)
159
 
                self._send(data)
160
 
 
161
 
        def sendQuestion(self, id, poster, question):
162
 
                data = u"PRIVMSG %s :#%s %s asked: %s\r\n" % (CLASSROOM, id, poster, question)
163
 
                self._send(data)
164
 
 
165
 
        def answerQuestion(self, id, answer):
166
 
                data = u"PRIVMSG %s :#%s answer: %s\r\n" % (CLASSROOM, id, answer)
167
 
                self._send(data)
168
 
 
169
 
        def sendLink(self, link):
170
 
                data = u"PRIVMSG %s :Link: %s\r\n" % (CLASSROOM, link)
 
291
                                self.chatHandler.askQuestion(userId, message)
 
292
                                return
 
293
                self.chatHandler.sendChatMessage(userId, line)
 
294
 
 
295
        def _parseClass(self, userId, line):
 
296
                try:
 
297
                        type, message = line.split(":", 1)
 
298
                except ValueError:
 
299
                        pass
 
300
                else:
 
301
                        if type == "LINK":
 
302
                                self.chatHandler.sendLink(userId, message)
 
303
                                return
 
304
                        elif type.startswith("ANSWER"):
 
305
                                #ANSWER 4: blabla blabla
 
306
                                try:
 
307
                                        id = type.split(" ", 1)[1]
 
308
                                except IndexError:
 
309
                                        pass
 
310
                                else:
 
311
                                        self.chatHandler.answerQuestion(userId, id, message)
 
312
                                        return
 
313
                self.chatHandler.sendClassMessage(userId, line)
 
314
 
 
315
        def _send(self, room, message):
 
316
                message = message.replace(u"\r", u"").replace(u"\n", u"")
 
317
                data = u"PRIVMSG %s :%s\r\n" % (room, message)
 
318
                self.write(data.encode("UTF-8"))
 
319
 
 
320
        def sendClassMessage(self, userId, message):
 
321
                if self.chatHandler.getUser(userId)["client"] == IRC_INTERFACE:
 
322
                        return
 
323
                self._send(CLASSROOM, message)
 
324
 
 
325
        def sendChatMessage(self, userId, message):
 
326
                user = self.chatHandler.getUser(userId)
 
327
                if user["client"] == IRC_INTERFACE:
 
328
                        return
 
329
                self._send(CHATROOM, u"%s wrote: %s" % (user["nickname"], message))
 
330
 
 
331
        def askQuestion(self, userId, id, question):
 
332
                user = self.chatHandler.getUser(userId)
 
333
                self._send(CLASSROOM, u"#%s %s asked: %s" % (id, user["nickname"], question))
 
334
 
 
335
        def answerQuestion(self, userId, id, answer):
 
336
                if self.chatHandler.getUser(userId)["client"] == IRC_INTERFACE:
 
337
                        return
 
338
                self._send(CLASSROOM, u"#%s answer: %s" % (id, answer))
 
339
 
 
340
        def sendLink(self, userId, link):
 
341
                if self.chatHandler.getUser(userId)["client"] == IRC_INTERFACE:
 
342
                        return
 
343
                data = u"Link: %s\r\n" % (CLASSROOM, link)
 
344
                self._send(data)
171
345
 
172
346
class WebSocket(tornado.websocket.WebSocketHandler):
173
347
        def __init__(self, *args, **kwargs):
176
350
 
177
351
        def open(self):
178
352
                self.chatHandler.addClient(self)
 
353
                self.chatHandler.userUpdated.handle(self._updateUser)
179
354
 
180
355
        def on_message(self, message):
181
 
                poster = tornado.escape.json_decode(self.get_secure_cookie("user"))["nickname"]
 
356
                userId = int(self.get_secure_cookie("userId"))
 
357
                user = self.chatHandler.getUser(userId)
182
358
 
183
359
                type, message = message.split("\n", 1)
184
360
                if type == "question":
185
 
                        self.chatHandler.sendQuestion(poster, message)
 
361
                        if user["role"] in ("admin", "user"):
 
362
                                self.chatHandler.askQuestion(userId, message)
 
363
                elif type == "answer":
 
364
                        if user["role"] == "admin":
 
365
                                self.chatHandler.answerQuestion(userId, -1, message) #FIXME: -1
186
366
                elif type == "chat":
187
 
                        self.chatHandler.sendChatMessage(poster, message)
 
367
                        if user["role"] in ("admin", "user"):
 
368
                                self.chatHandler.sendChatMessage(userId, message)
 
369
                elif type == "class":
 
370
                        if user["role"] == "admin":
 
371
                                self.chatHandler.sendClassMessage(userId, message)
188
372
 
189
373
        def on_close(self):
190
374
                self.chatHandler.removeClient(self)
191
375
 
 
376
        def _updateUser(self, userId, keys):
 
377
                if userId == self.get_secure_cookie("userId"):
 
378
                        self._send("update")
 
379
 
192
380
        def _send(self, *args):
193
381
                args = map(unicode, args)
 
382
 
 
383
                user = self.chatHandler.getUser(int(args.pop(1)))
 
384
                args.insert(1, user["client"])
 
385
                args.insert(2, user["nickname"])
 
386
 
194
387
                data = tornado.escape.xhtml_escape("\n".join(args))
195
388
                self.write_message(data)
196
389
 
197
390
        sendChatMessage = lambda self, *args: self._send("chat", *args)
198
 
        sendClassMessage = lambda self, *args: self._send(*args)
199
 
        sendLink = lambda sef, *args: self._send("link", *args)
200
 
        sendQuestion = lambda self, *args: self._send("question", *args)
 
391
        sendClassMessage = lambda self, *args: self._send("class", *args)
 
392
        sendLink = lambda self, *args: self._send("link", *args)
 
393
        askQuestion = lambda self, *args: self._send("question", *args)
201
394
        answerQuestion = lambda self, *args: self._send("answer", *args)
202
395
 
203
396
class ClientHandler(tornado.web.RequestHandler):
 
397
        def __init__(self, *args, **kwargs):
 
398
                self.chatHandler = kwargs.pop("chatHandler")
 
399
                super(ClientHandler, self).__init__(*args, **kwargs)
 
400
 
204
401
        def get(self):
205
 
                if not self.get_secure_cookie("user"):
 
402
                if not self.get_secure_cookie("userId"):
206
403
                        self.redirect("/")
207
404
                        return
208
 
                user = tornado.escape.json_decode(self.get_secure_cookie("user"))
209
 
                self.render("client.html", nick=user["nickname"])
 
405
                user = self.chatHandler.getUser(int(self.get_secure_cookie("userId")))
 
406
                self.render("pages/client.html", source=SOURCE, **user)
210
407
 
211
408
class NicknameLogin(tornado.web.RequestHandler):
 
409
        def __init__(self, *args, **kwargs):
 
410
                self.chatHandler = kwargs.pop("chatHandler")
 
411
                super(NicknameLogin, self).__init__(*args, **kwargs)
 
412
 
212
413
        def post(self):
213
 
                user = tornado.escape.json_encode({
214
 
                        "nickname": self.get_argument("nickname"),
215
 
                        "authenticated": False,
216
 
                })
217
 
                self.set_secure_cookie("user", user)
 
414
                nickname = self.get_argument("nickname")
 
415
                userId = self.chatHandler.addUser(WEB_INTERFACE, nickname, "user")
 
416
                self.set_secure_cookie("userId", unicode(userId))
 
417
 
218
418
                self.redirect("/client")
219
419
 
220
420
class LaunchpadLogin(tornado.web.RequestHandler, tornado.auth.OpenIdMixin):
221
421
        _OPENID_ENDPOINT = "https://login.launchpad.net/+openid"
222
422
 
 
423
        def __init__(self, *args, **kwargs):
 
424
                self.chatHandler = kwargs.pop("chatHandler")
 
425
                self.authorisationHandler = kwargs.pop("authorisationHandler")
 
426
                super(LaunchpadLogin, self).__init__(*args, **kwargs)
 
427
 
223
428
        @tornado.web.asynchronous
224
429
        def get(self):
225
430
                if self.get_argument("openid.mode", None):
231
436
                if user is None:
232
437
                        raise tornado.web.HTTPError(500, "Launchpad authentication failed.")
233
438
                else:
234
 
                        user["authenticated"] = True
235
 
                        user["nickname"] = self.get_argument("openid.sreg.nickname")
236
 
                        self.set_secure_cookie("user", tornado.escape.json_encode(user))
 
439
                        nickname = self.get_argument("openid.sreg.nickname")
 
440
                        role = self.authorisationHandler.getRoleByLogin(nickname)
 
441
 
 
442
                        userId = self.chatHandler.addUser(WEB_INTERFACE, nickname, role)
 
443
 
 
444
                        self.set_secure_cookie("userId", unicode(userId))
237
445
                        self.redirect("/client")
238
446
 
239
447
        def _openid_args(self, *args, **kwargs):
246
454
 
247
455
class LoginHandler(tornado.web.RequestHandler):
248
456
        def get(self):
249
 
                if self.get_secure_cookie("user"):
 
457
                if self.get_secure_cookie("userId"):
250
458
                        self.redirect("/client")
251
 
                        return
252
 
                self.render("login.html")
 
459
                self.render("pages/login.html", source=SOURCE)
253
460
 
254
461
class LogoutHandler(tornado.web.RequestHandler):
 
462
        def __init__(self, *args, **kwargs):
 
463
                self.chatHandler = kwargs.pop("chatHandler")
 
464
                super(LogoutHandler, self).__init__(*args, **kwargs)
 
465
 
255
466
        def get(self):
256
 
                self.clear_cookie("user")
 
467
                self.chatHandler.removeUser(int(self.get_secure_cookie("userId")))
 
468
                self.clear_cookie("userId")
257
469
                self.redirect("/")
258
470
 
259
 
if __name__ == "__main__":
 
471
class AuthorisationHandler(object):
 
472
        def __init__(self, *args, **kwargs):
 
473
                super(AuthorisationHandler, self).__init__(*args, **kwargs)
 
474
 
 
475
                lp = launchpadlib.launchpad.Launchpad.login_anonymously(
 
476
                        "Just For Learning",
 
477
                        "production",
 
478
                        "~/.launchpadlib/cache/"
 
479
                )
 
480
                self.team = lp.people[ADMIN_TEAM]
 
481
 
 
482
        def getRoleByLogin(self, username):
 
483
                if username in map(lambda p: p.name, self.team.members):
 
484
                        return "admin"
 
485
                else:
 
486
                        return "user"
 
487
 
 
488
        @property
 
489
        def adminIRCNicks(self):
 
490
                nicks = []
 
491
                for person in self.team.members:
 
492
                        nicks.extend(map(lambda i: i.nickname, person.irc_nicknames))
 
493
                return nicks
 
494
 
 
495
def main():
 
496
        #Start socket policy server for browsers that don't support web sockets
 
497
        command = ["sudo", "python", "socketpolicy/socketpolicy.py"]
 
498
        if os.getuid() == 0:
 
499
                del command[0]
 
500
        subprocess.call(command)
 
501
 
260
502
        chatHandler = ChatHandler()
 
503
        authorisationHandler = AuthorisationHandler()
261
504
 
262
505
        settings = {
263
506
                "static_path": os.path.join(os.path.dirname(__file__), "static"),
267
510
 
268
511
        tornado.web.Application([
269
512
                ("/", LoginHandler),
270
 
                ("/nick-login", NicknameLogin),
271
 
                ("/lp-login", LaunchpadLogin),
272
 
                ("/logout", LogoutHandler),
273
 
                ("/client", ClientHandler),
 
513
                ("/nick-login", NicknameLogin, {"chatHandler": chatHandler}),
 
514
                ("/lp-login", LaunchpadLogin, {"authorisationHandler": authorisationHandler, "chatHandler": chatHandler}),
 
515
                ("/logout", LogoutHandler, {"chatHandler": chatHandler}),
 
516
                ("/client", ClientHandler, {"chatHandler": chatHandler}),
274
517
                ("/ws", WebSocket, {"chatHandler": chatHandler}),
275
518
        ], **settings).listen(8080)
276
519
 
277
 
        IrcSocketStream(chatHandler)
 
520
        IrcSocketStream(chatHandler, authorisationHandler)
278
521
 
279
522
        tornado.ioloop.IOLoop.instance().start()
 
523
 
 
524
if __name__ == "__main__":
 
525
        main()