Ejemplo n.º 1
0
Archivo: irc.py Proyecto: BiohZn/sbncng
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.')
Ejemplo n.º 2
0
Archivo: irc.py Proyecto: BiohZn/sbncng
 def handle_connection_made(self):
     self._registration_timeout = Timer(30, self._registration_timeout_timer)
     self._registration_timeout.start()