class _BaseConnection(object): MAX_LINELEN = 512 connection_closed_event = Event() registration_event = Event() command_received_event = Event() def __init__(self, address, socket=None, factory=None): """ Base class for IRC connections. address: A tuple containing the remote host/IP and port of the connection socket: An existing socket for the connection, or None if a new connection is to be established. factory: The factory that was used to create this object. """ self.socket_address = address self.socket = socket self.factory = factory evt = Event() evt.bind(self.__class__.connection_closed_event, filter=match_source(self)) self.connection_closed_event = evt evt = Event() evt.bind(self.__class__.registration_event, filter=match_source(self)) self.registration_event = evt evt = Event() evt.bind(self.__class__.command_received_event, filter=match_source(self)) self.command_received_event = evt self.me = Nick(self) self.server = Nick(self) self.registered = False self.away = False self.realname = None self.usermodes = '' self.nicks = WeakValueDictionary() self.channels = {} self.isupport = { 'CHANMODES': 'bIe,k,l', 'CHANTYPES': '#&+', 'PREFIX': '(ov)@+', 'NAMESX': '' } self.motd = [] self.owner = None self._registration_timeout = None def start(self): return gevent.spawn(self._run) def _run(self): try: if self.socket == None: self.socket = socket.create_connection(self.socket_address) self._line_writer = QueuedLineWriter(self.socket) self._line_writer.start() self.handle_connection_made() connection = self.socket.makefile('w+b', 1) while True: line = connection.readline() if not line: break self.process_line(line) except Exception: exc_info = sys.exc_info() sys.excepthook(*exc_info) finally: try: # Not calling possibly derived methods # as they might not be safe to call from here. _BaseConnection.close(self) except: pass self.__class__.connection_closed_event.invoke(self) def close(self, message=None): if self._registration_timeout != None: self._registration_timeout.cancel() self._line_writer.close() def handle_exception(self, exc): pass def get_nick(self, hostmask): if hostmask == None: return None hostmask_dict = utils.parse_hostmask(hostmask) nick = hostmask_dict['nick'] nickobj = None if nick == self.me.nick: nickobj = self.me elif nick == self.server.nick: nickobj = self.server elif nick in self.nicks: nickobj = self.nicks[nick] else: nickobj = Nick(self, hostmask_dict) self.nicks[nick] = nickobj nickobj.update_hostmask(hostmask_dict) return nickobj def process_line(self, line): prefix, command, params = utils.parse_irc_message(line.rstrip('\r\n')) nickobj = self.get_nick(prefix) print nickobj, command, params command = command.upper() if self.__class__.command_received_event.invoke(self, command=command, nickobj=nickobj, params=params): return self.handle_unknown_command(nickobj, command, params) def send_line(self, line): self._line_writer.write_line(line) def send_message(self, command, *parameter_list, **prefix): self.send_line(utils.format_irc_message(command, *parameter_list, **prefix)) def handle_connection_made(self): self._registration_timeout = Timer(30, self._registration_timeout_timer) self._registration_timeout.start() def handle_unknown_command(self, command, nickobj, params): pass def register_user(self): self._registration_timeout.cancel() self._registration_timeout = None self.registered = True self.__class__.registration_event.invoke(self) def _registration_timeout_timer(self): self.handle_registration_timeout() def handle_registration_timeout(self): self.close('Registration timeout detected.')
def handle_connection_made(self): self._registration_timeout = Timer(30, self._registration_timeout_timer) self._registration_timeout.start()