]> jfr.im git - erebus.git/blame - bot.py
SQL dump added
[erebus.git] / bot.py
CommitLineData
b25d4368 1#!/usr/bin/python
2
3#TODO: error checking
4
49a455aa 5import socket, sys
b25d4368 6
7#bots = {'erebus': bot.Bot(nick='Erebus', user='erebus', bind='', server='irc.quakenet.org', port=6667, realname='Erebus')}
8class Bot(object):
9 def __init__(self, parent, nick, user, bind, server, port, realname, chans):
10 self.parent = parent
11 self.nick = nick
a12f7519 12 self.user = user
13 self.realname = realname
b25d4368 14 self.chans = chans
15
a12f7519 16 self.conn = BotConnection(self, bind, server, port)
b25d4368 17 def connect(self):
49a455aa 18 if self.conn.connect():
19 self.parent.newfd(self, self.conn.socket.fileno())
20
b25d4368 21 def getdata(self):
22 for line in self.conn.read():
49a455aa 23 print self.nick, '[I]', line
a4eacae2 24
49a455aa 25 if not self.conn.registered():
26 pieces = line.split()
a4eacae2 27
49a455aa 28 if pieces[0] == "PING":
29 self.conn.send("PONG %s" % (pieces[1]))
a4eacae2 30
49a455aa 31 elif pieces[1] == "001":
32 self.conn.registered(True)
33 for c in self.chans:
34 self.join(c)
43b98e4e 35
49a455aa 36 else:
37 self.parse(line)
b25d4368 38 def parse(self, line):
39 pieces = line.split()
a4eacae2 40
49a455aa 41 if pieces[1] == "PRIVMSG":
42 nick = pieces[0].split('!')[0][1:]
43 user = self.parent.user(nick)
44 chan = self.parent.channel(pieces[2])
45 msg = ' '.join(pieces[3:])[1:]
46 self.parsemsg(user, chan, msg)
a4eacae2 47
49a455aa 48 elif pieces[0] == "PING":
49 self.conn.send("PONG %s" % (pieces[1]))
a4eacae2 50
49a455aa 51 elif pieces[1] == "JOIN":
52 nick = pieces[0].split('!')[0][1:]
53 user = self.parent.user(nick)
54 chan = self.parent.channel(pieces[2]) #TODO TODO TODO
55
56 def parsemsg(self, user, chan, msg):
57 if msg[0] == '!': #TODO check config for trigger
58 msg = msg[1:]
a4eacae2 59
49a455aa 60 else:
61 return
a4eacae2 62
49a455aa 63 pieces = msg.split()
64 cmd = pieces[0].upper()
a4eacae2 65
49a455aa 66 if cmd == "EVAL":
67 try: ret = eval(' '.join(pieces[1:]))
68 except: self.msg(chan, "Error: %s %s" % (sys.exc_info()[0], sys.exc_info()[1]))
69 else: self.msg(chan, "Done: %r" % (ret))
a4eacae2 70
49a455aa 71 elif cmd == "EXEC":
72 try: exec ' '.join(pieces[1:])
73 except: self.msg(chan, "Error: %s %s" % (sys.exc_info()[0], sys.exc_info()[1]))
74 else: self.msg(chan, "Done.")
a4eacae2 75
49a455aa 76 #TODO
77
78 def msg(self, target, msg):
79 if isinstance(target, self.parent.User): self.conn.send("NOTICE %s :%s" % (target.nick, msg))
80 elif isinstance(target, self.parent.Channel): self.conn.send("PRIVMSG %s :%s" % (target.name, msg))
81 elif isinstance(target, basestring):
82 if target[0] == '#': self.conn.send("PRIVMSG %s :%s" % (target, msg))
83 else: self.conn.send("NOTICE %s :%s" % (target, msg))
84 else: raise TypeError('Bot.msg() "target" must be Erebus.User, Erebus.Channel, or string')
a4eacae2 85
49a455aa 86 def join(self, chan):
87 self.conn.send("JOIN %s" % (chan))
a4eacae2 88
49a455aa 89 def part(self, chan):
90 self.conn.send("PART %s" % (chan))
a4eacae2 91
49a455aa 92 def quit(self, reason="Shutdown"):
93 self.conn.send("QUIT :%s" % (reason))
b25d4368 94
a12f7519 95 def __str__(self): return self.nick
96 def __repr__(self): return "<Bot %r>" % (self.nick)
97
b25d4368 98class BotConnection(object):
99 state = 0 # 0=disconnected, 1=registering, 2=connected
100
a12f7519 101 def __init__(self, parent, bind, server, port):
b25d4368 102 self.parent = parent
103 self.buffer = ''
104 self.socket = None
105
b25d4368 106 self.bind = bind
107 self.server = server
108 self.port = int(port)
b25d4368 109
110 def connect(self):
111 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
112 self.socket.bind((self.bind, 0))
113 self.socket.connect((self.server, self.port))
a12f7519 114 self.send("NICK %s" % (self.parent.nick))
115 self.send("USER %s 0 * :%s" % (self.parent.user, self.parent.realname))
b25d4368 116 self.state = 1
49a455aa 117 return True
b25d4368 118
119 def registered(self, done=False):
120 if done: self.state = 2
121 return self.state == 2
122
b25d4368 123 #TODO: rewrite send() to queue
124 def send(self, line):
a12f7519 125 print self.parent.nick, '[O]', line
b25d4368 126 self.write(line)
a4eacae2 127
b25d4368 128 def write(self, line):
b25d4368 129 self.socket.sendall(line+"\r\n")
a4eacae2 130
b25d4368 131 def read(self):
132 self.buffer += self.socket.recv(8192)
133 lines = []
a4eacae2 134
b25d4368 135 while '\r\n' in self.buffer:
136 pieces = self.buffer.split('\r\n', 1)
b25d4368 137 lines.append(pieces[0])
138 self.buffer = pieces[1]
a4eacae2 139
b25d4368 140 return lines
a12f7519 141
142 def __str__(self): return self.nick
143 def __repr__(self): return "<BotConnection %r (%r)>" % (self.socket.fileno(), self.parent.nick)