irc

an Irc object handles the connection to the irc server .. receiving, sending, connect and reconnect code.

class fbf.drivers.irc.irc.Irc(cfg=None, users=None, plugs=None, *args, **kwargs)

Bases: fbf.lib.botbase.BotBase

the irc class, provides interface to irc related stuff.

action(printto, what, event=None, *args, **kwargs)

do action.

bind()
broadcast(txt)

broadcast txt to all joined channels.

close()

close the connection.

connect(reconnect=True)

connect to server/port using nick .. connect can timeout so catch exception .. reconnect if enabled.

ctcp(printto, what)

send ctcp privmsg.

ctcpreply(printto, what)

send ctcp notice.

delop(channel, who)

de-op user.

donick(nick, setorig=False, save=False, whois=False)

change nick .. optionally set original nick and/or save to config.

doop(channel, who)

give ops.

fakein(txt)

do a fake ircevent.

handle_001(ievent)

we are connected.

handle_401(ievent)

handle 401 .. nick not available.

handle_432(ievent)

erroneous nick.

handle_433(ievent)

handle nick already taken.

handle_465(ievent)

we are banned.. exit the bot.

handle_700(ievent)

handle 700 .. encoding request of the server.

handle_ctcp(ievent)

handle client to client request .. version and ping.

handle_error(ievent)

show error.

handle_ievent(ievent)

handle ircevent .. dispatch to ‘handle_command’ method.

handle_notice(ievent)

handle notice event .. check for version request.

handle_ping(ievent)

send pong response.

handle_pong(ievent)

set pongcheck on received pong.

handle_privmsg(ievent)

check if msg is ctcp or not .. return 1 on handling.

join(channel, password=None)

join channel with optional password.

logon()

log on to the network.

names(channel)

send names query.

normalize(what)
notice(printto, what)

send notice.

outnocb(printto, what, how='msg', *args, **kwargs)
part(channel)

leave channel.

ping()

ping the irc server.

privmsg(printto, what)

send privmsg to irc server.

quit(reason='http://github.com/feedbackflow/fbfbot & http:///docs/fbfbot')

send quit message.

save()

save state data.

send(txt)

send text to irc server.

sendraw(txt)

send raw text to the server.

shutdown()

shutdown the bot.

voice(channel, who)

give voice.

who(who)

send who query.

whois(who)

send whois query.

CODE

# fbf/socklib/irc/irc.py
#
#

"""
    an Irc object handles the connection to the irc server .. receiving,
    sending, connect and reconnect code.

"""

fbf imports

from fbf.utils.exception import handle_exception
from fbf.utils.generic import toenc, fromenc
from fbf.utils.generic import getrandomnick, strippedtxt
from fbf.utils.generic import fix_format, splittxt, uniqlist
from fbf.utils.locking import lockdec, lock_object, release_object
from fbf.lib.botbase import BotBase
from fbf.lib.threads import start_new_thread, threaded
from fbf.utils.pdod import Pdod
from fbf.lib.channelbase import ChannelBase
from fbf.lib.morphs import inputmorphs, outputmorphs
from fbf.lib.exit import globalshutdown
from fbf.lib.config import Config, getmainconfig

fbf.irc imports

from .ircevent import IrcEvent

basic imports

import time
import _thread
import socket
import threading
import os
import queue
import random
import logging
import types
import re
import select

locks

outlock = _thread.allocate_lock()
outlocked = lockdec(outlock)

exceptions

