This module implements the EventBase class from which all other events inherit.
Bases: gozerbot.xmpp.core.XMLDict
Base class for all events. Inherit from this.
check if resultlist is to be sent to the queues. if so do it.
copy in an event.
reply with the txt ‘done’.
see if txt if filtered on this event.
reconstruct the event from a jsonstring.
function to handler errors. .. overload this.
old compat function. use str() now.
create a response based on txt and result list.
show what arguments are missing.
parse raw string into event. overload this.
reply to event.
set ircevent compat attributes.
convert the event to a json string.
set arguments and rest attributes of an event.
# gozerbot/eventbase.py # # """ This module implements the EventBase class from which all other events inherit. """ __status__ = "seen"
from xmpp.core import XMLDict from utils.log import rlog from utils.generic import stripident, fix_format, fromenc, toenc from utils.lazydict import LazyDict from gozerbot.stats import stats from gozerbot.config import config
import time import re import types import copy
from simplejson import loads, dumps
cpy = copy.deepcopy
def makeargrest(event): """ set arguments and rest attributes of an event. """ try: event.args = event.txt.split()[1:] except ValueError: event.args = [] try: cmnd, event.rest = event.txt.split(' ', 1) except ValueError: event.rest = "" event.command = event.txt.split(' ')[0]
class EventBase(XMLDict): """ Base class for all events. Inherit from this. """ def __init__(self, event={}, bot=None): self.server = "" XMLDict.__init__(self) self.threaded = False self.onlyqueues = False self.orig = event # the original data .. SET BY HANDLER self.type = 'chat' # type of event self.cbtype = '' # callback type self.jabber = False # set if event is jabber event self.groupchat = False # set if event is groupchat self.botoutput = False # set if event is bot output self.cmnd = None # the event command self.prefix = u"" # txt before the command self.postfix = u"" # txt after the command self.target = u"" # target to give reponse to self.arguments = [] # arguments of event self.nick = u"" # nick of user originating the event self.user = u"" # user originating the event self.ruserhost = u"" # real userhost self.userhost = u"" # userhost that might change self.stripped = u"" # stripped JID self.resource = u"" # resource part of JID self.origin = u"" # source of the event self.origchannel = u"" # original channel self.channel = u"" # channel .. might change self.origtxt = u"" # original txt self.txt = u"" # text .. might change self.command = u"" # the bot command if any self.remoteout = u"" self.remotecmnd = False self.usercmnd = False self.alias = u"" # set to alias if one is used self.aliased = u"" # set if commadn is aliased self.time = time.time() # event creation time self.msg = False # set if event is a private message self.args = [] # arguments of command self.rest = u"" # txt following the command self.usercmnd = 0 # set if event is a command self.bot = bot # the bot where the event originated on self.sock = None # socket (set in DCC chat) self.allowqueue = True # allow event to be used in pipeline self.closequeue = True # cloase event queues when execution has ended self.inqueue = None # queue used as input in pipeline self.queues = [] # output queues (only used when set) self.printto = None # target to printto self.speed = 0 # speed with which this event needs to be processed self.groups = None # set if event triggers a RE callback self.cc = u"" # control character self.jid = None # JID of used originating the event self.jidchange = None # set is event changes jid self.conn = None # connection of bot originating the event self.denied = False # set if command is denied self.iscallback = False self.isresponse = False # set if event is a reponse self.isrelay = False self.isremote = False self.isdcc = False # set if event is DCC related self.isctcp = False # set if event is an ACTION self.options = LazyDict() # options dict on the event self.optionset = [] # list of options set self.filter = [] # filter list to use on output # xmpp stuff self.host = self.server self.xml = u"" self.realjid = u"" self.fromm = u"" self.to = u"" self.type = u"" self.id = 0 self.subject = u"" self.body = u"" self.error = u"" self.errorcode = u"" self.html = u"" self.thread = u"" self.x = {} if event: self.copyin(event) self.toirc() stats.up('events', 'created') def __copy__(self): return EventBase(self) def __deepcopy__(self, bla): return EventBase(self) def toirc(self): """ set ircevent compat attributes. """ self.jidchange = False self.cmnd = 'Message' try: self.resource = self.fromm.split('/')[1] except IndexError: pass self.channel = self['fromm'].split('/')[0] self.origchannel = self.channel self.nick = self.resource #try: # self.jid = bot.jids[self.channel][self.resource] # self.jidchange = True #except KeyError: # pass self.jid = self.fromm self.ruserhost = self.jid self.userhost = self.jid self.stripped = self.jid.split('/')[0] self.printto = self.channel self.target = self.printto for node in self.subelements: try: self.txt = node.body.data except (AttributeError, ValueError): continue self.origtxt = self.txt self.time = time.time() if self.type == 'groupchat': self.groupchat = True if self.jidchange: self.userhost = self.stripped else: self.groupchat = False self.userhost = self.stripped self.msg = not self.groupchat def copyin(self, ievent): """ copy in an event. """ self.update(ievent) if ievent.has_key('options'): self.options = dict(ievent.options) if ievent.has_key('queues'): self.queues = list(ievent.queues) return self def filtered(self, txt): """ see if txt if filtered on this event. """ if not self.filter: return False for filter in self.filter: if filter in txt: return False return True def parse(self, bot, rawstr): """ parse raw string into event. overload this. """ pass def make_response(self, txt, result=None, nick=None, dot=False, nritems=False, nr=False, fromm=None, private=False, how=''): """ create a response based on txt and result list. """ 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 = ' .. '.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, ' .. ') 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 restxt: i.put_nowait(restxt) elif lt: for j in result: i.put_nowait(j) else: i.put_nowait(txt) if self.onlyqueues: return if not self.bot: rlog(10, 'event', 'no bot defined in event') return "no bot is defined in this event" 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(u' .. '.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 = ' .. '.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 restxt: return restxt else: return "no data found" def reply(self, *args, **kwargs): """ reply to event. """ resp = self.make_response(*args, **kwargs) if not resp: return self.bot.say(self.channel, resp) def missing(self, txt): """ show what arguments are missing. """ stats.up('events', 'missing') if self.origtxt: splitted = self.origtxt.split() if self.bot.nick in splitted[0]: try: cmnd = splitted[1] except IndexError: cmnd = splitted[0] elif 'cmnd' in splitted[0]: try: cmnd = splitted[2] except IndexError: cmnd = splitted[0] else: if self.msg: cmnd = splitted[0] else: if self.aliased: cmnd = self.aliased else: cmnd = splitted[0][1:] self.reply(cmnd + ' ' + txt) else: self.reply('missing origtxt: %s' % txt) def ircstr(self): """ old compat function. use str() now. """ return str(self) def handle_error(self, data): """ function to handler errors. .. overload this. """ rlog(10, self.name.error, 'ERROR: %s' % str(data)) def done(self, txt=None): """ reply with the txt 'done'. """ if txt: self.reply('%s done' % txt) else: self.reply('done') def tojson(self): """ convert the event to a json string. """ new = cpy(self) new.sock = 'setremote' new.bot = 'setremote' new.request = 'setremote' new.response = 'setremote' new.queues = [] result = dumps(new) rlog(0, 'eventbase', 'tojson - %s' % str(result)) return result def fromjsonstring(self, input): """ reconstruct the event from a jsonstring. """ temp = loads(input) rlog(10, 'eventbase', str(temp)) self.update(temp) return self def checkqueues(self, resultlist): """ check if resultlist is to be sent to the queues. if so do it. """ if self.queues: for queue in self.queues: for item in resultlist: queue.put_nowait(item) return True def subelement(self, name): if self.subelements: rlog(10, 'eventbase', "got subelements") for node in self.subelements: try: attr = getattr(node, name) rlog(10, 'eventbase', "got subelement %s" % (name, str(attr))) return attr.data except (AttributeError, TypeError): continue
defaultevent = EventBase()