lolbot.py 4.52 KB
Newer Older
Jonathan Harker's avatar
Jonathan Harker committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#!/usr/bin/env python
#
# LolBot
#
# Code originally based on example bot and irc-bot class from
# Joel Rosdahl <joel@rosdahl.net>, author of included python-irclib.

"""
Useful bot for folks stuck behind censor walls at work
"""

import sys, string, random, time
from ircbot import SingleServerIRCBot
from irclib import nm_to_n, nm_to_h, irc_lower
import botcommon
16 17
import time
from mechanize import Browser
Jonathan Harker's avatar
Jonathan Harker committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

# Exclamations - wrong input
exclamations = [
    "Zing!",
    "Burns!",
    "Tard!",
    "Lol.",
    "Crazy!",
    "WTF?",
]

# Ponderings
ponderings = [
    "Hi, can I have a medium lamb roast, with just potatoes.",
    "Can I slurp on your Big Cock?",
    "Your Mum likes it two in the pink one in the stink.",
]

class LolBot(SingleServerIRCBot):
  def __init__(self, channel, nickname, server, port):
    SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)

    self.channel = channel
    self.nickname = nickname
42 43
    self.urls = {}
    self.logfile = open('/tmp/lolbot.log', 'a')
Jonathan Harker's avatar
Jonathan Harker committed
44 45 46 47 48 49 50

    self.helptext = "Adds URLs to a list. Commands: list - prints a bunch of URLs; clear - clears the list; lol - say something funny; <url> - adds the URL to the list; help - this message."

    self.queue = botcommon.OutputManager(self.connection)
    self.queue.start()
    self.start()

51 52 53 54 55 56 57 58 59 60 61
  def save_url(self, url):
    try:
      br = Browser()
      br.open(url)
      title = br.title()
    except Exception as ex:
      print ex
      title = ''
    self.urls[url] = title
    return title

Jonathan Harker's avatar
Jonathan Harker committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  def on_nicknameinuse(self, connection, event):
    self.nickname = connection.get_nickname() + "_"
    connection.nick(self.nickname)

  def on_welcome(self, connection, event):
    connection.join(self.channel)

  def on_privmsg(self, connection, event):
    "Deal with a /msg private message."
    from_nick = nm_to_n(event.source())
    self.do_command(event, event.arguments()[0], from_nick)

  def on_pubmsg(self, connection, event):
    "Deal with a public message in a channel."

77 78
    # log it
    self.logfile.write("%s\n" % event.arguments()[0])
Jonathan Harker's avatar
Jonathan Harker committed
79 80 81 82 83

    from_nick = nm_to_n(event.source())
    args = string.split(event.arguments()[0], ":", 1)
    if len(args) > 1 and irc_lower(args[0]) == irc_lower(self.nickname):
      self.do_command(event, string.strip(args[1]), from_nick)
84 85 86 87 88 89 90
    else:
      # parse it for links, add URLs to the list
      words = event.arguments()[0].split(" ")
      for w in words:
        if w.startswith('http://') or w.startswith('https://'):
          title = self.save_url(w)
          self.say_public(title)
Jonathan Harker's avatar
Jonathan Harker committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

  def say_public(self, text):
    "Print TEXT into public channel, for all to see."
    self.queue.send(text, self.channel)

  def say_private(self, nick, text):
    "Send private message of TEXT to NICK."
    self.queue.send(text, nick)

  def reply(self, text, to_private=None):
    "Send TEXT to either public channel or TO_PRIVATE nick (if defined)."
    if to_private is not None:
      self.say_private(to_private, text)
    else:
      self.say_public(text)

  def ponder(self):
    "Return a random string indicating what Pinky's pondering."
    return random.choice(ponderings)

  def exclaim(self):
    "Return a random exclamation string."
    return random.choice(exclamations)

  def do_command(self, event, cmd, from_private):
    """
    This is the function called whenever someone sends a public or
    private message addressed to the bot. (e.g. "bot: blah").
    """

    if event.eventtype() == "pubmsg":
      # self.reply() sees 'from_private = None' and sends to public channel.
      target = None
    else:
      # assume that from_private comes from a 'privmsg' event.
      target = from_private.strip()

    # Be forgiving about capitalization and whitespace.
    #cmd = cmd.replace(" ", "").lower()

    if cmd == 'help':
      self.reply(self.helptext, target)

    elif cmd == 'lol':
      self.reply(self.ponder(), target)

    elif cmd == 'urls' or cmd == 'list':
138 139 140 141
      for url, title in self.urls.items():
        line = "%s %s" % (url, title)
        self.reply(line, target)
        time.sleep(1)
Jonathan Harker's avatar
Jonathan Harker committed
142 143

    elif cmd.startswith('http:') or cmd.startswith('https:'):
144 145 146 147 148
      title = self.save_url(cmd)
      if title == '':
        self.reply('URL added.', target)
      if title != '':
        self.reply('URL added: %s' % title, target)
Jonathan Harker's avatar
Jonathan Harker committed
149 150 151
      
    elif cmd == 'clear':
      del self.urls
152
      self.urls = {}
Jonathan Harker's avatar
Jonathan Harker committed
153 154 155 156 157 158 159 160 161 162 163 164
      self.reply('URLs cleared.', target)

    else:
      self.reply(self.exclaim(), target)


if __name__ == "__main__":
  try:
    botcommon.trivial_bot_main(LolBot)
  except KeyboardInterrupt:
    print "Shutting down."