Hive13Bot

From Hive13 Wiki
Revision as of 16:45, 20 November 2009 by 66.213.10.5 (talk) (Example: Search MediaWiki)
Jump to navigation Jump to search

This is documenting the bot that I'm working on. The code is ancient; contributions are welcome.

Overview

This code uses an IRC bot library called ircbot.py available here.

How it works

Basic Bot

#!/usr/bin/python
"""
BasicBot - A Basic IRC Bot
License: GPL 2; share and enjoy!
Authors:
Sean B. Palmer, inamidst.com
   Suw Charman, chocnvodka.blogware.com
Augmented by:
   Dave Menninger
Requirements:
   http://inamidst.com/proj/suwbot/ircbot.py
"""

import ircbot, pickle, sys

def basicbot(host, port, channels, nick):
   p = ircbot.Bot(nick=nick, channels=channels)
   
   address_pattern = "(?:%s[:, ]+)" % p.nick

   def f_hi(m, origin, (cmd, channel), text, p=p):
      p.msg(origin.sender, 'hi %s' % origin.nick)
   p.rule(f_hi, 'hi', r"(?i)^Hi %s(\!)?$" % p.nick)

   def f_chop_by_length( longline, length):
      results = []
      while len(longline) > length:
         results.append( longline[:length] )
         longline = longline[length:]
      results.append(longline)
      return results
   
   def f_basicBotHelp(m, origin, (cmd, channel), text, p=p):
      p.msg(origin.sender, "Commands I understand:")
      p.msg(origin.sender, "help, ")
   p.rule(f_basicBotHelp, 'commands', "^%s(help|commands)$" % address_pattern)
   p.rule(f_basicBotHelp, 'commands', "^(help|commands) %s$" % p.nick)

   p.run(host, port)

def main(args):

   if args:
      nickname, ircserver = args[:3]
      rooms = args[3:]
   else:
      nickname = 'Hive13Bot'
      ircserver = 'irc.freenode.net'
      rooms = ['#hive13']
   basicbot(ircserver, 6667, rooms, nick=nickname )

if __name__=='__main__':
   main(sys.argv[1:])

Adding new functionality

To make new functionality you need two basic things: first, a rule that tells the bot when to react to something that someone says in the IRC channel, and second a function to call that some some action whenever that rule is activated. Look at the "hi" function above for an example.

The rule function looks like this:

p.rule(f_hi, 'hi', r"(?i)^Hi %s(\!)?$" % p.nick)

The rule has three arguments in this case. First, the name of the function to call: "f_hi". Second, a name for the command. Last, a regular expression that describes when the rule should activate. Writing a good regular expression can be tricky, see here for more on how they work: http://www.amk.ca/python/howto/regex/ Whenever someone says something in the IRC channel that matches the regular expression, it will call the function specified.

The function that does the action looks like this:

def f_hi(m, origin, (cmd, channel), text, p=p):
   p.msg(origin.sender, 'hi %s' % origin.nick)

Using the p.msg function is how you say things back into the room. The first argument tells where to say it. The second argument is just a string of what to say. Using the variable origin.nick will insert the name of the person that said the message that fired the rule.

More complex examples to come...

Example: Search MediaWiki

This function searches our wiki for a keyword and returns the results back into the IRC room:

   def f_hive13BotWiki(m, origin, (cmd, channel), text, p=p):
      search_term = m.group(2)
      search_url = 'http://wiki.hive13.org/api.php?action=query&list=search&srsearch=%s&format=json' % search_term
      results = simplejson.load(urllib.urlopen(search_url))
      titles = results['query']['search']
      num_titles = len(titles)
      p.msg(origin.sender, "%s results..." % num_titles )
      if num_titles > 0:
         if num_titles < 5:
            for t in titles:
               article_title = "%s" % t['title']
               article_title = article_title.replace(' ','_')
               title_url = "http://wiki.hive13.org/index.php?title=%s" % article_title
               p.msg(origin.sender, "%s" % title_url )
         else:
            p.msg(origin.sender, "too many results. click: http://wiki.hive13.org/index.php?search=%s" % search_term )
      else:
         p.msg(origin.sender, "no results..." )


   p.rule(f_hive13BotWiki, 'wiki', "^%s(wiki) ([^\s]+)$" % address_pattern)
   p.rule(f_hive13BotWiki, 'wiki', "^(wiki) ([^\s]+) %s$" % p.nick)