an ircevent is extracted from the IRC string received from the server.
Bases: gozerbot.eventbase.EventBase
represents an IRC event.
parse raw string into ircevent.
send reply to the channel the event originated from.
create ievent.args and ievent.rest .. this is needed because ircevents might be created outside the parse() function.
# gozerbot/ircevent.py # # # http://www.irchelp.org/irchelp/rfc/rfc2812.txt """ an ircevent is extracted from the IRC string received from the server. """ __status__ = "seen"
from gozerbot.utils.log import rlog from gozerbot.utils.generic import fix_format, toenc, fromenc, stripident from gozerbot.eventbase import EventBase, makeargrest from gozerbot.stats import stats from gozerbot.config import config
import time import re import types import copy
cpy = copy.deepcopy try: dotchars = config['dotchars'] if not dotchars: dotchars = ' .. ' except KeyError: dotchars = ' .. '
def makeargrest(ievent): """ create ievent.args and ievent.rest .. this is needed because ircevents might be created outside the parse() function. """ try: ievent.args = ievent.txt.split()[1:] except ValueError: ievent.args = [] try: cmnd, ievent.rest = ievent.txt.split(' ', 1) except ValueError: ievent.rest = "" ievent.command = ievent.txt.split(' ')[0]
class Ircevent(EventBase): """ represents an IRC event. """ def __copy__(self): return Ircevent(self) def __deepcopy__(self, bla): return Ircevent(self) def toirc(self): pass def parse(self, bot, rawstr): """ parse raw string into ircevent. """ self.bot = bot stats.up('events', bot.name) bot.nrevents += 1 rawstr = rawstr.rstrip() splitted = re.split('\s+', rawstr) if not rawstr[0] == ':': splitted.insert(0, ":none!none@none") rawstr = ":none!none@none " + rawstr self.prefix = splitted[0][1:] nickuser = self.prefix.split('!') if len(nickuser) == 2: self.nick = nickuser[0] stats.up('events', self.nick) if self.bot.cfg['stripident'] or config['stripident']: self.userhost = stripident(nickuser[1]) else: self.userhost = nickuser[1] self.cmnd = splitted[1] self.cbtype = self.cmnd stats.up('events', self.cmnd) if pfc.has_key(self.cmnd): self.arguments = splitted[2:pfc[self.cmnd]+2] txtsplit = re.split('\s+', rawstr, pfc[self.cmnd]+2) self.txt = txtsplit[-1] else: self.arguments = splitted[2:] if self.arguments: self.target = self.arguments[0] self.postfix = ' '.join(self.arguments) if self.target and self.target.startswith(':'): self.txt = ' '.join(self.arguments) if self.txt and self.txt[0] == ":": self.txt = self.txt[1:] rlog(0, 'ircevent',"%s %s %s" % (self.cmnd, self.arguments, self.txt)) if self.cmnd == 'PING': self.speed = 10 if self.cmnd == 'PRIVMSG': self.channel = self.arguments[0] if '\001' in self.txt: self.isctcp = True elif self.cmnd == 'JOIN' or self.cmnd == 'PART': if self.arguments: self.channel = self.arguments[0] else: self.channel = self.txt elif self.cmnd == 'MODE': self.channel = self.arguments[0] elif self.cmnd == 'TOPIC': self.channel = self.arguments[0] elif self.cmnd == 'KICK': self.channel = self.arguments[0] elif self.cmnd == '353': self.channel = self.arguments[2] elif self.cmnd == '324': self.channel = self.arguments[1] if self.userhost: self.ruserhost = self.userhost self.stripped = self.userhost self.user = stripident(self.userhost).split('@')[0] self.origtxt = self.txt self.channel = self.channel.strip() stats.up('events', self.channel) self.origchannel = self.channel rlog(-1, 'ircevent', self) try: nr = int(self.cmnd) if nr > 399: rlog(10, bot.name + '.error', '%s: %s %s' % (self.cmnd, self.arguments, self.txt)) except ValueError: pass return self def reply(self, txt, result=None, nick=None, dot=False, nritems=False, nr=False, fromm=None, private=False, how=''): """ send reply to the channel the event originated from. """ if result == []: return stats.up('events', 'replies') if not how: try: how = self.options['--how'] except KeyError: how = 'msg' restxt = "" splitted = [] if type(result) == types.DictType: for i, j in result.iteritems(): if type(j) == types.ListType: try: z = dotchars.join(j) except TypeError: z = unicode(j) else: z = j res = "%s: %s" % (i, z) splitted.append(res) if dot == True: restxt += "%s%s" % (res, dotchars) else: restxt += "%s %s" % (dot or ' ', res) if restxt: if dot == True: restxt = restxt[:-6] elif dot: restxt = restxt[:-len(dot)] lt = False # set if result is list if type(txt) == types.ListType and not result: result = txt origtxt = u"" lt = True else: origtxt = txt if result: lt = True if self.queues: for i in self.queues: if splitted: for item in splitted: i.put_nowait(item) elif lt: for j in result: i.put_nowait(j) elif restxt: i.put_nowait(restxt) else: i.put_nowait(txt) if self.onlyqueues: return if not self.bot: rlog(10, 'event', 'no bot defined in event') ; return pretxt = origtxt if lt and not restxt: res = [] for i in result: if type(i) == types.ListType or type(i) == types.TupleType: try: res.append(dotchars.join(i)) except TypeError: res.extend(i) else: res.append(i) result = res if nritems: if len(result) > 1: pretxt += "(%s items) .. " % len(result) txtlist = result if not nr is False: try: start = int(nr) except ValueError: start = 0 txtlist2 = [] teller = start for i in txtlist: txtlist2.append(u"%s) %s" % (teller, i)) teller += 1 txtlist = txtlist2 txtl = [] for item in txtlist: txtl.append(toenc(item)) txtlist = txtl if dot == True: restxt = dotchars.join(txtlist) elif dot: restxt = dot.join(txtlist) else: restxt = ' '.join(txtlist) if pretxt: try: restxt = pretxt + restxt except TypeError: rlog(10, 'eventbase', "can't add %s and %s" % (str(pretxt), str(restxt))) if self.filtered(restxt): return if self.cmnd == 'DCC' and self.sock: self.bot.say(self.sock, restxt, speed=self.speed, how=how) return if nick: self.bot.say(nick, restxt, fromm=nick, speed=self.speed, how=how) return if self.msg or private: self.bot.say(self.nick, restxt, fromm=self.nick, speed=self.speed, how=how) return silent = False channel = self.printto or self.channel try: silent = self.bot.channels[channel]['silent'] except (KeyError, TypeError): pass fromm = fromm or self.nick if silent: notice = False try: notice = self.bot.channels[channel]['notice'] except (KeyError, TypeError): pass if notice: self.bot.say(self.nick, restxt, how='notice', fromm=fromm, speed=self.speed) else: self.bot.say(self.nick, restxt, fromm=fromm, speed=self.speed, how=how) return if self.printto: self.bot.say(self.printto, restxt, fromm=fromm, speed=self.speed, how=how) ; return else: self.bot.say(self.channel, restxt, fromm=fromm, speed=self.speed, how=how)
# postfix count aka how many arguments pfc = {} pfc['NICK'] = 0 pfc['QUIT'] = 0 pfc['SQUIT'] = 1 pfc['JOIN'] = 0 pfc['PART'] = 1 pfc['TOPIC'] = 1 pfc['KICK'] = 2 pfc['PRIVMSG'] = 1 pfc['NOTICE'] = 1 pfc['SQUERY'] = 1 pfc['PING'] = 0 pfc['ERROR'] = 0 pfc['AWAY'] = 0 pfc['WALLOPS'] = 0 pfc['INVITE'] = 1 pfc['001'] = 1 pfc['002'] = 1 pfc['003'] = 1 pfc['004'] = 4 pfc['005'] = 15 pfc['302'] = 1 pfc['303'] = 1 pfc['301'] = 2 pfc['305'] = 1 pfc['306'] = 1 pfc['311'] = 5 pfc['312'] = 3 pfc['313'] = 2 pfc['317'] = 3 pfc['318'] = 2 pfc['319'] = 2 pfc['314'] = 5 pfc['369'] = 2 pfc['322'] = 3 pfc['323'] = 1 pfc['325'] = 3 pfc['324'] = 4 pfc['331'] = 2 pfc['332'] = 2 pfc['341'] = 3 pfc['342'] = 2 pfc['346'] = 3 pfc['347'] = 2 pfc['348'] = 3 pfc['349'] = 2 pfc['351'] = 3 pfc['352'] = 7 pfc['315'] = 2 pfc['353'] = 3 pfc['366'] = 2 pfc['364'] = 3 pfc['365'] = 2 pfc['367'] = 2 pfc['368'] = 2 pfc['371'] = 1 pfc['374'] = 1 pfc['375'] = 1 pfc['372'] = 1 pfc['376'] = 1 pfc['381'] = 1 pfc['382'] = 2 pfc['383'] = 5 pfc['391'] = 2 pfc['392'] = 1 pfc['393'] = 1 pfc['394'] = 1 pfc['395'] = 1 pfc['262'] = 3 pfc['242'] = 1 pfc['235'] = 3 pfc['250'] = 1 pfc['251'] = 1 pfc['252'] = 2 pfc['253'] = 2 pfc['254'] = 2 pfc['255'] = 1 pfc['256'] = 2 pfc['257'] = 1 pfc['258'] = 1 pfc['259'] = 1 pfc['263'] = 2 pfc['265'] = 1 pfc['266'] = 1 pfc['401'] = 2 pfc['402'] = 2 pfc['403'] = 2 pfc['404'] = 2 pfc['405'] = 2 pfc['406'] = 2 pfc['407'] = 2 pfc['408'] = 2 pfc['409'] = 1 pfc['411'] = 1 pfc['412'] = 1 pfc['413'] = 2 pfc['414'] = 2 pfc['415'] = 2 pfc['421'] = 2 pfc['422'] = 1 pfc['423'] = 2 pfc['424'] = 1 pfc['431'] = 1 pfc['432'] = 2 pfc['433'] = 2 pfc['436'] = 2 pfc['437'] = 2 pfc['441'] = 3 pfc['442'] = 2 pfc['443'] = 3 pfc['444'] = 2 pfc['445'] = 1 pfc['446'] = 1 pfc['451'] = 1 pfc['461'] = 2 pfc['462'] = 1 pfc['463'] = 1 pfc['464'] = 1 pfc['465'] = 1 pfc['467'] = 2 pfc['471'] = 2 pfc['472'] = 2 pfc['473'] = 2 pfc['474'] = 2 pfc['475'] = 2 pfc['476'] = 2 pfc['477'] = 2 pfc['478'] = 3 pfc['481'] = 1 pfc['482'] = 2 pfc['483'] = 1 pfc['484'] = 1 pfc['485'] = 1 pfc['491'] = 1 pfc['501'] = 1 pfc['502'] = 1 pfc['700'] = 2 # default event used to initialise events defaultevent = EventBase()