chiark / gitweb /
First hacked version
authormatthew <matthew>
Sun, 3 Feb 2002 22:39:33 +0000 (22:39 +0000)
committermatthew <matthew>
Sun, 3 Feb 2002 22:39:33 +0000 (22:39 +0000)
acrobat-chiark-0.2.py [new file with mode: 0755]

diff --git a/acrobat-chiark-0.2.py b/acrobat-chiark-0.2.py
new file mode 100755 (executable)
index 0000000..ccdf676
--- /dev/null
@@ -0,0 +1,241 @@
+#!/usr/local/bin/python
+#
+# Joel Rosdahl <joel@rosdahl.net>
+# Andrew Walkingshaw <andrew@lexical.org.uk>
+# 
+# This file is part of Acrobat.
+#
+# Acrobat is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; either version 2 of the License,
+# or (at your option) any later version.
+#
+# Foobar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Foobar; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+# USA.
+
+"""
+    disconnect -- Disconnect the bot.  The bot will try to reconnect
+                  after 60 seconds.
+
+    die -- Let the bot cease to exist.
+
+    google -- search, 'I'm Feeling Lucky', and notice the user who searches
+              back with the url.
+"""
+
+import string, urllib, sys, cPickle, os
+from ircbot import SingleServerIRCBot
+from irclib import nm_to_n, irc_lower
+
+class Karma:
+    def __init__(self):
+        self.dict = {}
+    
+class Acrobat(SingleServerIRCBot):
+    def __init__(self, channel, nickname, server, owner, port=6667):
+        SingleServerIRCBot.__init__(self,
+                                    [(server, port)], nickname, nickname)
+        self.channel = channel
+        self.owner = owner
+        # load the karma db
+        try:
+            f = open("karmadump", "r")
+            self.karma = cPickle.load(f)
+            f.close()
+        except IOError:
+            self.karma = Karma()
+
+    ## EVENT HANDLERS
+            
+    def on_welcome(self, conn, evt):
+        conn.join(self.channel)
+
+    def on_privmsg(self, conn, evt):
+        self.do_command(nm_to_n(evt.source()), evt.arguments()[0])
+        
+    def on_pubmsg(self, conn, evt):
+        payload = evt.arguments()[0]
+        a = string.split(evt.arguments()[0], " ", 1)
+        if len(a) > 1 \
+           and (irc_lower(a[0]) == irc_lower(self.connection.get_nickname())
+                or irc_lower(a[0])[:-1] == irc_lower(self.connection.get_nickname())):
+
+            self.do_command(self.channel, string.strip(a[1]), public = 1)
+        if a[0].endswith("++"):
+            self.karmaup(a[0])
+        if a[0].endswith("--"):
+            self.karmadown(a[0])
+        if payload[0] == "!" and len(payload)>1:
+            self.do_command(self.channel, string.strip(payload[1:]), public=1)
+        if payload[0] == "~" and len(payload)>1:
+            self.do_command(self.channel, string.strip(payload[1:]), public=1)
+
+    # And now bot commands;
+
+    # increment karma
+    def karmaup(self, cmd):
+        if self.karma.dict.has_key(cmd.split()[0][:-2]):
+            self.karma.dict[cmd.split()[0][:-2]] += 1
+        else:
+            self.karma.dict[cmd.split()[0][:-2]] = 1
+
+    #decrement karma
+    def karmadown(self, cmd):
+        if self.karma.dict.has_key(cmd.split()[0][:-2]):
+            self.karma.dict[cmd.split()[0][:-2]] -= 1
+        else:
+            self.karma.dict[cmd.split()[0][:-2]] = -1
+
+    # query karma
+    def karmaq(self, cmd, conn, nick, public):
+        # in public
+        if public == 1:
+            try:
+                if self.karma.dict.has_key(cmd.split()[1]):
+                    conn.privmsg(self.channel, "%s has karma %s."
+                                 %(cmd.split()[1],
+                                       self.karma.dict[cmd.split()[1]]))
+                else:
+                    conn.privmsg(self.channel, "%s has no karma set." %
+                                 cmd.split()[1])
+            except IndexError:
+                conn.privmsg(self.channel, "I have karma on %s items." %
+                             len(self.karma.dict.keys()))
+        # in private
+        else:
+            try:
+                if self.karma.dict.has_key(cmd.split()[1]):
+                    conn.notice(nick, "%s has karma %s." %
+                                (cmd.split()[1],
+                                 self.karma.dict[cmd.split()[1]]))
+                else:
+                    conn.notice(nick, "I have karma on %s items." %
+                                len(self.karma.dict.keys()))
+            except IndexError:
+                conn.notice(nick, "I have karma on %s items." %
+                            len(self.karma.dict.keys()))
+    # query bot status
+    def infoq(self, cmd, nick, conn, public):
+        if public == 1:
+            conn.privmsg(self.channel,
+                         "I am Acrobat 0.2chiark, on %s, as nick %s." %
+                         (self.channel, self.connection.get_nickname()))
+            conn.privmsg(self.channel,
+                         "My owner is %s; I have karma on %s items." %
+                         (self.owner, len(self.karma.dict.keys())))
+        else:
+            conn.notice(nick, "I am Acrobat 0.2chiark, on %s, as nick %s." %
+                        (self.channel, self.connection.get_nickname()))
+            conn.notice(nick, "My owner is %s; I have karma on %s items." %
+                        (self.owner, len(self.karma.dict.keys())))
+
+    # quit irc
+    def quit(self, cmd, nick, conn, public):
+        if irc_lower(nick) == irc_lower(self.owner):
+            f = open("karmadump", "w")
+            cPickle.dump(self.karma, f)
+            f.close()
+            self.die(msg="I have been chosen!")
+        elif public == 1:
+            conn.privmsg(nick, "Such aggression in public!")
+        else:
+            conn.notice(nick, "You're not my owner.")
+            
+    # google for something
+    def googleq(self, cmd, nick, conn, public):
+        cmdrest = string.join(cmd.split()[1:])
+        # "I'm Feeling Lucky" rather than try and parse the html
+        targ = ("http://www.google.com/search?q=%s&btnI=I'm+Feeling+Lucky"
+                % urllib.quote_plus(cmdrest))
+        try:
+            # get redirected and grab the resulting url for returning
+            gsearch = urllib.urlopen(targ).geturl()
+            if gsearch != targ: # we've found something
+                if public == 0:
+                    conn.notice(nick, str(gsearch))
+                else: # we haven't found anything.
+                    conn.privmsg(nick, str(gsearch))
+            else:
+                if public == 0:
+                    conn.notice(nick, "No pages found.")
+                else:
+                    conn.privmsg(nick, "No pages found.")
+        except IOError: # if the connection times out. This blocks. :(
+            if public == 0:
+                conn,notice(nick, "The web's broken. Waah!")
+            else:
+                conn.privmsg(nick, "The web's broken. Waah!")
+                
+    # General query handler
+    def do_command(self, nick, cmd, public=0):
+        conn = self.connection
+        # karma: up
+        if cmd.split()[0].endswith("++"):
+            self.karmaup(cmd)
+        
+        # karma: down
+        if cmd.split()[0].endswith("--"):
+            self.karmadown(cmd)
+            
+        # karma: query
+        if cmd.split()[0] == "karma" or cmd.split()[0] == "Karma":
+            self.karmaq(cmd, conn, nick, public)
+            
+        # bot's vital statistics
+        if cmd == "info":
+            self.infoq(cmd, nick, conn, public)
+
+        #disconnect
+        if cmd == "disconnect": # hop off for 60s
+            self.disconnect(msg="Be right back.")
+
+        # say to msg/channel
+        elif cmd.split()[0] == "say" \
+             and irc_lower(nick) == irc_lower(self.owner):
+            conn.privmsg(self.channel, string.join(cmd.split()[1:]))
+
+        # action to msg/channel
+        elif cmd.split()[0] == "do" \
+             and irc_lower(nick) == irc_lower(self.owner):
+            conn.action(self.channel, string.join(cmd.split()[1:]))
+
+        # quit IRC
+        elif cmd == "die":
+            self.quit(cmd, nick, conn, public)
+
+        # Google!
+        elif (cmd.split()[0] == "google" or cmd.split()[0] == "Google"):
+            self.googleq(cmd, nick, conn, public)            
+
+def main():
+    if len(sys.argv) != 5: # insufficient arguments
+        print "Usage: acrobat <server[:port]> <channel> <nickname> owner"
+        sys.exit(1)
+    sv_port = string.split(sys.argv[1], ":", 1) # tuple; (server, port)
+    server = sv_port[0]
+    if len(sv_port) == 2:
+        try:
+            port = int(sv_port[1])
+        except ValueError:
+            print "Error: Erroneous port."
+            sys.exit(1)
+    else:
+        port = 6667 # default irc port
+    channel = sys.argv[2]
+    nickname = sys.argv[3]
+    owner = sys.argv[4]
+    # initialize the bot
+    bot = Acrobat(channel, nickname, server, owner, port)
+    sys.stderr.write("Trying to connect...\n")
+    # and the event loop
+    bot.start()
+
+if __name__ == "__main__":
+    main()