]> jfr.im git - erebus.git/blame - erebus.py
Added a few module featuresm depends needs testing!
[erebus.git] / erebus.py
CommitLineData
b25d4368 1#!/usr/bin/python
2
3#TODO: tons
4
a12f7519 5import os, sys, select, MySQLdb, MySQLdb.cursors
db50981b 6import bot, config, ctlmod
b25d4368 7
8class Erebus(object):
49a455aa 9 bots = {}
10 fds = {}
11 mods = {}
12 msghandlers = {}
13
14 class User(object):
15 chans = []
a4eacae2 16
49a455aa 17 def __init__(self, nick, auth=None):
18 self.nick = nick
676b2a85 19 self.auth = nick #TEMP
20 self.checklevel()
a4eacae2 21
49a455aa 22 def authed(self, auth):
23 self.auth = auth
24 self.checklevel()
a4eacae2 25
676b2a85 26 def checklevel(self):
27 if self.auth is None:
28 self.level = -1
29 else:
30 c = main.db.cursor()
31 c.execute("SELECT level FROM users WHERE auth = %s", (self.auth,))
32 row = c.fetchone()
33 if row is not None:
34 self.level = row['level']
35 else:
36 self.level = 0
37 return self.level
43b98e4e 38
49a455aa 39 def __str__(self): return self.nick
676b2a85 40 def __repr__(self): return "<User %r (%d)>" % (self.nick,self.level)
43b98e4e 41
49a455aa 42 class Channel(object):
43 users = []
44 voices = []
45 ops = []
a4eacae2 46
49a455aa 47 def __init__(self, name):
48 self.name = name
a4eacae2 49
49a455aa 50 def userjoin(self, user, level=None):
51 if user not in self.users: self.users.append(user)
52 if level == 'op' and user not in self.ops: self.ops.append(user)
53 if level == 'voice' and user not in self.voices: self.voices.append(user)
54 def userpart(self, user):
55 if user in self.ops: self.ops.remove(user)
56 if user in self.voices: self.voices.remove(user)
57 if user in self.users: self.users.remove(user)
a4eacae2 58
49a455aa 59 def userop(self, user):
60 if user in self.users and user not in self.ops: self.ops.append(user)
61 def uservoice(self, user):
62 if user in self.users and user not in self.voices: self.voices.append(user)
63 def userdeop(self, user):
64 if user in self.ops: self.ops.remove(user)
65 def userdevoice(self, user):
66 if user in self.voices: self.voices.remove(user)
67
68 def __str__(self): return self.name
69 def __repr__(self): return "<Channel %r>" % (self.name)
70
71 def __init__(self):
fd96a423 72 if os.name == "posix":
73 self.potype = "poll"
74 self.po = select.poll()
75 else: # f.e. os.name == "nt" (Windows)
76 self.potype = "select"
77 self.fdlist = []
49a455aa 78
79 def newbot(self, nick, user, bind, server, port, realname, chans):
80 if bind is None: bind = ''
81 obj = bot.Bot(self, nick, user, bind, server, port, realname, chans)
82 self.bots[nick.lower()] = obj
a4eacae2 83
49a455aa 84 def newfd(self, obj, fileno):
49a455aa 85 self.fds[fileno] = obj
fd96a423 86 if self.potype == "poll":
87 self.po.register(fileno, select.POLLIN)
88 elif self.potype == "select":
89 self.fdlist.append(fileno)
a4eacae2 90
43b98e4e 91 def bot(self, name): #get Bot() by name (nick)
49a455aa 92 return self.bots[name.lower()]
43b98e4e 93 def fd(self, fileno): #get Bot() by fd/fileno
49a455aa 94 return self.fds[fileno]
95
43b98e4e 96 def user(self, nick): #TODO #get User() by nick
49a455aa 97 return self.User(nick.lower())
43b98e4e 98 def channel(self, name): #TODO #get Channel() by name
49a455aa 99 return self.Channel(name.lower())
100
101 def poll(self):
fd96a423 102 if self.potype == "poll":
103 return [fd for (fd, ev) in self.po.poll()]
104 elif self.potype == "select":
105 return select.select(self.fdlist, [], [])[0]
49a455aa 106
107 def connectall(self):
108 for bot in self.bots.itervalues():
109 if bot.conn.state == 0:
110 bot.connect()
111
49a455aa 112 #bind functions
db50981b 113 def hook(self, word, handler):
db50981b 114 self.msghandlers[word] = handler
115 def unhook(self, word):
116 del self.msghandlers[word]
117 def hashook(self, word):
118 return word in self.msghandlers
119 def gethook(self, word):
120 return self.msghandlers[word]
b25d4368 121
122def setup():
db50981b 123 global cfg, main
124
125 cfg = config.Config('bot.config')
126 main = Erebus()
127
128 autoloads = [mod for mod, yes in cfg.items('autoloads') if int(yes) == 1]
129 for mod in autoloads:
130 ctlmod.load(main, mod)
131
a12f7519 132 main.db = MySQLdb.connect(host=cfg.dbhost, user=cfg.dbuser, passwd=cfg.dbpass, db=cfg.dbname, cursorclass=MySQLdb.cursors.DictCursor)
133 c = main.db.cursor()
134 c.execute("SELECT nick, user, bind FROM bots WHERE active = 1")
135 rows = c.fetchall()
136 c.close()
137 for row in rows:
138 c2 = main.db.cursor()
139 c2.execute("SELECT chname FROM chans WHERE bot = %s AND active = 1", (row['nick'],))
140 chans = [chdic['chname'] for chdic in c2.fetchall()]
141 c2.close()
142 main.newbot(row['nick'], row['user'], row['bind'], cfg.host, cfg.port, cfg.realname, chans)
143 main.connectall()
b25d4368 144
145def loop():
49a455aa 146 poready = main.poll()
fd96a423 147 for fileno in poready:
49a455aa 148 main.fd(fileno).getdata()
b25d4368 149
150if __name__ == '__main__':
151 setup()
49a455aa 152 while True: loop()