3
# Copyright (c) 2009 Twisted Matrix Laboratories.
4
# See LICENSE for details.
6
from zope.interface import implements
8
from twisted.cred import portal, checkers
9
from twisted.spread import pb
10
from twisted.internet import reactor
14
self.groups = {} # indexed by name
16
def joinGroup(self, groupname, user, allowMattress):
17
if not self.groups.has_key(groupname):
18
self.groups[groupname] = Group(groupname, allowMattress)
19
self.groups[groupname].addUser(user)
20
return self.groups[groupname]
23
implements(portal.IRealm)
24
def requestAvatar(self, avatarID, mind, *interfaces):
25
assert pb.IPerspective in interfaces
26
avatar = User(avatarID)
27
avatar.server = self.server
29
return pb.IPerspective, avatar, lambda a=avatar:a.detached(mind)
31
class User(pb.Avatar):
32
def __init__(self, name):
34
def attached(self, mind):
36
def detached(self, mind):
38
def perspective_joinGroup(self, groupname, allowMattress=True):
39
return self.server.joinGroup(groupname, self, allowMattress)
40
def send(self, message):
41
self.remote.callRemote("print", message)
43
class Group(pb.Viewable):
44
def __init__(self, groupname, allowMattress):
46
self.allowMattress = allowMattress
48
def addUser(self, user):
49
self.users.append(user)
50
def view_send(self, from_user, message):
51
if not self.allowMattress and message.find("mattress") != -1:
52
raise ValueError, "Don't say that word"
53
for user in self.users:
54
user.send("<%s> says: %s" % (from_user.name, message))
57
realm.server = ChatServer()
58
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
59
checker.addUser("alice", "1234")
60
checker.addUser("bob", "secret")
61
checker.addUser("carol", "fido")
62
p = portal.Portal(realm, [checker])
64
reactor.listenTCP(8800, pb.PBServerFactory(p))