def __init__(self, type, prefix=None, params=None, hostmask=None, target=None, msg=None, nick=None, ident=None, host=None, encoding="utf-8", command=None, argument=None, priority=10, **kwargs): self.type = type self.prefix = prefix self.params = params self.hostmask = hostmask self.nick = coerceToUnicode(nick, encoding) if nick else nick self.ident = coerceToUnicode(ident, encoding) if ident else ident # Note: if unicode/punycode hostnames becomes a thing for IRC, .decode("idna") I guess self.host = host self.target = coerceToUnicode(target, encoding) if target else target # if there is a msg, it's already unicode (done in dispatcher.) self.msg = msg self.command = command self.argument = argument # kwargs is a dict of uncommon event attributes which will be looked up on attribute access self.kwargs = kwargs # might be useful self.time = time() self.dtime = datetime.now() self.priority = priority
def dispatch(self, botinst, eventtype, **eventkwargs): settings = self.settings servername = settings.serverlabel cont_or_wrap = botinst.container event = None # Case insensitivity for etypes (convenience) #TODO: (is this a bad idea?) eventtype = eventtype.lower() msg = eventkwargs.get("msg", None) if msg and eventtype != "sendmsg": eventkwargs["msg"] = msg = coerceToUnicode(eventkwargs["msg"], settings.encoding) command = "" if eventtype != "sendmsg" and msg and msg.startswith(settings.commandprefix): #case insensitive command (see below) #commands can't have spaces in them, and lol command prefix can't be a space #if you want a case sensitive match you can do your command as a regex command, argument = commandSplit(msg) #support multiple character commandprefix command = command[len(settings.commandprefix):] # Maintain case for event, for funny things like replying in all caps eventkwargs["command"], eventkwargs["argument"] = (command, argument) command = command.lower() eventmap = self.eventmap if eventtype in eventmap: # TODO: Event and wrapper creation could possible be delayed even further maybe if event is None: eventkwargs["encoding"] = settings.encoding event, cont_or_wrap = self.createEventAndWrap(cont_or_wrap, eventtype, eventkwargs) #lol dispatcher is 100 more simple now, but at the cost of more dict... for mapping in eventmap[eventtype]["instant"]: self._dispatchreally(mapping.function, event, cont_or_wrap) if mapping.priority == 0: break #lol cheap and easy way to support total override #super fast command dispatching now... Only thing left that's slow is the regex but has to be for mapping in eventmap[eventtype]["command"].get(command,()): self._dispatchreally(mapping.function, event, cont_or_wrap) if mapping.priority == 0: break # TODO: Consider this: # super priority==0 override doesn't really make much sense on a regex, but whatever for mapping in eventmap[eventtype]["regex"]: result = mapping.regex.search(msg) if result: event.regex_match = result self._dispatchreally(mapping.function, event, cont_or_wrap) if mapping.priority == 0: break if eventtype in self.waitmap: #special map to deal with WaitData #delayed event creation as late as possible: if event is None: event, cont_or_wrap = self.createEventAndWrap(cont_or_wrap, eventtype, eventkwargs) wdset = self.waitmap[eventtype] remove = [] for wd in wdset: # if found stopevent add it to list to remove after iteration if eventtype in wd.stope: remove.append(wd) wd.q.put(event) wd.done = True elif eventtype in wd.interestede: wd.q.put(event) if remove: for x in remove: self.delWaitData(x)
def dispatch(self, botinst, event_type, **eventkwargs): settings = self.settings cont_or_wrap = botinst.container event = None # Case insensitivity for event_type lookups l_event_type = event_type.lower() dispatched = False msg = eventkwargs.get("msg", None) if msg and l_event_type != "sendmsg": eventkwargs["msg"] = msg = coerceToUnicode(eventkwargs["msg"], settings.encoding) command = "" if l_event_type != "sendmsg" and msg and msg.startswith(settings.commandprefix): #case insensitive command (see below) #commands can't have spaces in them, and lol command prefix can't be a space #if you want a case sensitive match you can do your command as a regex command, argument = commandSplit(msg) #support multiple character commandprefix command = command[len(settings.commandprefix):] # Maintain case for event, for funny things like replying in all caps eventkwargs["command"], eventkwargs["argument"] = (command, argument) command = command.lower() eventmap = self.eventmap if l_event_type in eventmap: # TODO: Event and wrapper creation could possible be delayed even further maybe if event is None: eventkwargs["encoding"] = settings.encoding event, cont_or_wrap = self.createEventAndWrap(cont_or_wrap, l_event_type, eventkwargs) if self.debug >= 2: print "DISPATCHING: %s" % event #lol dispatcher is 100 more simple now, but at the cost of more dict... for mapping in eventmap[l_event_type]["instant"]: self._dispatchreally(mapping.function, event, cont_or_wrap, self.debug) dispatched = True if mapping.priority == 0: break #lol cheap and easy way to support total override #super fast command dispatching now... Only thing left that's slow is the regex but has to be for mapping in eventmap[l_event_type]["command"].get(command,()): if mapping.admin and (event.nick.lower() not in settings.admins): # TODO: Do we bot.say("access denied") ? continue self._dispatchreally(mapping.function, event, cont_or_wrap, self.debug) dispatched = True if mapping.priority == 0: break # TODO: Consider this: # super priority==0 override doesn't really make much sense on a regex, but whatever for mapping in eventmap[l_event_type]["regex"]: result = mapping.regex.search(msg) if result: event.regex_match = result self._dispatchreally(mapping.function, event, cont_or_wrap, self.debug) dispatched = True if mapping.priority == 0: break if l_event_type in self.waitmap: #special map to deal with WaitData #delayed event creation as late as possible: if event is None: event, cont_or_wrap = self.createEventAndWrap(cont_or_wrap, event_type, eventkwargs) wdset = self.waitmap[l_event_type] remove = [] for wd in wdset: # if found stopevent add it to list to remove after iteration if l_event_type in wd.stope: remove.append(wd) wd.q.put(event) wd.done = True dispatched = True elif l_event_type in wd.interestede: wd.q.put(event) dispatched = True if remove: for x in remove: self.delWaitData(x) return dispatched