talk-0.001/
talk-0.001/CVS/
talk-0.001/talklib/CVS/
"""This file defines a class Session, which is responsible for
handling a user's session from the moment they log in to the moment
they leave. This is really the work of TalkHandler, but it is
abstracted to another class for readability's sake. The TalkHandler
instance responsible is still held as an instance variable
self.handler so its members are present to the session."""

from constants import *
import users,sys,time,commands,socket

class Session:

    def __init__(self,handler):
        """Start a session - if user_login() returns 0, TalkHandler
        will quit, as self.logged_in will be false."""
        self.handler = handler
        # this is a borg, so instancing it just references an old
        # instance, singleton-stylee
        self.allusers = users.AllUsers()
        self.logged_in = self.user_login()

    def user_logout(self):
        '''Deletes a user and its reference in allusers. Called by the
        handler even if the connection dies'''
        name = self.user.name
        self.send_all("--%s logs out!" % name)
        self.allusers.deluser(self.user)
        del(self.user)

    def user_login(self):
        '''This method needs updating when the pfiles come into the
        code. At the moment it just asks for a name, then returns 0 if
        it's invalid or in use. If valid it'll create a new User
        object and add the user to allusers.'''
        self.send_prompt("Please login:")
        username = self.get_input().strip()
        if not username.isalnum():
            self.send_user('Sorry, name must be only letters and numbers')
            return 0
        if self.allusers.userdict.has_key(username.lower()):
            self.send_user('Sorry, name in use')
            return 0
        self.user = users.User(self,username)
        self.allusers.adduser(self.user)
        self.send_all("++%s logs in!" % self.user.name)
        return 1

    def process(self,msg):
        """Strips the message, logs the user out if it's 'quit', and
        creates a Command object from it"""
        msg = msg.strip()
        # nasty debug follows - prints to console everything typed
        print ("DEBUG: %s typed %s" % (self.user.name, msg))
        if msg.lower() == 'quit':
            self.logged_in = 0
            return
        command = commands.Command(self,msg)
        self.logged_in = 1

    def send_user(self,msg):
        "Sends a message to the user, and logs them out if they're dead"
        try:
            self.handler.request.send("%s\r\n" % msg)
        except socket.error:
            self.logged_in = 0
            self.user_logout()
            del self
            
    def send_all(self,msg):
        "Sends a message to all the users in allusers"
        for user in self.allusers.userdict.copy():
        #copy() because users might be deleted during iteration
            self.allusers.userdict[user].session.send_user(msg)

    def send_prompt(self,prompt):
        """This sends the user an unterminated string, which is usually
        a prompt."""
        self.handler.request.send("%s " % prompt)

    def get_input(self):
        """This keeps receiving messages until it gets a \n (problem
        with Windoze Telnet there, and then returns the lot."""
        msg = self.handler.request.recv(BLOCK_SIZE)
        if msg == "": return ""
        elif msg.endswith("\n"): return msg
        else: return msg + self.get_input()