diff --git a/dr_botzo/markov/ircplugin.py b/dr_botzo/markov/ircplugin.py new file mode 100644 index 0000000..dc0c697 --- /dev/null +++ b/dr_botzo/markov/ircplugin.py @@ -0,0 +1,72 @@ +import logging +import re + +import irc.client + +from ircbot.lib import Plugin, reply_destination_for_event +import markov.lib as markovlib +from markov.models import MarkovContext, MarkovState, MarkovTarget + +log = logging.getLogger('markov.ircplugin') + + +class Markov(Plugin): + + """Build Markov chains and reply with them.""" + + def start(self): + """Set up the handlers.""" + + self.connection.add_global_handler('pubmsg', getattr(self, 'handle_chatter'), -20) + self.connection.add_global_handler('privmsg', getattr(self, 'handle_chatter'), -20) + + super(Markov, self).start() + + def stop(self): + """Tear down handlers.""" + + self.connection.remove_global_handler('pubmsg', getattr(self, 'handle_chatter')) + self.connection.remove_global_handler('privmsg', getattr(self, 'handle_chatter')) + + super(Markov, self).stop() + + def handle_chatter(self, connection, event): + """Learn from IRC chatter.""" + + what = event.arguments[0] + my_nick = connection.get_nickname() + trimmed_what = re.sub(r'^{0:s}[:,]\s+'.format(my_nick), '', what) + nick = irc.client.NickMask(event.source).nick + target = reply_destination_for_event(event) + + # learn the line + log.debug(u"learning %s", trimmed_what) + context = markovlib.get_or_create_target_context(target) + markovlib.learn_line(trimmed_what, context) + + log.debug(u"searching '%s' for '%s'", what, my_nick) + if re.search(my_nick, what, re.IGNORECASE) is not None: + context = markovlib.get_or_create_target_context(target) + + addressed_pattern = r'^{0:s}[:,]\s+(.*)'.format(my_nick) + addressed_re = re.compile(addressed_pattern) + if addressed_re.match(what): + # i was addressed directly, so respond, addressing + # the speaker + topics = [x for x in addressed_re.match(what).group(1).split(' ') if len(x) >= 3] + + self.bot.privmsg(target, u"{0:s}: {1:s}" + u"".format(nick, u" ".join(markovlib.generate_line(context, + topics=topics, + max_sentences=1)))) + else: + # i wasn't addressed directly, so just respond + topics = [x for x in what.split(' ') if len(x) >= 3] + + self.bot.privmsg(target, u"{0:s}" + u"".format(u" ".join(markovlib.generate_line(context, + topics=topics, + max_sentences=1)))) + + +plugin = Markov