By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,222 Members | 2,416 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,222 IT Pros & Developers. It's quick & easy.

Python noobie needs help with chatroom development

P: 1
Hey there
I've been following through the book "Beginning Python from Novice to Professional", and I have learned a great deal. At the moment, I am trying to expand upon the chatroom project near the end of this book.

My problem, is that I can't get my head around how to allow the users to add new rooms. At the moment, there is only one room. My first thought on how to do this was instantiating objects from the main room class, using the name that the user entered in the command. So, entering the command "/room myroom" would create a new object called "myroom" (if it didn't already exist) and then move the user into that room.

However, I can't see how you can specify the name of the new object as the program is running. A google session turned up nothing either.

I think I am attacking this in totally the wrong way, am I?

Expand|Select|Wrap|Line Numbers
  1. from asyncore import dispatcher
  2. from asynchat import async_chat
  3.  
  4. import socket, asyncore
  5.  
  6. PORT = 5006
  7. NAME = "Test Chat"
  8.  
  9. class EndSession(Exception): pass
  10.  
  11. class CommandHandler():
  12.     def unknown(self, session, cmd):
  13.         session.push('Unknown Command: %s\r\n' % cmd)
  14.  
  15.     def handle(self, session, line):
  16.         if not line.strip(): return
  17.  
  18.         parts = line.split(' ', 1)
  19.         cmd = parts[0]
  20.         #try: line = parts[1].strip()
  21.         #except IndexError: line = ''
  22.  
  23.         if cmd[0] == "/":
  24.             cmd = cmd[1:]
  25.             meth = getattr(self, 'do_'+cmd, None)
  26.  
  27.             if callable(meth):
  28.                 meth(session, line)
  29.             else:
  30.                 self.unknown(session, cmd)
  31.         else:
  32.             meth = getattr(self, 'do_say', None)
  33.             if callable(meth):
  34.                 meth(session, line)
  35.             else:
  36.                 self.unknown(session, cmd)
  37.  
  38. class Room(CommandHandler): 
  39.     def __init__(self, server):
  40.         self.server = server
  41.         self.sessions = []
  42.         self.name = "default"
  43.  
  44.     def add(self, session):
  45.         self.sessions.append(session)
  46.  
  47.     def remove(self, session):
  48.         self.sessions.remove(session)
  49.  
  50.     def broadcast(self, line):
  51.         for session in self.sessions:
  52.             session.push(line)
  53.  
  54.     def do_logout(self, session, line):
  55.         raise EndSession
  56.  
  57.     def do_room(self, session, line):
  58.         parts = line.split(' ', 1)
  59.         try: line = parts[1].strip()
  60.         except IndexError: line = ''
  61.         roomname = line.strip()
  62.         session.enter(self.server.main_room)
  63.  
  64. class LoginRoom(Room):
  65.     def add(self, session):
  66.         Room.add(self, session)
  67.         self.broadcast('Welcome to %s\r\n' % self.server.NAME)
  68.  
  69.     def unknown(self, session, cmd):
  70.         session.push('Please log in \nUse "login <nick>"\r\n')
  71.  
  72.     def do_login(self, session, line):
  73.         parts = line.split(' ', 1)
  74.         try: line = parts[1].strip()
  75.         except IndexError: line = ''
  76.         name = line.strip()
  77.         if not name:
  78.             session.push('Please enter a name\r\n')
  79.         elif name in self.server.users:
  80.             session.push('That name is already in use!')
  81.         else:
  82.             session.name = name
  83.             session.enter(self.server.main_room)
  84.  
  85.  
  86. class ChatRoom(Room):
  87.     def add(self, session):
  88.         self.broadcast(session.name + ' has entered the room!\r\n')
  89.         self.server.users[session.name] = session
  90.         Room.add(self, session)
  91.  
  92.     def remove(self, session):
  93.         Room.remove(self, session)
  94.         self.broadcast(session.name + ' has left the room!\r\n')
  95.  
  96.     def do_say(self, session, line):
  97.         self.broadcast(session.name+': '+line+'\r\n')
  98.  
  99.     def do_look(self, session, line):
  100.         session.push('The following people are in the room:\r\n')
  101.         for other in self.sessions:
  102.             session.push(other.name + '\r\n')
  103.  
  104.     def do_who(self, session, line):
  105.         session.push('The following people are logged in:\r\n')
  106.         for name in self.server.users:
  107.             session.push(name + '\r\n')
  108.  
  109. class LogoutRoom(Room):
  110.     def add(self, session):
  111.         try: del self.server.users[session.name]
  112.         except KeyError: pass
  113.  
  114. class ChatSession(async_chat):
  115.     def __init__(self, server, sock):
  116.         async_chat.__init__(self, sock)
  117.         self.server = server
  118.         self.set_terminator("\r\n")
  119.         self.data = []
  120.         self.name = None
  121.         self.enter(LoginRoom(server))
  122.  
  123.     def enter(self, room):
  124.         try: cur = self.room
  125.         except AttributeError: pass
  126.         else: cur.remove(self)
  127.         self.room = room
  128.         room.add(self)
  129.  
  130.     def collect_incoming_data(self, data):
  131.         self.data.append(data)
  132.  
  133.     def found_terminator(self):
  134.         line = ''.join(self.data)
  135.         self.data = []
  136.         try: self.room.handle(self, line)
  137.         except EndSession:
  138.             self.handle_close()
  139.  
  140.     def handle_close(self):
  141.         async_chat.handle_close(self)
  142.         self.enter(LogoutRoom(self.server))
  143.  
  144. class ChatServer(dispatcher):
  145.     def __init__(self, PORT, NAME):
  146.         dispatcher.__init__(self)
  147.         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
  148.         self.set_reuse_addr()
  149.         self.bind(('', PORT))
  150.         self.listen(5)
  151.         self.NAME = NAME
  152.         self.users = {}
  153.         self.main_room = ChatRoom(self)
  154.         self.rooms
  155.  
  156.     def handle_accept(self):
  157.         conn, addr = self.accept()
  158.         ChatSession(self, conn)
  159.  
  160. if __name__ == '__main__':
  161.     s = ChatServer(PORT, NAME)
  162.     try: asyncore.loop()
  163.     except KeyboardInterrupt: print
May 18 '07 #1
Share this Question
Share on Google+
1 Reply


bartonc
Expert 5K+
P: 6,596
Hey there
I've been following through the book "Beginning Python from Novice to Professional", and I have learned a great deal. At the moment, I am trying to expand upon the chatroom project near the end of this book.

My problem, is that I can't get my head around how to allow the users to add new rooms. At the moment, there is only one room. My first thought on how to do this was instantiating objects from the main room class, using the name that the user entered in the command. So, entering the command "/room myroom" would create a new object called "myroom" (if it didn't already exist) and then move the user into that room.

However, I can't see how you can specify the name of the new object as the program is running. A google session turned up nothing either.

I think I am attacking this in totally the wrong way, am I?
You can use exec() to turn strings into variable names. The trick (sometimes) is choosing which namespace to use. Go with default at first, thusly:

>>> class anObject:
... pass
...
>>> aName = "myVaribaleName"

>>> exec("%s = anObject" %(aName))
>>> myVaribaleName
<class __builtin__.anObject at 0x02CB3A20>
>>>
May 18 '07 #2

Post your reply

Sign in to post your reply or Sign up for a free account.