1 #!/usr/local/bin/python
3 # Joel Rosdahl <joel@rosdahl.net>
4 # Andrew Walkingshaw <andrew@lexical.org.uk>
6 # This file is part of Acrobat.
8 # Acrobat is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published
10 # by the Free Software Foundation; either version 2 of the License,
11 # or (at your option) any later version.
13 # Foobar is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with Foobar; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 disconnect -- Disconnect the bot. The bot will try to reconnect
27 die -- Let the bot cease to exist.
29 google -- search, 'I'm Feeling Lucky', and notice the user who searches
33 import string, urllib, sys, cPickle, os
34 from ircbot import SingleServerIRCBot
35 from irclib import nm_to_n, irc_lower
41 class Acrobat(SingleServerIRCBot):
42 def __init__(self, channel, nickname, server, owner, port=6667):
43 SingleServerIRCBot.__init__(self,
44 [(server, port)], nickname, nickname)
45 self.channel = channel
49 f = open("karmadump", "r")
50 self.karma = cPickle.load(f)
57 def on_welcome(self, conn, evt):
58 conn.join(self.channel)
60 def on_privmsg(self, conn, evt):
61 self.do_command(nm_to_n(evt.source()), evt.arguments()[0])
63 def on_pubmsg(self, conn, evt):
64 payload = evt.arguments()[0]
65 a = string.split(evt.arguments()[0], " ", 1)
67 and (irc_lower(a[0]) == irc_lower(self.connection.get_nickname())
68 or irc_lower(a[0])[:-1] == irc_lower(self.connection.get_nickname())):
70 self.do_command(self.channel, string.strip(a[1]), public = 1)
71 if a[0].endswith("++"):
73 if a[0].endswith("--"):
75 if payload[0] == "!" and len(payload)>1:
76 self.do_command(self.channel, string.strip(payload[1:]), public=1)
77 if payload[0] == "~" and len(payload)>1:
78 self.do_command(self.channel, string.strip(payload[1:]), public=1)
80 # And now bot commands;
83 def karmaup(self, cmd):
84 if self.karma.dict.has_key(cmd.split()[0][:-2]):
85 self.karma.dict[cmd.split()[0][:-2]] += 1
87 self.karma.dict[cmd.split()[0][:-2]] = 1
90 def karmadown(self, cmd):
91 if self.karma.dict.has_key(cmd.split()[0][:-2]):
92 self.karma.dict[cmd.split()[0][:-2]] -= 1
94 self.karma.dict[cmd.split()[0][:-2]] = -1
97 def karmaq(self, cmd, conn, nick, public):
101 if self.karma.dict.has_key(cmd.split()[1]):
102 conn.privmsg(self.channel, "%s has karma %s."
104 self.karma.dict[cmd.split()[1]]))
106 conn.privmsg(self.channel, "%s has no karma set." %
109 conn.privmsg(self.channel, "I have karma on %s items." %
110 len(self.karma.dict.keys()))
114 if self.karma.dict.has_key(cmd.split()[1]):
115 conn.notice(nick, "%s has karma %s." %
117 self.karma.dict[cmd.split()[1]]))
119 conn.notice(nick, "I have karma on %s items." %
120 len(self.karma.dict.keys()))
122 conn.notice(nick, "I have karma on %s items." %
123 len(self.karma.dict.keys()))
125 def infoq(self, cmd, nick, conn, public):
127 conn.privmsg(self.channel,
128 "I am Acrobat 0.2chiark, on %s, as nick %s." %
129 (self.channel, self.connection.get_nickname()))
130 conn.privmsg(self.channel,
131 "My owner is %s; I have karma on %s items." %
132 (self.owner, len(self.karma.dict.keys())))
134 conn.notice(nick, "I am Acrobat 0.2chiark, on %s, as nick %s." %
135 (self.channel, self.connection.get_nickname()))
136 conn.notice(nick, "My owner is %s; I have karma on %s items." %
137 (self.owner, len(self.karma.dict.keys())))
140 def quit(self, cmd, nick, conn, public):
141 if irc_lower(nick) == irc_lower(self.owner):
142 f = open("karmadump", "w")
143 cPickle.dump(self.karma, f)
145 self.die(msg="I have been chosen!")
147 conn.privmsg(nick, "Such aggression in public!")
149 conn.notice(nick, "You're not my owner.")
151 # google for something
152 def googleq(self, cmd, nick, conn, public):
153 cmdrest = string.join(cmd.split()[1:])
154 # "I'm Feeling Lucky" rather than try and parse the html
155 targ = ("http://www.google.com/search?q=%s&btnI=I'm+Feeling+Lucky"
156 % urllib.quote_plus(cmdrest))
158 # get redirected and grab the resulting url for returning
159 gsearch = urllib.urlopen(targ).geturl()
160 if gsearch != targ: # we've found something
162 conn.notice(nick, str(gsearch))
163 else: # we haven't found anything.
164 conn.privmsg(nick, str(gsearch))
167 conn.notice(nick, "No pages found.")
169 conn.privmsg(nick, "No pages found.")
170 except IOError: # if the connection times out. This blocks. :(
172 conn,notice(nick, "The web's broken. Waah!")
174 conn.privmsg(nick, "The web's broken. Waah!")
176 # General query handler
177 def do_command(self, nick, cmd, public=0):
178 conn = self.connection
180 if cmd.split()[0].endswith("++"):
184 if cmd.split()[0].endswith("--"):
188 if cmd.split()[0] == "karma" or cmd.split()[0] == "Karma":
189 self.karmaq(cmd, conn, nick, public)
191 # bot's vital statistics
193 self.infoq(cmd, nick, conn, public)
196 if cmd == "disconnect": # hop off for 60s
197 self.disconnect(msg="Be right back.")
200 elif cmd.split()[0] == "say" \
201 and irc_lower(nick) == irc_lower(self.owner):
202 conn.privmsg(self.channel, string.join(cmd.split()[1:]))
204 # action to msg/channel
205 elif cmd.split()[0] == "do" \
206 and irc_lower(nick) == irc_lower(self.owner):
207 conn.action(self.channel, string.join(cmd.split()[1:]))
211 self.quit(cmd, nick, conn, public)
214 elif (cmd.split()[0] == "google" or cmd.split()[0] == "Google"):
215 self.googleq(cmd, nick, conn, public)
218 if len(sys.argv) != 5: # insufficient arguments
219 print "Usage: acrobat <server[:port]> <channel> <nickname> owner"
221 sv_port = string.split(sys.argv[1], ":", 1) # tuple; (server, port)
223 if len(sv_port) == 2:
225 port = int(sv_port[1])
227 print "Error: Erroneous port."
230 port = 6667 # default irc port
231 channel = sys.argv[2]
232 nickname = sys.argv[3]
235 bot = Acrobat(channel, nickname, server, owner, port)
236 sys.stderr.write("Trying to connect...\n")
240 if __name__ == "__main__":