"""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()