Пример #1
0
 def run(self):
     """
     Connect to the IRC server and wait for messages to send. If connection
     is lost, automatically reconnect.
     """
     while True:
         # Connect to IRC
         irc_sock = Irc(self.config)
         irc_sock.set_parser(IrcParser())
         try:
             irc_sock.connect()
         except IrcError as e:
             logging.error('IRC error: {0}'.format(e.value))
             time.sleep(1)
             continue
         # Send messages until disconnect
         while(True):
             out_msg = self.out_queue.get(block=True)
             out_str = 'PRIVMSG {0} : {1}\r\n'.format(
                 self.config['irc']['channel'],
                 out_msg)
             timeout = self.config['irc']['send_timeout']
             sent_success = irc_sock.send_message(out_str, timeout=timeout)
             if not sent_success:
                 logging.warning(
                     'IRC: failed to send chat message {0}'.format(out_str))
                 break
         GLib.idle_add(self.glib_func, ['DISCONNECTED'])
Пример #2
0
    def run(self):
        """
        Connect to the IRC server and send events to the GUI. This funtion is
        an endless loop that never exits, as it waits for a message before
        sending a signal to the GUI. If the connection to the server is lost,
        the connection is automatically re-established.

        In addition to the events defined by Irc, the following events are
        also sent:
        - CONNECTING: ['CONNECTING']
            Connecting to the server.
        - CONNECTED: ['CONNECTED']
            Connected to the server.
        - DISCONNECTED: ['DISCONNECTED']
            Connection to the server lost.
        """
        self.glib_func = self.func_queue.get()
        while True:
            # Connect to IRC
            GLib.idle_add(self.glib_func, ['CONNECTING'])
            irc_sock = Irc(self.config)
            irc_sock.set_parser(IrcParser())
            try:
                irc_sock.connect('TWITCHCLIENT 1\r\n')
            except IrcError as e:
                logging.error('IRC error: {0}'.format(e.value))
                time.sleep(1)
                continue
            GLib.idle_add(self.glib_func, ['CONNECTED'])
            # Receive messages until disconnect
            try:
                while(True):
                    if irc_sock.receive_message(timeout=None):
                        messages = irc_sock.parse_message()
                        for msg in messages:
                            GLib.idle_add(self.glib_func, msg)
            except IrcError:
                pass
            GLib.idle_add(self.glib_func, ['DISCONNECTED'])
Пример #3
0
class Client(object):
    """An IRC Client, designed to be pluggable"""

    def __init__(self, name, config):
        self.name = name
        self.config = config  # Overall config
        self.options = config.clients[name]  # Client options
        self.publisher = Publisher()
        # Initialize Irc connection object
        self.server = config.servers[self.options['server']]
        self.irc = Irc(self.server, self.publisher)
        # Configuration
        self.nick = self.options['nick']
        self.stdio = StdIO()
        self.sending = Queue()
        self.receiving = Queue()
        # Plugins
        self.plugins = {}
        plugins = ['Base'] + self.options['plugins'].keys()
        [self.load_plugin(p) for p in plugins]
        self.instance = None

    def start(self):
        if self.instance is not None:
            raise
        self.publisher.subscribe(self.irc.sender, self.sending)
        self.publisher.subscribe(self.receiving, self.irc.receiver)
# TODO: Remove, debugging
        self.publisher.subscribe(self.stdio.output,
                self.irc.receiver, str)
        self.publisher.subscribe(self.stdio.output,
                self.irc.sender, str)
        from lib.irc import Msg
        self.publisher.subscribe(self.sending,
                self.stdio.input, Msg.from_msg)
        self.irc.connect()
        self.instance = gevent.spawn(self._event_loop)
        return self.instance

    def kill(self):
        """Completely close connection to server"""
        while not self.sending.empty():
            gevent.sleep(0.5)
        self.irc.kill()
# TODO: Remove, debugging
        self.publisher.unsubscribe(self.irc.sender, self.sending)
        self.publisher.unsubscribe(self.receiving, self.irc.receiver)
        self.publisher.unsubscribe(self.stdio.output,
            self.irc.receiver)
        self.publisher.unsubscribe(self.stdio.output,
            self.irc.sender)
        self.stdio.stop()
        self.receiving.put(FinishLoop)

    def load_plugin(self, plugin):
        if self._load_module(plugin):
            if hasattr(self.plugins[plugin], 'setup'):
                settings = None
                if plugin in self.config.plugins:
                    settings = self.config.plugins[plugin]
                botSettings = None
                if plugin in self.options['plugins']:
                    botSettings = self.options['plugins'][plugin]
                self.plugins[plugin].setup(settings, botSettings)

    def _event_loop(self):
        gevent.spawn(self.plugins['Base'].on_connect)
        for msg in self.receiving:
            if msg is FinishLoop:
                break
            for plugin in self.plugins.values():
                cmd = 'on_' + msg.cmd.lower()
                if hasattr(plugin, cmd):
                    func = getattr(plugin, cmd)
                    gevent.spawn(func, msg)
                if msg.ctcp is not None:
                    cmd = 'on_ctcp_' + msg.ctcp[0].lower()
                    if hasattr(plugin, cmd):
                        func = getattr(plugin, cmd)
                        gevent.spawn(func, msg)

    def _load_module(self, plugin):
        try:
            p_name = 'plugin.' + plugin.lower()
            p = __import__(p_name, fromlist=[plugin], level=-1)
            self.plugins[plugin] = getattr(p, plugin)(self)
            return True
        except ImportError as e:
            print str(e)
            return False