MADNESS
[scrappy.git] / scrappy2.py
blob2d8e34a24f559c1064db0361c375c8b310edd4f6
1 #!/usr/bin/env python
2 #Let's keep this file in particular as clean and neatly organized as possible.
3 #If this is nice and organized, then writing new modules will be a snap and this
4 #file should rarely have to be edited.
6 import irclib_scrappy
7 import sys
8 import time
10 ################################################################################
11 #set to False to turn off debugging to stdout
12 DEBUG = True
14 def debug(msg):
15 if DEBUG:
16 print msg
18 ################################################################################
20 #this is our main bot class. Once scrappy.py is called, an instance of this
21 #class (our bot) gets created and some initialization is done. The real work is
22 #done via modules that get loaded here.
24 class scrappy:
25 def __init__(self):
26 debug("Scrappy bot started.")
27 #hard-code these for now
28 #then write a config loading module
29 self.cmdchar = '!'
30 self.nickname = 'Scrappy'
31 self.username = 'scrappy'
32 self.realname = 'Scrappy Bot'
33 self.server = ''
34 self.port = 6667
35 self.chanlist = []
36 self.ircsock = ''
37 self.connection = ''
39 #our event lists.
40 #each module adds functions to be called to these events.
41 #each event handler calls all of the functions within its list.
42 self.modulelist = []
43 self.eventlist = ["connect", "disconnect", "error", "invite",
44 "join", "kick", "load", "mode", "msg", "part", "ping", "pong",
45 "privmsg", "privnotice", "pubmsg", "pubnotice", "quit"]
46 self.connect_events = []
47 self.disconnect_events = []
48 self.error_events = []
49 self.invite_events = []
50 self.join_events = []
51 self.kick_events = []
52 self.load_events = []
53 self.mode_events = []
54 self.msg_events = []
55 self.part_events = []
56 self.ping_events = []
57 self.pong_events = []
58 self.privmsg_events = []
59 self.privnotice_events = []
60 self.pubmsg_events = []
61 self.pubnotice_events = []
62 self.quit_events = []
64 #do it up
65 self.__main()
67 ########################################################################
68 def parse_argv(self):
69 """Parse the command line args and print a usage message if incorrect."""
70 #need at least a server to connect to
71 if len(sys.argv) < 3:
72 self.print_usage()
73 sys.exit(1)
75 #split out the port if specified
76 s = sys.argv[1].split(":",1)
77 self.server = s[0]
79 if len(s) == 2: #have a port
80 try:
81 self.port = int(s[1])
82 except ValueError:
83 print "Error: Invalid port."
84 sys.exit(1)
86 self.nickname = sys.argv[2]
87 #add the channels to a list
88 for chan in sys.argv[3:]:
89 self.chanlist.append("#%s" % chan)
91 def print_usage(self):
92 print 'Usage: %s <server[:port]> <nickname> [channel 1 channel 2 ... channelN]' % sys.argv[0]
94 ########################################################################
95 def __main(self):
96 """The real work. Initialize our connection and register events."""
97 #parse comamnd line and create a new socket
98 self.parse_argv()
99 self.ircsock = irclib_scrappy.IRC()
101 #attempt to create a socket and connect to the server
102 try:
103 self.connection = self.ircsock.server().connect(self.server, self.port, self.nickname, username = self.username, ircname = self.realname)
104 except irclib_scrappy.ServerConnectionError, x: #connection failed, print error and exit
105 print x
106 sys.exit(1)
108 #register handlers for events
109 self.connection.add_global_handler("welcome", self.on_connect)
110 self.connection.add_global_handler("disconnect", self.on_disconnect)
111 self.connection.add_global_handler("error", self.on_error)
112 self.connection.add_global_handler("invite", self.on_invite)
113 self.connection.add_global_handler("join", self.on_join)
114 self.connection.add_global_handler("kick", self.on_kick)
115 self.connection.add_global_handler("mode", self.on_mode)
116 self.connection.add_global_handler("part", self.on_part)
117 self.connection.add_global_handler("ping", self.on_ping)
118 self.connection.add_global_handler("pong", self.on_pong)
119 self.connection.add_global_handler("privmsg", self.on_privmsg)
120 self.connection.add_global_handler("privnotice", self.on_privnotice)
121 self.connection.add_global_handler("pubmsg", self.on_privmsg)
122 self.connection.add_global_handler("quit", self.on_quit)
126 #enter main event loop after this
127 #no code after here
128 try:
129 self.ircsock.process_forever()
130 except KeyboardInterrupt:
131 self.connection.quit("Keyboard interrupt!")
133 ########################################################################
134 ###################
135 #Event Registering#
136 ###################
138 def register_event(self, event_type, func):
139 """Call this with an event_type and a function to call when that event_type happens."""
140 #list of legal event types
141 #keep in ABC order
144 if not event_type in self.eventlist:
145 debug("Oops! I don't know what a %s event is." % event_type)
146 return
147 #event is good, add them to event list
148 #keep these in ABC order
149 #should these require the func name be unique?
151 if event_type == "connect":
152 self.connect_events.append(func)
153 if event_type == "disconnect":
154 self.disconnect_events.append(func)
155 if event_type == "error":
156 self.error_events.append(func)
157 if event_type == "invite":
158 self.invite_events.append(func)
159 if event_type == "join":
160 self.join_events.append(func)
161 if event_type == "kick":
162 self.kick_events.append(func)
163 if event_type == "load":
164 self.load_events.append(func)
165 if event_type == "mode":
166 self.mode_events.append(func)
167 if event_type == "msg":
168 self.privmsg_events.append(func)
169 self.pubmsg_events.append(func)
170 if event_type == "part":
171 self.part_events.append(func)
172 if event_type == "ping":
173 self.ping_events.append(func)
174 if event_type == "pong":
175 self.pong_events.append(func)
176 if event_type == "privmsg":
177 self.privmsg_events.append(func)
178 if event_type == "privnotice":
179 self.privnotice_events.append(func)
180 if event_type == "pubmsg":
181 self.pubmsg_events.append(func)
182 if event_type == "pubnotice":
183 self._events.append(func)
184 if event_type == "quit":
185 self.quit_events.append(func)
188 def deregister_event(self, event_type, func):
189 pass
190 ########################################################################
191 ##################
192 #Event Handlers #
193 ##################
194 #note that right now these don't all pass args to the functions they call
195 #We'll need to eventuall pass the appropriate args.
197 def on_connect(self, conn, eventlist):
198 """Called when bot makes a connection to the server."""
199 #do all of our events
200 for func in self.connect_events:
201 func()
203 #join channels
204 for chan in self.chanlist:
205 if irclib_scrappy.is_channel(chan):
206 conn.join(chan)
208 ########################################################################
209 def on_disconnect(self, conn, eventlist):
210 """Called when the connection to the server is closed."""
211 for func in self.disconnect_events:
212 func()
213 conn.quit("Scrappy bot signing off.")
214 #do we need to clean stuff up?
215 sys.exit(0)
217 ########################################################################
218 def on_error(self, conn, eventlist):
219 debug("Error received: %s" % eventlist.arguments())
220 for func in self.error_events:
221 func()
223 ########################################################################
224 def on_invite(self, conn, eventlist):
225 debug("Received an invite: %s" % eventlist.arguments())
226 for func in self.invite_events:
227 func()
229 ########################################################################
230 def on_join(self, conn, eventlist):
231 debug("User joined: %s" % eventlist.arguments())
232 for func in self.join_events:
233 func()
235 ########################################################################
236 def on_kick(self, conn, eventlist):
237 debug("Someone was kicked: %s" % eventlist.arguments())
238 for func in self.kick_events:
239 func()
241 ########################################################################
242 def on_mode(self, conn, eventlist):
243 debug("Mode change: %s" % eventlist.arguments())
244 for func in self.mode_events:
245 func()
247 ########################################################################
248 def on_part(self, conn, eventlist):
249 debug("Part: %s" % eventlist.arguments())
250 for func in self.part_events:
251 func()
253 ########################################################################
254 def on_ping(self, conn, eventlist):
255 debug("Ping: %s" % eventlist.arguments())
256 for func in self.ping_events:
257 func()
259 ########################################################################
260 def on_pong(self, conn, eventlist):
261 debug("Pong: %s" % eventlist.arguments())
262 for func in self.pong_events:
263 func()
265 ########################################################################
266 def on_privmsg(self, conn, eventlist):
267 """Called when bot receives a private or channel (public) message."""
268 #eventlist.arguments() = the message body
269 cmd = eventlist.arguments()[0]
271 nick = irclib_scrappy.nm_to_n(eventlist.source())
272 user = irclib_scrappy.nm_to_u(eventlist.source())
273 host = irclib_scrappy.nm_to_h(eventlist.source())
275 for func in self.privmsg_events:
276 func(conn, [nick, user, host, true, None, event.target()], self)
278 ########################################################################
279 def on_privnotice(self, conn, eventlist):
280 debug("Privnotice: %s" % eventlist.arguments())
281 for func in self.privnotice_events:
282 func()
284 ########################################################################
285 def on_pubmsg(self, conn, eventlist):
286 debug("Pubmsg: % " % eventlist.arguments())
287 for func in pubmsg_events:
288 func()
290 ########################################################################
291 def on_quit(self, conn, eventlist):
292 debug("Quit: %s" % eventlist.arguments())
293 for func in quit_events:
294 func()
297 ################################################################################
299 if __name__ == "__main__":
300 bot = scrappy()