<s> RCS_ID = '<STR_LIT>' <EOL> import string <EOL> VERSION = string . split ( RCS_ID ) [ <NUM_LIT:2> ] <EOL> import socket <EOL> import asyncore_25 as asyncore <EOL> import asynchat_25 as asynchat <EOL> import status_handler <EOL> class chat_channel ( asynchat . async_chat ) : <EOL> def __init__ ( self , server , sock , addr ) : <EOL> asynchat . async_chat . __init__ ( self , sock ) <EOL> self . server = server <EOL> self . addr = addr <EOL> self . set_terminator ( '<STR_LIT:\r\n>' ) <EOL> self . data = '<STR_LIT>' <EOL> self . nick = None <EOL> self . push ( '<STR_LIT>' ) <EOL> def collect_incoming_data ( self , data ) : <EOL> self . data = self . data + data <EOL> def found_terminator ( self ) : <EOL> line = self . data <EOL> self . data = '<STR_LIT>' <EOL> if self . nick is None : <EOL> self . nick = string . split ( line ) [ <NUM_LIT:0> ] <EOL> if not self . nick : <EOL> self . nick = None <EOL> self . push ( '<STR_LIT>' ) <EOL> else : <EOL> self . greet ( ) <EOL> else : <EOL> if not line : <EOL> pass <EOL> elif line [ <NUM_LIT:0> ] != '<STR_LIT:/>' : <EOL> self . server . push_line ( self , line ) <EOL> else : <EOL> self . handle_command ( line ) <EOL> def greet ( self ) : <EOL> self . push ( '<STR_LIT>' % self . nick ) <EOL> num_channels = len ( self . server . channels ) - <NUM_LIT:1> <EOL> if num_channels == <NUM_LIT:0> : <EOL> self . push ( '<STR_LIT>' ) <EOL> else : <EOL> self . push ( '<STR_LIT>' % ( len ( self . server . channels ) - <NUM_LIT:1> ) ) <EOL> nicks = map ( lambda x : x . get_nick ( ) , self . server . channels . keys ( ) ) <EOL> self . push ( string . join ( nicks , '<STR_LIT>' ) + '<STR_LIT:\r\n>' ) <EOL> self . server . push_line ( self , '<STR_LIT>' ) <EOL> def handle_command ( self , command ) : <EOL> import types <EOL> command_line = string . split ( command ) <EOL> name = '<STR_LIT>' % command_line [ <NUM_LIT:0> ] [ <NUM_LIT:1> : ] <EOL> if hasattr ( self , name ) : <EOL> method = getattr ( self , name ) <EOL> if type ( method ) == type ( self . handle_command ) : <EOL> method ( command_line [ <NUM_LIT:1> : ] ) <EOL> else : <EOL> self . push ( '<STR_LIT>' % command_line [ <NUM_LIT:0> ] ) <EOL> def cmd_quit ( self , args ) : <EOL> self . server . push_line ( self , '<STR_LIT>' ) <EOL> self . push ( '<STR_LIT>' ) <EOL> self . close_when_done ( ) <EOL> cmd_q = cmd_quit <EOL> def push_line ( self , nick , line ) : <EOL> self . push ( '<STR_LIT>' % ( nick , line ) ) <EOL> def handle_close ( self ) : <EOL> self . close ( ) <EOL> def close ( self ) : <EOL> del self . server . channels [ self ] <EOL> asynchat . async_chat . close ( self ) <EOL> def get_nick ( self ) : <EOL> if self . nick is not None : <EOL> return self . nick <EOL> else : <EOL> return '<STR_LIT>' <EOL> class chat_server ( asyncore . dispatcher ) : <EOL> SERVER_IDENT = '<STR_LIT>' % VERSION <EOL> channel_class = chat_channel <EOL> spy = <NUM_LIT:1> <EOL> def __init__ ( self , ip = '<STR_LIT>' , port = <NUM_LIT> ) : <EOL> asyncore . dispatcher . __init__ ( self ) <EOL> self . port = port <EOL> self . create_socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> self . bind ( ( ip , port ) ) <EOL> print '<STR_LIT>' % ( self . SERVER_IDENT , port ) <EOL> self . listen ( <NUM_LIT:5> ) <EOL> self . channels = { } <EOL> self . count = <NUM_LIT:0> <EOL> def handle_accept ( self ) : <EOL> conn , addr = self . accept ( ) <EOL> self . count = self . count + <NUM_LIT:1> <EOL> print '<STR_LIT>' % ( self . count , addr [ <NUM_LIT:0> ] , addr [ <NUM_LIT:1> ] ) <EOL> self . channels [ self . channel_class ( self , conn , addr ) ] = <NUM_LIT:1> <EOL> def push_line ( self , from_channel , line ) : <EOL> nick = from_channel . get_nick ( ) <EOL> if self . spy : <EOL> print '<STR_LIT>' % ( nick , line ) <EOL> for c in self . channels . keys ( ) : <EOL> if c is not from_channel : <EOL> c . push ( '<STR_LIT>' % ( nick , line ) ) <EOL> def status ( self ) : <EOL> lines = [ <EOL> '<STR_LIT>' % self . SERVER_IDENT , <EOL> '<STR_LIT>' % self . port , <EOL> '<STR_LIT>' % self . count , <EOL> '<STR_LIT>' % ( len ( self . channels ) ) <EOL> ] <EOL> return status_handler . lines_producer ( lines ) <EOL> def writable ( self ) : <EOL> return <NUM_LIT:0> <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> import sys <EOL> if len ( sys . argv ) > <NUM_LIT:1> : <EOL> port = string . atoi ( sys . argv [ <NUM_LIT:1> ] ) <EOL> else : <EOL> port = <NUM_LIT> <EOL> s = chat_server ( '<STR_LIT>' , port ) <EOL> asyncore . loop ( ) </s>
