]>
jfr.im git - erebus.git/blob - erebus.py
3 # Erebus IRC bot - Author: John Runyon
6 import os
, sys
, select
, MySQLdb
, MySQLdb
. cursors
, time
, random
7 import bot
, config
, ctlmod
22 def __init__ ( self
, nick
, auth
= None ):
29 def msg ( self
, * args
, ** kwargs
):
30 main
. randbot
. msg ( self
, * args
, ** kwargs
)
33 return self
. auth
is not None
35 def authed ( self
, auth
):
36 if auth
== '0' : self
. auth
= None
37 else : self
. auth
= auth
. lower ()
45 if c
. execute ( "SELECT level FROM users WHERE auth = %s " , ( self
. auth
,)):
48 self
. glevel
= row
[ 'level' ]
56 self
. chans
. append ( chan
)
58 self
. chans
. remove ( chan
)
60 for chan
in self
. chans
:
61 self
. chans
. remove ( chan
)
62 def nickchange ( self
, newnick
):
65 def __str__ ( self
): return self
. nick
66 def __repr__ ( self
): return "<User %r ( %d )>" % ( self
. nick
, self
. glevel
)
68 class Channel ( object ):
69 def __init__ ( self
, name
, bot
):
79 if c
. execute ( "SELECT user, level FROM chusers WHERE chan = %s " , ( self
. name
,)):
81 while row
is not None :
82 self
. levels
[ row
[ 'user' ]] = row
[ 'level' ]
86 def msg ( self
, * args
, ** kwargs
):
87 self
. bot
. msg ( self
. name
, * args
, ** kwargs
)
89 def levelof ( self
, auth
):
93 if auth
in self
. levels
:
94 return self
. levels
[ auth
]
98 def setlevel ( self
, auth
, level
, savetodb
= True ):
102 if c
. execute ( "REPLACE INTO chusers (chan, user, level) VALUES ( %s , %s , %s )" , ( self
. name
, auth
, level
)):
103 self
. levels
[ auth
] = level
108 def userjoin ( self
, user
, level
= None ):
109 if user
not in self
. users
: self
. users
. append ( user
)
110 if level
== 'op' and user
not in self
. ops
: self
. ops
. append ( user
)
111 if level
== 'voice' and user
not in self
. voices
: self
. voices
. append ( user
)
112 def userpart ( self
, user
):
113 if user
in self
. ops
: self
. ops
. remove ( user
)
114 if user
in self
. voices
: self
. voices
. remove ( user
)
115 if user
in self
. users
: self
. users
. remove ( user
)
117 def userop ( self
, user
):
118 if user
in self
. users
and user
not in self
. ops
: self
. ops
. append ( user
)
119 def uservoice ( self
, user
):
120 if user
in self
. users
and user
not in self
. voices
: self
. voices
. append ( user
)
121 def userdeop ( self
, user
):
122 if user
in self
. ops
: self
. ops
. remove ( user
)
123 def userdevoice ( self
, user
):
124 if user
in self
. voices
: self
. voices
. remove ( user
)
126 def __str__ ( self
): return self
. name
127 def __repr__ ( self
): return "<Channel %r >" % ( self
. name
)
129 def __init__ ( self
, cfg
):
131 self
. trigger
= cfg
. trigger
132 if os
. name
== "posix" :
134 self
. po
= select
. poll ()
135 else : # f.e. os.name == "nt" (Windows)
136 self
. potype
= "select"
139 def newbot ( self
, nick
, user
, bind
, authname
, authpass
, server
, port
, realname
):
140 if bind
is None : bind
= ''
141 obj
= bot
. Bot ( self
, nick
, user
, bind
, authname
, authpass
, server
, port
, realname
)
142 self
. bots
[ nick
. lower ()] = obj
144 def newfd ( self
, obj
, fileno
):
145 self
. fds
[ fileno
] = obj
146 if self
. potype
== "poll" :
147 self
. po
. register ( fileno
, select
. POLLIN
)
148 elif self
. potype
== "select" :
149 self
. fdlist
. append ( fileno
)
151 def bot ( self
, name
): #get Bot() by name (nick)
152 return self
. bots
[ name
. lower ()]
153 def fd ( self
, fileno
): #get Bot() by fd/fileno
154 return self
. fds
[ fileno
]
155 def randbot ( self
): #get Bot() randomly
156 return self
. bots
[ random
. choice ( self
. bots
. keys ())]
158 def user ( self
, _nick
, justjoined
= False ):
160 if nick
in self
. users
:
161 return self
. users
[ nick
]
163 user
= self
. User ( _nick
)
164 self
. users
[ nick
] = user
167 self
. randbot (). conn
. send ( "WHO %s n %% ant,2" % ( nick
))
170 def channel ( self
, name
): #get Channel() by name
171 if name
. lower () in self
. chans
:
172 return self
. chans
[ name
. lower ()]
176 def newchannel ( self
, bot
, name
):
177 chan
= self
. Channel ( name
. lower (), bot
)
178 self
. chans
[ name
. lower ()] = chan
182 if self
. potype
== "poll" :
183 return [ fd
for ( fd
, ev
) in self
. po
. poll ()]
184 elif self
. potype
== "select" :
185 return select
. select ( self
. fdlist
, [], [])[ 0 ]
187 def connectall ( self
):
188 for bot
in self
. bots
. itervalues ():
189 if bot
. conn
. state
== 0 :
192 def module ( self
, name
):
193 return ctlmod
. modules
[ name
]
196 def hook ( self
, word
, handler
):
198 self
. msghandlers
[ word
]. append ( handler
)
200 self
. msghandlers
[ word
] = [ handler
]
201 def unhook ( self
, word
, handler
):
202 if word
in self
. msghandlers
and handler
in self
. msghandlers
[ word
]:
203 self
. msghandlers
[ word
]. remove ( handler
)
204 def hashook ( self
, word
):
205 return word
in self
. msghandlers
and len ( self
. msghandlers
[ word
]) != 0
206 def gethook ( self
, word
):
207 return self
. msghandlers
[ word
]
209 def hooknum ( self
, word
, handler
):
211 self
. numhandlers
[ word
]. append ( handler
)
213 self
. numhandlers
[ word
] = [ handler
]
214 def unhooknum ( self
, word
, handler
):
215 if word
in self
. numhandlers
and handler
in self
. numhandlers
[ word
]:
216 self
. numhandlers
[ word
]. remove ( handler
)
217 def hasnumhook ( self
, word
):
218 return word
in self
. numhandlers
and len ( self
. numhandlers
[ word
]) != 0
219 def getnumhook ( self
, word
):
220 return self
. numhandlers
[ word
]
222 def hookchan ( self
, chan
, handler
):
224 self
. chanhandlers
[ chan
]. append ( handler
)
226 self
. chanhandlers
[ chan
] = [ handler
]
227 def unhookchan ( self
, chan
, handler
):
228 if chan
in self
. chanhandlers
and handler
in self
. chanhandlers
[ chan
]:
229 self
. chanhandlers
[ chan
]. remove ( handler
)
230 def haschanhook ( self
, chan
):
231 return chan
in self
. chanhandlers
and len ( self
. chanhandlers
[ chan
]) != 0
232 def getchanhook ( self
, chan
):
233 return self
. chanhandlers
[ chan
]
236 class MyCursor ( MySQLdb
. cursors
. DictCursor
):
237 def execute ( self
, * args
, ** kwargs
):
238 print " %0 5.3f [SQL] [#] MyCursor.execute(self, %s , %s )" % ( time
. time () % 100000 , ', ' . join ([ repr ( i
) for i
in args
]), ', ' . join ([ str ( key
)+ "=" + repr ( kwargs
[ key
]) for key
in kwargs
]))
240 super ( self
.__ class
__ , self
). execute (* args
, ** kwargs
)
241 except MySQLdb
. MySQLError
as e
:
242 print " %0 5.3f [SQL] [!] MySQL error! %r " % ( time
. time () % 100000 , e
)
250 main
. db
= MySQLdb
. connect ( host
= cfg
. dbhost
, user
= cfg
. dbuser
, passwd
= cfg
. dbpass
, db
= cfg
. dbname
, cursorclass
= MyCursor
)
255 cfg
= config
. Config ( 'bot.config' )
258 autoloads
= [ mod
for mod
, yes
in cfg
. items ( 'autoloads' ) if int ( yes
) == 1 ]
259 for mod
in autoloads
:
260 ctlmod
. load ( main
, mod
)
264 if c
. execute ( "SELECT nick, user, bind, authname, authpass FROM bots WHERE active = 1" ):
268 main
. newbot ( row
[ 'nick' ], row
[ 'user' ], row
[ 'bind' ], row
[ 'authname' ], row
[ 'authpass' ], cfg
. host
, cfg
. port
, cfg
. realname
)
272 poready
= main
. poll ()
273 for fileno
in poready
:
274 for line
in main
. fd ( fileno
). getdata ():
275 main
. fd ( fileno
). parse ( line
)
277 if __name__
== '__main__' :