Multithreading maybe?
[scrappy.git] / scrappy.py
blob6425f90e30365d581c52fb00327c53885f05569e
1 #!/usr/bin/env python
2 # Thou shalt use a fixed tab size of 8
4 import irclib_scrappy
5 import sys, os
6 import traceback
7 import thread
9 DEBUG = True
11 def debug(msg):
12 if DEBUG:
13 print msg
14 def loadme(self):
15 debug("LOADME")
17 def modload_cmd(c,list,bot):
18 """modload - Loads a module"""
19 cmd = list[4].split(" ")[0]
21 if cmd == "modload" and list[3]:
22 param = list[4].split(" ")[1]
23 bot.load_module(param)
25 def modlist_cmd(c,list,bot):
26 """modlist - Lists loaded modules"""
27 if list[4] == "modlist" and list[3]:
28 c.privmsg(list[0],bot.modulelist)
31 class scrappy:
32 def __init__(self):
33 debug("Scrappy bot started.")
34 self.cmdchar = '!'
35 self.nickname = 'macscrap'
36 self.username = 'scrappy'
37 self.realname = 'Scrappy Bot'
38 self.nickservpass = ''
39 self.identify = False
40 self.server = ''
41 self.port = 6667
42 self.chanlist = []
43 self.irc = '' #this will be the socket
44 self.c = '' #Thomas, explain this to me later
46 #testvar, should be gotten rid of
47 self.configing = False
49 #Experimental stuff for dynamic modules
50 self.modulelist = []
51 self.privmsg_events = []
52 self.pubmsg_events = []
53 self.onload_events = []
54 self.onquit_events = []
55 #self.what_other_events? = []
57 #load modules(currently in main())
58 self.load_module("config")
59 self.load_module("core")
60 #self.load_module("markov")
62 self.register_onload_event(loadme)
64 #on_load event
65 self.on_load()
67 self.__main()
69 def parse_argv(self):
70 """Parse the commandline args and print a usage message if incorrect."""
71 if len(sys.argv) < 3: #Need at least server
72 self.print_usage()
73 sys.exit(1)
75 s = sys.argv[1].split(":", 1)
76 self.server = s[0]
78 if len(s) == 2:
79 try:
80 self.port = int(s[1])
81 except ValueError:
82 print "Error: Erroneous port."
83 sys.exit(1)
85 self.nickname = sys.argv[2]
86 for ch in sys.argv[3:]:
87 self.chanlist.append('#%s' % ch)
89 def print_usage(self):
90 print 'Usage: %s <server[:port]> <nickname> [channel 1 channel 2 ... channelN]' % sys.argv[0]
92 def __main(self):
93 self.parse_argv()
94 self.irc = irclib_scrappy.IRC()
96 try:
97 self.c = self.irc.server().connect(self.server,
98 self.port, self.nickname,
99 username=self.username,ircname=self.realname)
100 except irclib_scrappy.ServerConnectionError, x:
101 print x
102 sys.exit(1)
104 #if all goes well, register handlers
105 self.c.add_global_handler("welcome", self.on_connect)
106 self.c.add_global_handler("disconnect", self.on_disconnect)
107 self.c.add_global_handler("privmsg", self.on_privmsg)
108 self.c.add_global_handler("pubmsg", self.on_pubmsg)
110 #register some phony modules for testing
111 # self.register_module("My phony module", 'foo', 'foo')
112 # self.register_module("Another phony module", 'foo', 'foo')
114 #register some events
115 self.register_msg_event(modload_cmd)
116 self.register_msg_event(modlist_cmd)
118 self.list_modules()
120 #nothng after this executes
121 self.irc.process_forever()
123 ##################
124 #Event Processing#
125 ##################
126 def register_privmsg_event(self,func):
127 self.privmsg_events.append(func)
129 def register_pubmsg_event(self,func):
130 self.pubmsg_events.append(func)
132 #Convenience function, registers the func
133 #for both privmsgs and pubmsgs
134 def register_msg_event(self,func):
135 self.register_privmsg_event(func)
136 self.register_pubmsg_event(func)
138 def register_onload_event(self,func):
139 self.onload_events.append(func)
141 def register_onquit_event(self,func):
142 self.onquit_events.append(func)
144 ################
145 #Event Handlers#
146 ################
147 def on_connect(self, c, event):
148 for ch in self.chanlist:
149 if irclib_scrappy.is_channel(ch) :
150 c.join(ch)
152 if self.identify == True:
153 self.c.privmsg("nickserv", "identify %s" % self.nickservpass)
155 def on_pubmsg(self, c, event):
156 arg = event.arguments()[0]
157 iscmd = False
159 nick = irclib_scrappy.nm_to_n(event.source())
160 user = irclib_scrappy.nm_to_u(event.source())
161 host = irclib_scrappy.nm_to_h(event.source())
163 debug(nick)
165 if arg[0] == self.cmdchar:
166 cmd = arg[1:]
167 iscmd = True
168 else:
169 cmd = arg
171 #dispatch the command
172 for func in self.pubmsg_events:
173 thread.start_new_thread(func, (c,[nick,user,host,iscmd,cmd,event.target()],self))
175 def on_privmsg(self, c, event):
176 cmd = event.arguments()[0]
177 iscmd = False
179 nick = irclib_scrappy.nm_to_n(event.source())
180 user = irclib_scrappy.nm_to_u(event.source())
181 host = irclib_scrappy.nm_to_h(event.source())
183 if cmd[0] == self.cmdchar:
184 c.privmsg(nick,"You privmsged me, you don't need to " +
185 "prefix commands with %s" % self.cmdchar)
186 cmd = cmd[1:]
188 iscmd = True
190 #dispatch the command
191 for func in self.privmsg_events:
192 thread.start_new_thread(func, (c,[nick,user,host,iscmd,cmd,event.target()],self))
195 def on_disconnect(self, c, event):
196 for func in self.onquit_events:
197 func()
199 sys.exit(0)
201 def on_load(self):
202 for func in self.onload_events:
203 func(self)
205 ################
206 #Module Loading#
207 ################
208 def load_module(self,name):
209 #for whatever reason, OS X needs your modules folder to be in PYTHONPATH to load
210 try:
211 sys.path.append(os.path.join(os.getcwd(), "modules"))
212 module = __import__(name)
213 except ImportError:
214 #should be error output
215 print "No such module\n"
216 print traceback.print_exc()
217 return
219 module.__init__(self)
220 self.register_module(name,'foo','foo')
222 def register_module(self, name, eventlist, function):
223 self.modulelist.append(name)
225 def list_modules(self):
226 """List currently loaded modules."""
227 print "Currently loaded modules:"
228 for mod in self.modulelist:
229 print mod
232 if(__name__ == "__main__"):
233 bot = scrappy()