-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbot.py
117 lines (97 loc) · 3.52 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""
This is a base for an IRC bot.
"""
from . import connect
class Bot(object):
"""
An IRC bot interface.
"""
def __init__(self, com, ident):
"""
@com and @ident must be classes that presents a particular interface.
TODO: Describe the @com and @ident interfaces
"""
self.ident = ident()
self.conn = connect.IRCConn(self)
self.cmds = com(self)
self.conn.connect()
def handle_privmsg(self, tokens, sender):
chan = tokens.pop(0)
tokens[0] = tokens[0].strip(':')
if tokens[0] == self.ident.nick:
l = [tokens.pop(0)]
is_to_me = True
else:
l = []
is_to_me = False
nick, host = sender.split('!')
if chan == self.ident.nick:
chan = nick
data = {'channel': chan, 'sender': sender, 'is_to_me': is_to_me,
'nick': nick, 'host': host}
cmd = tokens[0]
try:
args = tokens[1:]
except IndexError:
args = []
if is_to_me and (cmd in getattr(self.cmds, 'addr_funcs', {})):
self.cmds.addr_funcs[cmd](args, data)
elif cmd in getattr(self.cmds, 'unaddr_funcs', {}):
self.cmds.unaddr_funcs[cmd](args, data)
else:
for func in getattr(self.cmds, 'all_privmsg_funcs', []):
func(l + tokens, data)
def handle_name_list(self, tokens):
tokens.pop(0) # get rid of our nick from the beginning of the msg.
tokens.pop(0) # get rid of the equals sign(?!)
chan = tokens.pop(0)
nicks = [t.lstrip(':') for t in tokens]
for func in getattr(self.cmds, 'on_name_list', []):
func(nicks, chan)
def handle_join(self, channel):
for func in getattr(self.cmds, 'on_join_funcs', []):
func(channel)
def handle_other_join(self, tokens, joiner):
chan = tokens.pop().strip(':')
nick, host = joiner.split('!')
data = {'channel': chan, 'joiner': joiner, 'nick': nick, 'host': host}
for func in getattr(self.cmds, 'other_join_funcs', []):
func(data)
def handle_kick(self, tokens, sender):
chan = tokens.pop(0)
tokens[0] = tokens[0].strip(':')
if tokens[0] == self.ident.nick:
tokens.pop(0)
is_about_me = True
else:
is_about_me = False
nick, host = sender.split('!')
data = {'channel': chan, 'sender': sender, 'nick': nick, 'host': host, 'kickee': tokens.pop(0)}
msg = tokens[0].lstrip(':') if tokens else None
if is_about_me:
for func in getattr(self.cmds, 'on_kicked_funcs', []):
func(msg, data)
else:
for func in getattr(self.cmds, 'other_kicked_funcs', []):
func(msg, data)
def main(self):
"""
Run the mainloop.
"""
self.conn.mainloop()
class BunBot(Bot):
"""
An IRC bot interface compatible with bunburya's original bot. This Bot()
supports command reloading, but is more stringent in its setup requirements.
"""
def __init__(self, confmod):
"""
@confmod must be a module with Identity() and CommandLib() classes.
These classes must follow the same protocol as the @ident and @com
arguments to Bot().
"""
Bot.__init__(self, confmod.CommandLib, confmod.Identity)
self.config = confmod
self.main()
def reload_cmds(self):
self.cmds = reload(self.config).CommandLib(self)