193 lines
5.4 KiB
Python
193 lines
5.4 KiB
Python
import threading
|
|
import string
|
|
import socket
|
|
import sys
|
|
|
|
#server = "casimir.ponteilla.net"
|
|
server = "localhost"
|
|
port = 6667
|
|
chan = "#pno"
|
|
nick = "PaulBot"
|
|
|
|
|
|
class ModNotFoundException(Exception):
|
|
pass
|
|
|
|
def getnick(user):
|
|
return user.split('!')[0]
|
|
|
|
class monmodule:
|
|
def __init__(self, name, client):
|
|
self.name = name
|
|
if name in sys.modules:
|
|
reload(sys.modules[name])
|
|
self.mod = __import__(name)
|
|
self.mod.mod_init(client)
|
|
|
|
class TCPClient:
|
|
|
|
cmds = ["privmsg", "ping"] #"mode", "join", "part", "quit"]
|
|
|
|
def __init__(self, sock, nick):
|
|
self.sock = sock
|
|
self.nick = nick
|
|
self.modules = []
|
|
|
|
def send(self, msg):
|
|
self.sock.send(":%s %s\r\n" % (self.nick, msg))
|
|
print "=== sent: :%s %s" % (self.nick, msg)
|
|
|
|
def pubchat(self, chan, msg):
|
|
self.send("PRIVMSG %s :%s" % (chan, msg))
|
|
|
|
def sendto(self, who, msg):
|
|
self.pubchat(getnick(who), msg)
|
|
|
|
def handle(self, data):
|
|
#print data
|
|
if data[0] != ':':
|
|
data = ':none ' + data
|
|
args = data.split(':')[1:]
|
|
args = args[0].split() + [':'.join(args[1:])]
|
|
cmd = args[1].lower()
|
|
|
|
# print "=== CMD(%s)" % cmd
|
|
|
|
if cmd in self.cmds:
|
|
getattr(self, "on_" + cmd)(args[0], args[2:])
|
|
|
|
|
|
def onconnect(self):
|
|
self.sock.send("NICK %s\r\n" % nick)
|
|
self.sock.send("USER paulbot ponteilla.net blektr :PaulBot\r\n")
|
|
|
|
self.send("JOIN #pno")
|
|
|
|
def find_mod(self, name):
|
|
try:
|
|
i = [x.name for x in self.modules].index(name)
|
|
except ValueError:
|
|
raise ModNotFoundException()
|
|
else:
|
|
return self.modules[i]
|
|
|
|
def remove_mod(self, name):
|
|
mod = self.find_mod(name)
|
|
reload(mod.mod)
|
|
self.modules.remove(mod)
|
|
|
|
def handle_command(self, who, cmd):
|
|
if len(cmd.split()) < 1:
|
|
return
|
|
ncmd = cmd.split()[0]
|
|
nargs = cmd.split()[1:]
|
|
if ncmd == "reload":
|
|
try:
|
|
mod = self.find_mod(nargs[0])
|
|
except ModNotFoundException:
|
|
self.sendto(who, "ERROR: Module '%s' not loaded" % nargs[0])
|
|
else:
|
|
self.sendto(who, "Reloading module '%s'..." % nargs[0])
|
|
try:
|
|
reload(mod.mod)
|
|
mod.mod.mod_init(self)
|
|
except Exception, e:
|
|
self.sendto(who, "ERROR: %s" % str(e))
|
|
|
|
if ncmd == "unload":
|
|
try:
|
|
self.remove_mod(nargs[0])
|
|
except ModNotFoundException:
|
|
self.sendto(who, "ERROR: Module '%s' not loaded" % nargs[0])
|
|
else:
|
|
self.sendto(who, "Module '%s' unloaded." % nargs[0])
|
|
|
|
if ncmd == "load":
|
|
if nargs[0] in [x.name for x in self.modules]:
|
|
self.sendto(who, "ERROR: Module '%s' already loaded" % str(e))
|
|
else:
|
|
try:
|
|
mod = monmodule(nargs[0], self)
|
|
except Exception, e:
|
|
self.sendto(who, "ERROR: %s" % str(e))
|
|
else:
|
|
self.modules.append(mod)
|
|
self.sendto(who, "Module '%s' loaded." % nargs[0])
|
|
|
|
def on_pubchat(self, who, chan, msg):
|
|
if msg[:len(self.nick)] == self.nick:
|
|
nmsg = ':'.join(msg.split(':')[1:]).lstrip()
|
|
self.handle_command(chan, nmsg)
|
|
|
|
for mod in self.modules:
|
|
if 'on_pubchat' in dir(mod.mod):
|
|
try:
|
|
mod.mod.on_pubchat(who, chan, msg)
|
|
except Exception, e:
|
|
self.sendto(chan, str(e))
|
|
self.sendto(chan, "Module '%s' unloaded" % mod.name)
|
|
self.remove_mod(mod.name)
|
|
|
|
def on_privchat(self, who, msg):
|
|
self.handle_command(who, msg)
|
|
|
|
for mod in self.modules:
|
|
if 'on_privchat' in dir(mod.mod):
|
|
try:
|
|
mod.mod.on_privchat(who, msg)
|
|
except Exception, e:
|
|
self.sendto(getnick(who), str(e))
|
|
self.sendto(getnick(who), "Module '%s' unloaded" % mod.name)
|
|
self.remove_mod(mod.name)
|
|
|
|
|
|
def on_privmsg(self, who, params):
|
|
towho = params[0]
|
|
msg = params[1]
|
|
|
|
if getnick(towho) == self.nick:
|
|
self.on_privchat(who, msg)
|
|
else:
|
|
self.on_pubchat(who, towho, msg)
|
|
|
|
print "(%s) %s: %s" % (towho, who.split('!')[0], msg)
|
|
|
|
|
|
def on_ping(self, who, params):
|
|
print "PING? PONG!"
|
|
self.send("PONG %s" % self.nick)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
client = TCPClient(sock, nick)
|
|
|
|
print "Connecting to %s:%d" % (server, port)
|
|
try:
|
|
sock.connect((server, port))
|
|
except socket.error:
|
|
sock.close()
|
|
print "ERR: could not connect!"
|
|
exit(1)
|
|
|
|
client.onconnect()
|
|
|
|
try:
|
|
while True:
|
|
data = sock.recv(2048)
|
|
if not data:
|
|
break
|
|
for s in data.split('\r\n'):
|
|
if s.rstrip() != "":
|
|
client.handle(s)
|
|
except KeyboardInterrupt:
|
|
client.sendto("#pno",
|
|
"Aiiieuuuh, me suis pris un C-c dans les dents :/")
|
|
finally:
|
|
sock.close()
|
|
for m in client.modules:
|
|
if 'on_die' in dir(m.mod):
|
|
m.mod.on_die()
|
|
|