lolbot.py 4.63 KB
Newer Older
Jonathan Harker's avatar
Jonathan Harker committed
1 2 3 4 5 6 7 8 9
#!/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
Jonathan Harker's avatar
Jonathan Harker committed
10
Logs a channel and collects URLs for later.
Jonathan Harker's avatar
Jonathan Harker committed
11 12 13 14 15 16
"""

import sys, string, random, time
from ircbot import SingleServerIRCBot
from irclib import nm_to_n, nm_to_h, irc_lower
import botcommon
Jonathan Harker's avatar
Jonathan Harker committed
17 18 19
import os

from datetime import datetime
20
from mechanize import Browser
Jonathan Harker's avatar
Jonathan Harker committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

# 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.",
Jonathan Harker's avatar
Jonathan Harker committed
37 38
    "Quentin Tarantino is so awesome I want to have his babies.",
    "No it's a week night 8pm is past my bedtime.",
Jonathan Harker's avatar
Jonathan Harker committed
39 40 41 42 43 44 45 46
]

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

    self.channel = channel
    self.nickname = nickname
47
    self.urls = {}
Jonathan Harker's avatar
Jonathan Harker committed
48 49 50 51 52 53 54

    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()

55 56 57 58 59 60 61 62 63 64
  def save_url(self, url):
    try:
      br = Browser()
      br.open(url)
      title = br.title()
    except Exception as ex:
      title = ''
    self.urls[url] = title
    return title

Jonathan Harker's avatar
Jonathan Harker committed
65 66 67 68 69 70 71 72
  def now(self):
    return datetime.today().strftime("%Y-%m-%d %H:%M:%S")

  def log_event(self, event):
    nick = nm_to_n(event.source())
    text = event.arguments()[0]
    print "(%s) %s: %s" % (self.now(), nick, text)

Jonathan Harker's avatar
Jonathan Harker committed
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
  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."

88
    # log it
Jonathan Harker's avatar
Jonathan Harker committed
89
    self.log_event(event)
Jonathan Harker's avatar
Jonathan Harker committed
90 91 92 93 94

    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)
95 96 97 98 99 100 101
    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
102 103 104 105

  def say_public(self, text):
    "Print TEXT into public channel, for all to see."
    self.queue.send(text, self.channel)
Jonathan Harker's avatar
Jonathan Harker committed
106
    print "(%s) %s: %s" % (self.now(), self.nickname, text)
Jonathan Harker's avatar
Jonathan Harker committed
107 108 109 110 111 112 113 114 115 116 117 118 119

  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):
Jonathan Harker's avatar
Jonathan Harker committed
120
    "Return a random pondering."
Jonathan Harker's avatar
Jonathan Harker committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    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":
      target = None
    else:
      target = from_private.strip()

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

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

    elif cmd == 'urls' or cmd == 'list':
145 146 147 148
      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
149 150

    elif cmd.startswith('http:') or cmd.startswith('https:'):
151 152 153 154 155
      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
156 157 158
      
    elif cmd == 'clear':
      del self.urls
159
      self.urls = {}
Jonathan Harker's avatar
Jonathan Harker committed
160 161 162 163 164 165 166 167 168 169 170 171
      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."