Source code for irc3.plugins.core

# -*- coding: utf-8 -*-
from irc3 import event
from irc3 import rfc
__doc__ = '''
==============================================
:mod:`irc3.plugins.core` Core plugin
==============================================

Core events

.. autoclass:: Core
   :members:

..
    >>> from irc3.testing import IrcBot

Usage::

    >>> bot = IrcBot()
    >>> bot.include('irc3.plugins.core')
'''


[docs]class Core: def __init__(self, bot): self.bot = bot self.timeout = int(self.bot.config.get('timeout')) self.max_lag = int(self.bot.config.get('max_lag')) self.reconn_handle = None self.ping_handle = None self.nick_handle = None self.before_connect_events = [ event(rfc.CONNECTED, self.connected), event(r"^:\S+ 005 \S+ (?P<data>.+) :\S+.*", self.set_config), ] def connection_made(self, client=None): # handle server config config = self.bot.defaults['server_config'].copy() self.bot.config['server_config'] = config self.bot.detach_events(*self.before_connect_events) self.bot.attach_events(insert=True, *self.before_connect_events) # ping/ping self.connection_made_at = self.bot.loop.time() self.pong(event='CONNECT', data='')
[docs] def connected(self, **kwargs): """triger the server_ready event""" self.bot.log.info('Server config: %r', self.bot.server_config) # recompile when I'm sure of my nickname self.bot.config['nick'] = kwargs['me'] self.bot.recompile() # Let all plugins know that server can handle commands self.bot.notify('server_ready') # detach useless events self.bot.detach_events(*self.before_connect_events)
def reconnect(self): # pragma: no cover self.bot.log.info( "We're waiting a ping for too long. Trying to reconnect...") self.bot.loop.call_soon( self.bot.protocol.connection_lost, 'No pong reply' ) self.pong(event='RECONNECT', data='')
[docs] @event(rfc.PONG) def pong(self, event='PONG', data='', **kw): # pragma: no cover """P0NG/PING""" self.bot.log.debug('%s ping-pong (%s)', event, data) if self.reconn_handle is not None: self.reconn_handle.cancel() self.reconn_handle = self.bot.loop.call_later(self.timeout, self.reconnect) if self.ping_handle is not None: self.ping_handle.cancel() self.ping_handle = self.bot.loop.call_later( self.timeout - self.max_lag, self.bot.send, 'PING :%s' % int(self.bot.loop.time()))
[docs] @event(rfc.PING) def ping(self, data): """PING reply""" self.bot.send('PONG :' + data) self.pong(event='PING', data=data)
[docs] @event(rfc.NEW_NICK) def recompile(self, nick=None, new_nick=None, **kw): """recompile regexp on new nick""" if self.bot.nick == nick.nick: self.bot.config['nick'] = new_nick self.bot.recompile()
[docs] @event(rfc.ERR_NICK) def badnick(self, me=None, nick=None, **kw): """Use alt nick on nick error""" if me == '*': self.bot.set_nick(self.bot.nick + '_') self.bot.log.debug('Trying to regain nickname in 30s...') self.nick_handle = self.bot.loop.call_later( 30, self.bot.set_nick, self.bot.original_nick)
[docs] def set_config(self, data=None, **kwargs): """Store server config""" config = self.bot.config['server_config'] for opt in data.split(' '): if '=' in opt: opt, value = opt.split('=', 1) else: value = True if opt.isupper(): config[opt] = value