class Irc(BotBase):

    """ the irc class, provides interface to irc related stuff. """

    def __init__(self, cfg=None, users=None, plugs=None, *args, **kwargs):
        BotBase.__init__(self, cfg, users, plugs, *args, **kwargs)
        BotBase.setstate(self)
        self.type = 'irc'
        self.fsock = None
        self.oldsock = None
        self.sock = None
        self.reconnectcount = 0
        self.pongcheck = 0
        self.nickchanged = False
        self.noauto433 = False
        if self.state:
            if 'alternick' not in self.state: self.state['alternick'] = self.cfg['alternick']
            if 'no-op' not in self.state: self.state['no-op'] = []
        self.nicks401 = []
        self.cfg.port = self.cfg.port or 6667
        self.connecttime = 0
        self.encoding = 'utf-8'
        self.blocking = 1
        self.lastoutput = 0
        self.splitted = []
        if not self.cfg.server: self.cfg.server = self.cfg.host or "localhost"
        assert self.cfg.port
        assert self.cfg.server

    def _raw(self, txt):
        """ send raw text to the server. """
        if not txt or self.stopped or not self.sock:
            logging.debug("%s - bot is stopped .. not sending." % self.cfg.name)
            return 0
        try:
            self.lastoutput = time.time()
            itxt = bytes(txt + "\n", self.encoding or "utf-8")
            if not self.sock: logging.debug("%s - socket disappeared - not sending." % self.cfg.name) ; return
            if not txt.startswith("PONG"): logging.warn("> %s (%s)" % (itxt, self.cfg.name))
            else: logging.info("> %s (%s)" % (itxt, self.cfg.name))
            if 'ssl' in self.cfg and self.cfg['ssl']: self.sock.write(itxt)
            else: self.sock.send(itxt[:502])
        except Exception as ex: handle_exception() ; logging.error("%s - can't send: %s" % (self.cfg.name, str(ex)))

    def _connect(self):
        """ connect to server/port using nick. """
        self.stopped = False
        self.connecting = True
        self.connectok.clear()
        if self.cfg.ipv6:
            self.oldsock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
        else:
            self.oldsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        assert self.oldsock
        assert self.cfg.server
        assert self.cfg.port
        server = self.bind()
        logging.warn('connecting to %s - %s - %s (%s)' % (server, self.cfg.server, self.cfg.port, self.cfg.name))
        self.oldsock.settimeout(30)
        self.oldsock.connect((server, int(str(self.cfg.port))))
        self.blocking = 1
        self.oldsock.setblocking(self.blocking)
        logging.warn('connected! (%s)' % self.cfg.name)
        self.connected = True
        self.fsock = self.oldsock.makefile("r")
        if self.blocking:
            socktimeout = self.cfg['socktimeout']
            if not socktimeout:
                socktimeout = 301.0
            else:
                socktimeout = float(socktimeout)
            self.oldsock.settimeout(socktimeout)
        if 'ssl' in self.cfg and self.cfg['ssl']:
            logging.warn('ssl enabled (%s)' % self.cfg.name)
            self.sock = socket.ssl(self.oldsock)
        else: self.sock = self.oldsock
        try:
            self.outputlock.release()
        except _thread.error:
            pass
        self.connecttime = time.time()
        return True

    def bind(self):
        server = self.cfg.server
        elite = self.cfg['bindhost'] or getmainconfig()['bindhost']
        if elite:
            logging.warn("trying to bind to %s" % elite)
            try:
                self.oldsock.bind((elite, 0))
            except socket.gaierror:
                logging.debug("%s - can't bind to %s" % (self.cfg.name, elite))
                if not server:
                    try: socket.inet_pton(socket.AF_INET6, self.cfg.server)
                    except socket.error: pass
                    else: server = self.cfg.server
                if not server:
                    try: socket.inet_pton(socket.AF_INET, self.cfg.server)
                    except socket.error: pass
                    else: server = self.cfg.server
                if not server:
                    ips = []
                    try:
                        for item in socket.getaddrinfo(self.cfg.server, None):
                            if item[0] in [socket.AF_INET, socket.AF_INET6] and item[1] == socket.SOCK_STREAM:
                                ip = item[4][0]
                                if ip not in ips: ips.append(ip)
                    except socket.error: pass
                    else: server = random.choice(ips)
        return server

    def _readloop(self):
        """ loop on the socketfile. """
        self.stopreadloop = False
        self.stopped = False
        doreconnect = True
        timeout = 1
        logging.debug('%s - starting readloop' % self.cfg.name)
        prevtxt = ""
        while not self.stopped and not self.stopreadloop and self.sock and self.fsock:
            try:
                time.sleep(0.01)
                if 'ssl' in self.cfg and self.cfg['ssl']: intxt = inputmorphs.do(self.sock.read()).split('\n')
                else: intxt = inputmorphs.do(self.fsock.readline()).split('\n')
                if self.stopreadloop or self.stopped:
                    doreconnect = 0
                    break
                if intxt == ["",]:
                    logging.error("remote disconnected")
                    doreconnect = 1
                    break
                if prevtxt:
                    intxt[0] = prevtxt + intxt[0]
                    prevtxt = ""
                if intxt[-1] != '':
                    prevtxt = intxt[-1]
                    intxt = intxt[:-1]
                for r in intxt:
                    if not r: continue
                    try:
                        r = strippedtxt(r.rstrip(), ["\001", "\002", "\003"])
                        rr = str(fromenc(r.rstrip(), self.encoding))
                    except UnicodeDecodeError:
                        logging.warn("decode error - ignoring (%s)" % self.cfg.name)
                        continue
                    if not rr: continue
                    res = rr
                    try:
                        ievent = IrcEvent().parse(self, res)
                    except Exception as ex:
                        handle_exception()
                        continue
                    try:
                        if int(ievent.cmnd) > 400: logging.error("< %s - %s" % (res, self.cfg.name))
                        elif int(ievent.cmnd) >= 300: logging.info("< %s - %s" % (res, self.cfg.name))
                    except ValueError:
                        if not res.startswith("PING") and not res.startswith("NOTICE"): logging.warn("< %s - %s" % (res, self.cfg.name))
                        else: logging.info("< %s - %s" % (res, self.cfg.name))
                    if ievent: self.handle_ievent(ievent)
                    timeout = 1
            except UnicodeError:
                handle_exception()
                continue
            except socket.timeout as ex:
                logging.warn("socket timeout (%s)" % self.cfg.name)
                self.error = str(ex)
                if self.stopped or self.stopreadloop: break
                timeout += 1
                if timeout > 2:
                    doreconnect = 1
                    logging.warn('no pong received (%s)' % self.cfg.name)
                    break
                pingsend = self.ping()
                if not pingsend:
                    doreconnect = 1
                    break
                continue
            except socket.sslerror as ex:
                self.error = str(ex)
                if self.stopped or self.stopreadloop: break
                if not 'timed out' in str(ex):
                    handle_exception()
                    doreconnect = 1
                    break
                timeout += 1
                if timeout > 2:
                    doreconnect = 1
                    logging.warn('no pong received (%s)' % self.cfg.name)
                    break
                logging.warn("socket timeout (%s)" % self.cfg.name)
                pingsend = self.ping()
                if not pingsend:
                    doreconnect = 1
                    break
                continue
            except IOError as ex:
                self.error = str(ex)
                if self.blocking and 'temporarily' in str(ex):
                    logging.warn("iorror: %s (%s)" % (self.error, self.cfg.name))
                    time.sleep(1)
                    continue
                if not self.stopped:
                    logging.error('connecting error: %s (%s)' % (str(ex), self.cfg.name))
                    handle_exception()
                    doreconnect = 1
                break
            except socket.error as ex:
                self.error = str(ex)
                if self.blocking and 'temporarily' in str(ex):
                    logging.warn("ioerror: %s (%s)" % (self.error, self.cfg.name))
                    time.sleep(0.5)
                    continue
                if not self.stopped:
                    logging.error('connecting error: %s (%s)' % (str(ex), self.cfg.name))
                    doreconnect = 1
                break
            except Exception as ex:
                self.error = str(ex)
                if self.stopped or self.stopreadloop:
                    break
                logging.error("%s - error in readloop: %s" % (self.cfg.name, str(ex)))
                doreconnect = 1
                break
        logging.debug('%s - readloop stopped - %s' % (self.cfg.name, self.error))
        self.connectok.clear()
        self.connected = False
        if doreconnect and not self.stopped:
            time.sleep(2)
            self.reconnect()

    def logon(self):
        """ log on to the network. """
        time.sleep(2)
        if self.cfg.password:
            logging.debug('%s - sending password' % self.cfg.name)
            self._raw("PASS %s" % self.cfg.password)
        logging.warn('registering with %s using nick %s (%s)' % (self.cfg.server, self.cfg.nick, self.cfg.name))
        logging.warn('%s - this may take a while' % self.cfg.name)
        username = self.cfg.username or "fbfbot"
        realname = self.cfg.realname or "fbfbot"
        time.sleep(1)
        self._raw("NICK %s" % self.cfg.nick)
        time.sleep(1)
        self._raw("USER %s localhost %s :%s" % (username, self.cfg.server, realname))

    def _onconnect(self):
        """ overload this to run after connect. """
        on = self.cfg.onconnect
        logging.debug("onconnect is %s" % on)
        if on: time.sleep(2) ; self._raw(on)
        m = self.cfg.servermodes
        if m:
            time.sleep(2)
            logging.debug("sending servermodes %s" % m)
            self._raw("MODE %s %s" % (self.cfg.nick, m))

    def _resume(self, data, botname, reto=None):
        """ resume to server/port using nick. """
        try:
            if data['ssl']:
                self.exit()
                time.sleep(3)
                self.start()
                return 1
        except KeyError:
            pass
        self.stopped = False
        try:
            fd = int(data['fd'])
        except (KeyError, TypeError, ValueError):
            fd = None
            logging.error("%s - can't determine file descriptor" % self.cfg.name)
            print(data.tojson())
            return 0
        logging.warn("resume - file descriptor is %s (%s)" % (fd, data.name))
        # create socket
        if self.cfg.ipv6: self.oldsock = socket.fromfd(fd , socket.AF_INET6, socket.SOCK_STREAM)
        else: self.oldsock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
        assert self.oldsock
        self.oldsock.settimeout(30)
        self.fsock = self.oldsock.makefile("r")
        self.oldsock.setblocking(self.blocking)
        if self.blocking:
            socktimeout = self.cfg['socktimeout']
            if not socktimeout: socktimeout = 301.0
            else: socktimeout = float(socktimeout)
            self.oldsock.settimeout(socktimeout)
        self.sock = self.oldsock
        self.nickchanged = 0
        self.connecting = False
        time.sleep(2)
        self._raw('PING :RESUME %s' % str(time.time()))
        self.dostart(self.cfg.name, self.type)
        self.connectok.set()
        self.connected = True
        self.reconnectcount = 0
        if reto: self.say(reto, 'rebooting done')
        logging.warn("rebooting done (%s)" % self.cfg.name)
        return True

    def outnocb(self, printto, what, how='msg', *args, **kwargs):
        what = fix_format(what)
        what = self.normalize(what)
        if 'socket' in repr(printto) and self.sock:
            printto.send(bytearray(what + "\n", self.encoding or "utf-8"))
            return True
        if not printto: self._raw(what)
        elif how == 'notice': self.notice(printto, what)
        elif how == 'ctcp': self.ctcp(printto, what)
        else: self.privmsg(printto, what)

    def broadcast(self, txt):
        """ broadcast txt to all joined channels. """
        for i in self.state['joinedchannels']:
            self.say(i, txt, speed=1)

    def normalize(self, what):
        txt = strippedtxt(what, ["\001", "\002", "\003"])
        txt = txt.replace("<b>", "\002")
        txt = txt.replace("</b>", "\002")
        txt = txt.replace("<i>", "\0032")
        txt = txt.replace("</i>", "\003")
        txt = txt.replace("<li>", "\0033*\003 ")
        txt = txt.replace("</li>", "")
        txt = txt.replace("<br><br>", " - ")
        txt = txt.replace("<br>", " [!] ")
        txt = txt.replace("&lt;b&gt;", "\002")
        txt = txt.replace("&lt;/b&gt;", "\002")
        txt = txt.replace("&lt;i&gt;", "\003")
        txt = txt.replace("&lt;/i&gt;", "")
        txt = txt.replace("&lt;h2&gt;", "\0033")
        txt = txt.replace("&lt;/h2&gt;", "\003")
        txt = txt.replace("&lt;h3&gt;", "\0034")
        txt = txt.replace("&lt;/h3&gt;", "\003")
        txt = txt.replace("&lt;li&gt;", "\0034")
        txt = txt.replace("&lt;/li&gt;", "\003")
        return txt

    def save(self):
        """ save state data. """
        if self.state: self.state.save()

    def connect(self, reconnect=True):
        """
            connect to server/port using nick .. connect can timeout so catch
            exception .. reconnect if enabled.
        """
        res = self._connect()
        logging.info("%s - starting logon" % self.cfg.name)
        self.logon()
        time.sleep(1)
        self.nickchanged = 0
        self.reconnectcount = 0
        self._onconnect()
        self.connected = True
        self.connecting = False
        return res

    def shutdown(self):
        """ shutdown the bot. """
        logging.warn('shutdown (%s)' % self.cfg.name)
        self.stopoutputloop = 1
        #self.close()
        self.connecting = False
        self.connected = False
        self.connectok.clear()

    def close(self):
        """ close the connection. """
        try:
            if 'ssl' in self.cfg and self.cfg['ssl']: self.oldsock.shutdown(2)
            else: self.sock.shutdown(2)
        except:
            pass
        try:
            if 'ssl' in self.cfg and self.cfg['ssl']: self.oldsock.close()
            else: self.sock.close()
            self.fsock.close()
        except:
            pass

    def handle_pong(self, ievent):
        """ set pongcheck on received pong. """
        logging.debug('%s - received server pong' % self.cfg.name)
        self.pongcheck = 1

    def sendraw(self, txt):
        """ send raw text to the server. """
        if self.stopped: return
        logging.debug('%s - sending %s' % (self.cfg.name, txt))
        self._raw(txt)

    def fakein(self, txt):
        """ do a fake ircevent. """
        if not txt: return
        logging.debug('%s - fakein - %s' % (self.cfg.name, txt))
        self.handle_ievent(IrcEvent().parse(self, txt))

    def donick(self, nick, setorig=False, save=False, whois=False):
        """ change nick .. optionally set original nick and/or save to config.  """
        if not nick: return
        self.noauto433 = True
        nick = nick[:16]
        self._raw('NICK %s\n' % nick)
        self.noauto433 = False

    def join(self, channel, password=None):
        """ join channel with optional password. """
        if not channel: return
        if password:
            self._raw('JOIN %s %s' % (channel, password))
        else: self._raw('JOIN %s' % channel)
        if self.state:
            if channel not in self.state.data.joinedchannels:
                self.state.data.joinedchannels.append(channel)
                self.state.save()

    def part(self, channel):
        """ leave channel. """
        if not channel: return
        self._raw('PART %s' % channel)
        try:
            self.state.data['joinedchannels'].remove(channel)
            self.state.save()
        except (KeyError, ValueError) as ex:
            logging.error("error removing %s from joinedchannels: %s" % (channel, str(ex)))
        if self.cfg.channels and channel in self.cfg.channels: self.cfg.channels.remove(channel) ; self.cfg.save()

    def who(self, who):
        """ send who query. """
        if not who: return
        self.putonqueue(4, None, 'WHO %s' % who.strip())

    def names(self, channel):
        """ send names query. """
        if not channel: return
        self.putonqueue(4, None, 'NAMES %s' % channel)

    def whois(self, who):
        """ send whois query. """
        if not who: return
        self.putonqueue(4, None, 'WHOIS %s' % who)

    def privmsg(self, printto, what):
        """ send privmsg to irc server. """
        if not printto or not what: return
        self.send('PRIVMSG %s :%s' % (printto, what))

    #@outlocked
    def send(self, txt):
        """ send text to irc server. """
        if not txt: return
        if self.stopped: return
        try:
            #lock_object(self)
            now = time.time()
            txt = txt.rstrip()
            self._raw(txt)
            if self.cfg.sleepsec: timetosleep = self.cfg.sleepsec - (now - self.lastoutput)
            else: timetosleep = 4 - (now - self.lastoutput)
            if timetosleep > 0 and not self.cfg.nolimiter and not (time.time() - self.connecttime < 5):
                logging.debug('%s - flood protect' % self.cfg.name)
                time.sleep(timetosleep)
        except Exception as ex:
            logging.error('%s - send error: %s' % (self.cfg.name, str(ex)))
            handle_exception()
        #finally: release_object(self)

    def voice(self, channel, who):
        """ give voice. """
        if not channel or not who: return
        self.putonqueue(9, None, 'MODE %s +v %s' % (channel, who))

    def doop(self, channel, who):
        """ give ops. """
        if not channel or not who: return
        self._raw('MODE %s +o %s' % (channel, who))

    def delop(self, channel, who):
        """ de-op user. """
        if not channel or not who: return
        self._raw('MODE %s -o %s' % (channel, who))

    def quit(self, reason='http://github.com/feedbackflow/fbfbot & http:///docs/fbfbot'):
        """ send quit message. """
        logging.warn('sending quit - %s (%s)' % (reason, self.cfg.name))
        self._raw('QUIT :%s' % reason)

    def notice(self, printto, what):
        """ send notice. """
        if not printto or not what: return
        self.putonqueue(3, None, 'NOTICE %s :%s' % (printto, what))

    def ctcp(self, printto, what):
        """ send ctcp privmsg. """
        if not printto or not what: return
        self.putonqueue(3, None, "PRIVMSG %s :\001%s\001" % (printto, what))

    def ctcpreply(self, printto, what):
        """ send ctcp notice. """
        if not printto or not what: return
        self.putonqueue(3, None, "NOTICE %s :\001%s\001" % (printto, what))

    def action(self, printto, what, event=None, *args, **kwargs):
        """ do action. """
        if not printto or not what: return
        self.putonqueue(9, None, "PRIVMSG %s :\001ACTION %s\001" % (printto, what))

    def handle_ievent(self, ievent):
        """ handle ircevent .. dispatch to 'handle_command' method. """
        try:
            if ievent.cmnd == 'JOIN' or ievent.msg:
                if ievent.nick in self.nicks401:
                    self.nicks401.remove(ievent.nick)
                    logging.debug('%s - %s joined .. unignoring' % (self.cfg.name, ievent.nick))
            ievent.bind(self)
            method = getattr(self,'handle_' + ievent.cmnd.lower())
            if method:
                try:
                    method(ievent)
                except:
                    handle_exception()
        except AttributeError:
            pass

    def handle_432(self, ievent):
        """ erroneous nick. """
        self.handle_433(ievent)

    def handle_433(self, ievent):
        """ handle nick already taken. """
        if self.noauto433:
            return
        nick = ievent.arguments[1]
        alternick = self.state['alternick']
        if alternick and not self.nickchanged:
            logging.debug('%s - using alternick %s' % (self.cfg.name, alternick))
            self.donick(alternick)
            self.nickchanged = 1
            return
        randomnick = getrandomnick()
        self._raw("NICK %s" % randomnick)
        self.cfg.wantnick = self.cfg.nick
        self.cfg.nick = randomnick
        logging.warn('ALERT: nick %s already in use/unavailable .. using randomnick %s (%s)' % (nick, randomnick, randomnick))
        self.nickchanged = 1

    def handle_ping(self, ievent):
        """ send pong response. """
        if not ievent.txt: logging.debug("no txt set") ; return
        self._raw('PONG :%s' % ievent.txt)

    def handle_001(self, ievent):
        """ we are connected.  """
        time.sleep(1)
        self._onconnect()
        self.connectok.set()
        self.connected = True
        self.whois(self.cfg.nick)

    def handle_privmsg(self, ievent):
        """ check if msg is ctcp or not .. return 1 on handling. """
        if ievent.txt and ievent.txt[0] == '\001':
            self.handle_ctcp(ievent)
            return 1

    def handle_notice(self, ievent):
        """ handle notice event .. check for version request. """
        if ievent.txt and ievent.txt.find('VERSION') != -1:
            from fbf.version import getversion
            self.say(ievent.nick, getversion(), None, 'notice')
            return 1

    def handle_ctcp(self, ievent):
        """ handle client to client request .. version and ping. """
        if ievent.txt.find('VERSION') != -1:
            from fbf.version import getversion
            self.ctcpreply(ievent.nick, 'VERSION %s' % getversion())
        if ievent.txt.find('PING') != -1:
            try:
                pingtime = ievent.txt.split()[1]
                pingtifbf = ievent.txt.split()[2]
                if pingtime:
                    self.ctcpreply(ievent.nick, 'PING ' + pingtime + ' ' + pingtifbf)
            except IndexError:
                pass

    def handle_error(self, ievent):
        """ show error. """
        txt = ievent.txt
        if 'Closing' in txt:
            if "banned" in txt.lower() or "-lined" in txt.lower():
                logging.error("WE ARE BANNED !! - %s - %s" % (self.cfg.server, txt))
                self.exit()
            else: logging.error("%s - %s" % (self.cfg.name, txt))
        else: logging.error("%s - %s - %s" % (self.cfg.name.upper(), ", ".join(ievent.arguments[1:]), txt))

    def ping(self):
        """ ping the irc server. """
        logging.debug('%s - sending ping' % self.cfg.name)
        try:
            self._raw('PING :%s' % self.cfg.server)
            return 1
        except Exception as ex:
            logging.warn("can't send ping: %s (%s)" % (str(ex), self.cfg.name))
            return 0

    def handle_401(self, ievent):
        """ handle 401 .. nick not available. """
        pass

    def handle_700(self, ievent):
        """ handle 700 .. encoding request of the server. """
        try:
            self.encoding = ievent.arguments[1]
            logging.warn('700 encoding now is %s (%s)' % (self.encoding, self.cfg.name))
        except:
            pass

    def handle_465(self, ievent):
        """ we are banned.. exit the bot. """
        self.exit()

Table Of Contents

Previous topic

channels

Next topic

ircevent

This Page