6
the bot can relay between different bots both IRC and Jabber ones.
7
relay uses the following format.
9
<botname> <channel> <botname> <channel>
11
<------ from -----> <------- to ------>
14
__copyright__ = 'this file is in the public domain'
15
__gendoclast__ = ['relay-del', ]
17
from gozerbot.commands import cmnds
18
from gozerbot.examples import examples
19
from gozerbot.callbacks import callbacks, jcallbacks
20
from gozerbot.fleet import fleet
21
from gozerbot.monitor import saymonitor, jabbermonitor
22
from gozerbot.datadir import datadir
23
from gozerbot.pdol import Pdol
24
from gozerbot.plughelp import plughelp
25
from gozerbot.ignore import shouldignore
26
from gozerbot.generic import rlog
27
from gozerbot.thr import start_new_thread
30
plughelp.add('relay', 'relay between fleet bots or channels')
34
""" relay is implemented as a pickled dict of lists """
36
def check(self, botname, channel, txt, fromm=None):
37
""" check if we relay on (botname, channel) .. if so do output """
38
channel = channel.lower()
39
if self.data.has_key((botname, channel)):
40
for i in self.data[(botname, channel)]:
41
if i != (botname, channel):
42
bot = fleet.byname(i[0])
44
if txt.count('[%s]' % bot.nick) > 0:
48
bot.outputnolog(i[1], txt, 'msg', fromm=fromm)
50
def wouldrelay(self, botname, channel):
51
""" check if (botname, channel) would relay """
52
return self.data.has_key((botname, channel.lower()))
54
def channels(self, botname):
55
""" show channels that are relayed on bot """
57
for i in self.data.keys():
59
result.append(i[1].lower())
63
""" called after reload """
64
saymonitor.add('relay', saycb, prerelaysay, True)
65
jabbermonitor.add('relay', jabbersaycb, jabberprerelaysay, True)
68
relay = Relay(datadir + os.sep + 'relay')
73
""" return number of relays """
74
return len(relay.data)
76
def prerelay(bot, ievent):
78
if shouldignore(ievent.userhost):
80
return relay.wouldrelay(bot.name, ievent.channel)
82
def cbrelayquit(bot, ievent):
83
""" relay quit callback """
85
nick = ievent.nick.lower()
86
if nick in bot.splitted:
89
for i in bot.userchannels[nick]:
90
if i in bot.state['joinedchannels']:
91
relay.check(bot.name, i, "%s (%s) quit %s - %s" % \
92
(ievent.nick, ievent.userhost, bot.server, ievent.txt))
94
rlog(10, 'relay', 'missing %s in userchannels' % nick)
96
callbacks.add('QUIT', cbrelayquit, nr=0, threaded=True)
98
def cbrelaykick(bot, ievent):
99
""" relay kick callback """
100
relay.check(bot.name, ievent.channel, "%s kicked %s from %s (%s) - %s" % \
101
(ievent.nick, ievent.arguments[1], ievent.channel, bot.server, ievent.txt))
103
callbacks.add('KICK', cbrelaykick, prerelay, threaded=True)
105
def cbrelaynick(bot, ievent):
106
""" relay nick callback """
107
nick = ievent.nick.lower()
109
for i in bot.userchannels[nick]:
110
if i in bot.state['joinedchannels']:
111
relay.check(bot.name, i, "%s is now known as %s" % \
112
(ievent.nick, ievent.txt))
114
rlog(10, 'relay', 'missing %s in userchannels' % nick)
116
callbacks.add('NICK', cbrelaynick, threaded=True)
118
def cbrelaytopic(bot, ievent):
119
""" relay topic callback """
120
relay.check(bot.name, ievent.channel, "%s changed topic to %s" % \
121
(ievent.nick, ievent.txt))
123
callbacks.add('TOPIC', cbrelaytopic, prerelay, threaded=True)
125
def cbrelaymode(bot, ievent):
126
""" callback for MODE events """
127
relay.check(bot.name, ievent.channel, "mode change on %s by %s \
128
(%s): %s" % (bot.server, ievent.nick, ievent.userhost, ievent.postfix))
130
callbacks.add('MODE', cbrelaymode, prerelay, threaded=True)
132
def cbrelaypriv(bot, ievent):
133
""" PRIVMSG relay callback """
136
if ievent.txt[0] == '\001' and ievent.txt.find('ACTION') != -1:
137
result = "[%s] *** %s" % (ievent.nick, ievent.origtxt[8:-1])
139
result = "[%s] %s" % (ievent.nick, ievent.origtxt)
140
relay.check(bot.name, ievent.channel, result, fromm=ievent.userhost)
142
callbacks.add('PRIVMSG', cbrelaypriv, prerelay, threaded=True)
144
def cbMessage(bot, msg):
145
""" jabber relay message callback """
146
if msg.usercmnd and not msg.groupchat:
149
result = "[%s] %s" % (msg.userhost, msg.origtxt)
151
result = "[%s] %s" % (msg.nick, msg.origtxt)
152
relay.check(bot.name, msg.channel, result, fromm=msg.userhost)
154
jcallbacks.add('Message', cbMessage, prerelay, threaded=True)
156
def cbPresence(bot, msg):
157
""" jabber relay presence callback """
160
if msg.type == 'unavailable':
161
result = "%s (%s) left %s" % (msg.nick, msg.userhost, msg.channel)
163
jabberjoined[msg.channel].remove(msg.nick)
164
except (ValueError, KeyError):
168
if msg.nick in jabberjoined[msg.channel]:
175
if not jabberjoined.has_key(msg.channel):
176
jabberjoined[msg.channel] = []
177
jabberjoined[msg.channel].append(msg.nick)
178
if bot.timejoined.has_key(msg.channel):
179
if time.time() - bot.timejoined[msg.channel] > 10:
180
result = "%s (%s) joined %s" % (msg.nick, msg.userhost, msg.channel)
182
relay.check(bot.name, msg.channel, result)
184
jcallbacks.add('Presence', cbPresence, prerelay, threaded=True)
186
def cbrelayjoin(bot, ievent):
187
""" JOIN relay callback """
188
if ievent.nick.lower() in bot.splitted:
190
relay.check(bot.name, ievent.channel, "%s (%s) joined %s on %s" % \
191
(ievent.nick, ievent.userhost, ievent.channel, bot.server))
193
callbacks.add('JOIN', cbrelayjoin, prerelay, nr=0, threaded=True)
195
def cbrelaypart(bot, ievent):
196
""" PART relay callback """
197
relay.check(bot.name, ievent.channel, "%s left %s on %s" % \
198
(ievent.nick, ievent.channel, bot.name))
200
callbacks.add('PART', cbrelaypart, prerelay, threaded=True)
202
def prerelaysay(botname, printto, txt, who, how, fromm):
203
""" precondition on bot.say callbacks """
204
return relay.wouldrelay(botname, printto)
206
def saycb(botname, printto, txt, who, how, fromm):
207
""" callback for bots output """
208
relay.check(botname, printto, "[bot] %s" % txt, fromm=fromm)
210
def jabberprerelaysay(bot, jmsg):
211
""" precondition on bot.say callbacks """
213
return relay.wouldrelay(bot.name, jmsg.to.split('/')[0])
215
def jabbersaycb(bot, jmsg):
216
""" callback for bots output """
217
if jmsg.botoutput and not jmsg.groupchat:
220
relay.check(bot.name, jmsg.to.split('/')[0], "[%s] %s" % (bot.nick, \
221
jmsg.txt), fromm=bot.name)
222
except AttributeError:
225
def handle_relaylist(bot, ievent):
226
""" realy-list .. list all relays """
228
for item, value in relay.data.iteritems():
230
for relayto in value:
231
tempstr += "(%s,%s) .. " % (relayto[0], relayto[1])
232
tempstr = tempstr[:-4]
233
result.append("(%s,%s) => %s" % (item[0], item[1], tempstr))
235
ievent.reply(result, dot=' | ')
237
ievent.reply('no relays')
239
cmnds.add('relay-list', handle_relaylist, 'OPER')
240
examples.add('relay-list', 'list the relays', 'relay-list')
242
def handle_relayadd(bot, ievent):
243
""" relay-add <botname> <channel> <botname> <channel> .. add a relay """
245
(botnamefrom, channelfrom, botnameto, channelto) = ievent.args
247
ievent.missing('<botnamefrom> <channelfrom> <botnameto> <channelto>')
249
relay[(botnamefrom, channelfrom.lower())] = (botnameto, channelto.lower())
251
ievent.reply('relay added')
253
cmnds.add('relay-add', handle_relayadd, 'OPER')
254
examples.add('relay-add', 'relay-add <botname> <channel> <botname> \
255
<channel> .. add bot/channel to relay', 'relay-add main #dunkbots test \
258
def handle_relaydel(bot, ievent):
259
""" relay-del <botname> <channel> <botname> <channel> .. delete a relay """
261
(botnamefrom, channelfrom, botnameto, channelto) = ievent.args
263
ievent.missing('<botnamefrom> <channelfrom> <botnameto> <channelto>')
266
relay.data[(botnamefrom, channelfrom.lower())].remove((botnameto, \
268
except (KeyError, ValueError):
269
ievent.reply("there is no %s %s - %s %s relay" % \
270
(botnamefrom, channelfrom, botnameto, channelto))
272
if len(relay[(botnamefrom, channelfrom.lower())]) == 0:
273
del relay[(botnamefrom, channelfrom.lower())]
275
ievent.reply('relay deleted')
277
cmnds.add('relay-del', handle_relaydel, 'OPER')
278
examples.add('relay-del', 'relay-del <botname> <channel> <botname> \
279
<channel> .. delete bot/channel from relay', 'relay-del main #dunkbots \