This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!

wxPBchatServer.py

By: Dernhelm on Jul 5th, 2012  |  syntax: Python  |  size: 4.12 KB  |  views: 5  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. from twisted.spread import pb
  2. from twisted.internet import reactor
  3. from twisted.cred import checkers, portal
  4. from zope.interface import implements
  5.  
  6. #[http://twistedmatrix.com/documents/current/core/howto/pb-cred.html]
  7.  
  8. class ChatS:
  9.     def __init__(self):
  10.         self.groups = {}
  11.         self.users = []
  12.  
  13.     #groups should be an option, but not the only option -
  14.     #figure out how to implement user-to-user chat without a group, or implicitly through a group
  15.     #for example: clicking on an online user creates a unique group ("user1+user2") and calls join group for the clicker and the clickee
  16.  
  17.     def joinGroup(self, groupN, user):
  18.         #if group doesn't exist...create
  19.         if not groupN in self.groups:
  20.             #creates a group object w/ given name, and put in dict w/ name as key
  21.             self.groups[groupN] = Group(groupN)
  22.             print "%s created." % (self.groups[groupN].name)
  23.         #add user to group
  24.         groupObj = self.groups[groupN]
  25.         groupObj.addUser(user)
  26.         print "%s really added to %s" % (user.name, groupObj.name)
  27.         print "Groups: %s" % (self.groups)
  28.         return self.groups[groupN]
  29.  
  30. #       TODO keep logs (where?)
  31.  
  32. #When the client runs login to request the Perspective,
  33. #they can provide it with an optional client argument
  34. #(which must be a pb.Referenceable object).
  35. #If they do, then a reference to that object will be handed
  36. #to the realm's requestAvatar in the mind argument.
  37.  
  38. class MyPerspective(pb.Avatar):
  39.     def __init__(self, name):
  40.         self.name = name
  41.     def attached(self, mind):
  42.         self.remote = mind
  43.     def detached(self, mind):
  44.         self.remote = None
  45.     def perspective_joinGroup(self, groupN):
  46.         print "about to call the REAL joinGroup"
  47.         return self.server.joinGroup(groupN, self)
  48.     #provide a way for the client to access the user list
  49.     def perspective_userList(self):
  50.         return ChatS().users
  51.     def perspective_groupList(self):
  52.         return ChatS().groups.keys
  53.     def send(self, message):
  54.         self.remote.callRemote("print", message)
  55.  
  56. #using viewable means that the class knows which avatar is using it
  57. class Group(pb.Viewable):
  58.     def __init__(self, groupN):
  59.         self.name = groupN
  60.         self.users = []
  61.     def addUser(self, user):
  62.         self.users.append(user)
  63.         print "Group consists of %s" % (self.users)
  64.     def view_send(self, sender, message):
  65.         #"Notice that the client uses perspective_joinGroup to both join a group
  66.         #and retrieve a RemoteReference to the Group object. However, the reference
  67.         #they get is actually to a special intermediate object called a pb.ViewPoint.
  68.         #When they do group.callRemote("send", "message"), their avatar is inserted
  69.         #into the argument list that Group.view_send actually sees. This lets the group
  70.         #get their username out of the Avatar without giving the client an opportunity
  71.         #to spoof someone else."
  72.         #[http://twistedmatrix.com/documents/10.1.0/core/howto/pb-cred.html#auto18]
  73.         for user in self.users:
  74.             user.send("%s: %s" % (sender.name, message))
  75.             print "Sent: %s, from %s, to %s" % (message, sender.name, user.name)
  76.         return self
  77.  
  78. #takes an avatarID and returns a MyPerspective object
  79. class MyRealm:
  80.     implements(portal.IRealm)
  81.     def requestAvatar(self, avatarID, mind, *interfaces):
  82.         assert pb.IPerspective in interfaces
  83.         user = MyPerspective(avatarID)
  84.         user.server = self.server
  85.         user.attached(mind)
  86.         user.server.users.append(user.name)
  87.         print user.server.users
  88.         return pb.IPerspective, user, lambda: None
  89.  
  90. def main():
  91.     #authuntication happens here
  92.     c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
  93.     c.addUser("USER", "none")
  94.     c.addUser("USER2", "none")
  95.     c.addUser("USER3", "none")
  96.     realm = MyRealm()
  97.     realm.server = ChatS()
  98.     p = portal.Portal(realm, [c])
  99.     server = pb.PBServerFactory(p)
  100.     #when called upon, make connection
  101.     reactor.listenTCP(1025, server)
  102.     reactor.run()
  103.  
  104.  
  105. if __name__ == '__main__':
  106.     main()
clone this paste RAW Paste Data