~ubuntu-branches/ubuntu/utopic/gozerbot/utopic

« back to all changes in this revision

Viewing changes to build/lib/gozerbot/plugs/irc.py

  • Committer: Package Import Robot
  • Author(s): Jeremy Malcolm
  • Date: 2012-04-03 21:58:28 UTC
  • mfrom: (3.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20120403215828-6mik0tzug5na93la
Tags: 0.99.1-2
* Removes logfiles on purge (Closes: #668767)
* Reverted location of installed files back to /usr/lib/gozerbot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# plugs/irc.py
 
2
#
 
3
#
 
4
 
 
5
""" irc related commands. """
 
6
 
 
7
__copyright__ = 'this file is in the public domain'
 
8
__gendocfirst__ = ['reconnect', 'join']
 
9
__gendoclast__ = ['part', ]
 
10
 
 
11
# gozerbot imports
 
12
from gozerbot.callbacks import callbacks
 
13
from gozerbot.fleet import fleet
 
14
from gozerbot.partyline import partyline
 
15
from gozerbot.commands import cmnds
 
16
from gozerbot.examples import examples
 
17
from gozerbot.plughelp import plughelp
 
18
from gozerbot.tests import tests
 
19
import gozerbot.threads.thr as thr
 
20
 
 
21
# basic imports
 
22
import Queue, sets
 
23
 
 
24
plughelp.add('irc', 'irc related commands')
 
25
 
 
26
ignorenicks = []
 
27
 
 
28
def handle_broadcast(bot, ievent):
 
29
 
 
30
    """ broadcast txt to all joined channels. """
 
31
 
 
32
    if not ievent.rest:
 
33
         ievent.missing('<txt>')
 
34
         return
 
35
 
 
36
    ievent.reply('broadcasting')
 
37
    fleet.broadcast(ievent.rest)
 
38
    partyline.say_broadcast(ievent.rest)
 
39
    ievent.reply('done')
 
40
 
 
41
cmnds.add('broadcast', handle_broadcast, 'OPER')
 
42
examples.add('broadcast', 'send a message to all channels and dcc users', 'broadcast good morning')
 
43
tests.add('broadcast testing testing')
 
44
 
 
45
def handle_alternick(bot, ievent):
 
46
 
 
47
    """ set alternative nick used if nick is already taken. """
 
48
 
 
49
    try:
 
50
        nick = ievent.args[0]
 
51
    except IndexError:
 
52
        ievent.reply('alternick is %s' % bot.state['alternick'])
 
53
        return
 
54
 
 
55
    ievent.reply('changing alternick to %s' % nick)
 
56
    bot.state['alternick'] = nick
 
57
    bot.state.save()
 
58
    ievent.reply('done')
 
59
 
 
60
cmnds.add('alternick', handle_alternick, 'OPER')
 
61
examples.add('alternick', 'get/set alertnick' , '1) alternick 2) alternick gozerbot2')
 
62
tests.add('alternick testbot', 'testbot')
 
63
 
 
64
def dojoin(bot, ievent):
 
65
 
 
66
    """ join <channel> [password]. """
 
67
 
 
68
    try:
 
69
        channel = ievent.args[0]
 
70
    except IndexError:
 
71
        ievent.missing("<channel> [password]")
 
72
        return
 
73
 
 
74
    try:
 
75
        password = ievent.args[1]
 
76
    except IndexError:
 
77
        password = None
 
78
 
 
79
    ievent.reply('joining %s' % channel)
 
80
    bot.join(channel, password=password)
 
81
    ievent.done()
 
82
 
 
83
cmnds.add('join', dojoin, ['OPER', 'JOIN'])
 
84
examples.add('join', 'join <channel> [password]', '1) join #test 2) join #test mekker')
 
85
tests.add('join #dunkbots')
 
86
 
 
87
def delchan(bot, ievent):
 
88
 
 
89
    """ delchan <channel>  .. remove channel from bot.channels. """
 
90
 
 
91
    try:
 
92
        chan = ievent.args[0].lower()
 
93
    except IndexError:
 
94
        ievent.missing("<channel>")
 
95
        return
 
96
 
 
97
    try:
 
98
        bot.state['joinedchannels'].remove(chan)
 
99
        bot.state.save()
 
100
    except ValueError:
 
101
        pass
 
102
 
 
103
    try:
 
104
        del bot.channels.data[chan]
 
105
        bot.channels.save()
 
106
    except KeyError:
 
107
        ievent.reply("no channel %s in database" % chan)
 
108
 
 
109
    ievent.done()
 
110
 
 
111
cmnds.add('delchan', delchan, 'OPER')
 
112
examples.add('delchan', 'delchan <channel> .. remove channel from bot.channels', 'delchan #mekker')
 
113
 
 
114
def dopart(bot, ievent):
 
115
 
 
116
    """ part [<channel>]. """
 
117
 
 
118
    if not ievent.rest:
 
119
        chan = ievent.channel
 
120
    else:
 
121
        chan = ievent.rest
 
122
 
 
123
    ievent.reply('leaving %s chan' % chan)
 
124
    bot.part(chan)
 
125
    ievent.done()
 
126
 
 
127
cmnds.add('part', dopart, 'OPER')
 
128
examples.add('part', 'part [<channel>]', '1) part 2) part #test')
 
129
tests.add('part #mekker')
 
130
 
 
131
def handle_channels(bot, ievent):
 
132
 
 
133
    """ channels .. show joined channels. """
 
134
 
 
135
    chans = bot.state['joinedchannels']
 
136
 
 
137
    if chans:
 
138
        ievent.reply("joined channels: ", chans, dot=True)
 
139
    else:
 
140
        ievent.reply('no channels joined')
 
141
 
 
142
cmnds.add('channels', handle_channels, ['USER', 'WEB'])
 
143
examples.add('channels', 'show what channels the bot is on', 'channels')
 
144
tests.add('channels', '#dunkbots')
 
145
 
 
146
def handle_chat(bot, ievent):
 
147
 
 
148
    """ chat .. start a bot initiated dcc chat session. """
 
149
 
 
150
    if not bot.type == 'irc':
 
151
        ievent.reply("chat only works on irc bots")
 
152
        return
 
153
 
 
154
    i = ievent
 
155
    thr.start_new_thread(bot._dcclisten, (i.nick, i.userhost, i.channel))
 
156
    ievent.reply('dcc chat request sent')
 
157
 
 
158
cmnds.add('chat', handle_chat, 'USER')
 
159
examples.add('chat', 'start a dcc chat session', 'chat')
 
160
tests.add('chat', 'sent')
 
161
 
 
162
def handle_cycle(bot, ievent):
 
163
 
 
164
    """ cycle .. recycle channel. """
 
165
 
 
166
    ievent.reply('cycling %s' % ievent.channel)
 
167
    bot.part(ievent.channel)
 
168
    try:
 
169
        key = bot.channels[ievent.channel.lower()]['key']
 
170
    except (KeyError, TypeError):
 
171
        key = None
 
172
 
 
173
    bot.join(ievent.channel, password=key)
 
174
    ievent.done()
 
175
 
 
176
cmnds.add('cycle', handle_cycle, 'OPER')
 
177
examples.add('cycle', 'part/join channel', 'cycle')
 
178
tests.add('cycle')
 
179
 
 
180
def handle_jump(bot, ievent):
 
181
 
 
182
    """ jump <server> <port> .. change server. """
 
183
 
 
184
    if bot.jabber:
 
185
        ievent.reply('jump only works on irc bots')
 
186
        return
 
187
    if len(ievent.args) != 2:
 
188
        ievent.missing('<server> <port>')
 
189
        return
 
190
    (server, port) = ievent.args
 
191
    ievent.reply('changing to server %s' % server)
 
192
    bot.shutdown()
 
193
    bot.server = server
 
194
    bot.port = port
 
195
    bot.connect()
 
196
    ievent.done()
 
197
 
 
198
cmnds.add('jump', handle_jump, 'OPER')
 
199
examples.add('jump', 'jump <server> <port> .. switch server', 'jump localhost 6667')
 
200
 
 
201
def modecb(bot, ievent):
 
202
 
 
203
    """ callback to detect change of channel key. """
 
204
 
 
205
    if ievent.postfix.find('+k') != -1:
 
206
        key = ievent.postfix.split('+k')[1]
 
207
        bot.channels[ievent.channel.lower()]['key'] = key
 
208
 
 
209
callbacks.add('MODE', modecb)
 
210
 
 
211
def handle_nick(bot, ievent):
 
212
 
 
213
    """ nick <nickname> .. change bot's nick. """
 
214
 
 
215
    if bot.jabber:
 
216
        ievent.reply('nick works only on irc bots')
 
217
        return
 
218
 
 
219
    try:
 
220
        nick = ievent.args[0]
 
221
    except IndexError:
 
222
        ievent.missing('<nickname>')
 
223
        return
 
224
 
 
225
    ievent.reply('changing nick to %s' % nick)
 
226
    bot.donick(nick, setorig=1, save=1)
 
227
    ievent.done()
 
228
 
 
229
cmnds.add('nick', handle_nick, 'OPER', threaded=True)
 
230
examples.add('nick', 'nick <nickname> .. set nick of the bot', 'nick mekker')
 
231
tests.add('nick miep')
 
232
 
 
233
def handle_sendraw(bot, ievent):
 
234
 
 
235
    """ sendraw <txt> .. send raw text to the server. """
 
236
 
 
237
    ievent.reply('sending raw txt')
 
238
    bot.sendraw(ievent.rest)
 
239
    ievent.done()
 
240
 
 
241
cmnds.add('sendraw', handle_sendraw, 'SENDRAW')
 
242
examples.add('sendraw', 'sendraw <txt> .. send raw string to the server', \
 
243
'sendraw PRIVMSG #test :yo!')
 
244
 
 
245
def handle_nicks(bot, ievent):
 
246
 
 
247
    """ return nicks on channel. """
 
248
 
 
249
    if bot.jabber:
 
250
        ievent.reply('nicks only works on irc bots')
 
251
        return
 
252
 
 
253
    try:
 
254
        chan = ievent.args[0]
 
255
    except IndexError:
 
256
        chan = ievent.channel
 
257
 
 
258
    queue = Queue.Queue()
 
259
    # set callback for name info response
 
260
    wait353 = bot.wait.register('353', chan, queue)
 
261
    # 366 is end of names response list
 
262
    wait366 = bot.wait.register('366', chan, queue)
 
263
    result = ""
 
264
    ievent.reply('searching for nicks')
 
265
    bot.names(chan)
 
266
 
 
267
    while(1):
 
268
        qres = queue.get()
 
269
        if qres == None:
 
270
            break
 
271
        if qres.cmnd == '366':
 
272
            break
 
273
        else:
 
274
            result += "%s " % qres.txt
 
275
 
 
276
    bot.wait.delete(wait353)
 
277
    bot.wait.delete(wait366)
 
278
 
 
279
    if result:
 
280
        res = result.split()
 
281
 
 
282
        for nick in res:
 
283
            for i in ignorenicks:
 
284
                if i in nick:
 
285
                    try:
 
286
                        res.remove(nick)
 
287
                    except ValueError:
 
288
                        pass
 
289
 
 
290
        res.sort()
 
291
        ievent.reply("nicks on %s (%s): " % (chan, bot.server), res)
 
292
    else:
 
293
        ievent.reply("can't get nicks of channel %s" % chan)
 
294
 
 
295
cmnds.add('nicks', handle_nicks, ['OPER', 'WEB'], threaded=True)
 
296
examples.add('nicks', 'show nicks on channel the command was given in', 'nicks')
 
297
tests.add('nicks', "can't")
 
298
 
 
299
def handle_silent(bot, ievent):
 
300
 
 
301
    """ set silent mode of channel. """
 
302
 
 
303
    if ievent.rest:
 
304
        channel = ievent.rest.split()[0].lower()
 
305
    else:
 
306
        if ievent.cmnd == 'DCC':
 
307
            return
 
308
        channel = ievent.channel
 
309
 
 
310
    ievent.reply('putting %s to silent mode' % channel)
 
311
 
 
312
    try:
 
313
        bot.channels[channel]['silent'] = 1
 
314
    except (KeyError, TypeError):
 
315
        ievent.reply("no %s channel in database" % channel)
 
316
        return 
 
317
    ievent.done()
 
318
 
 
319
cmnds.add('silent', handle_silent, 'OPER')
 
320
examples.add('silent', 'set silent mode on channel the command was given in', 'silent')
 
321
tests.add('silent').add('loud')
 
322
 
 
323
def handle_loud(bot, ievent):
 
324
 
 
325
    """ loud .. enable output to the channel. """
 
326
 
 
327
    if ievent.rest:
 
328
        channel = ievent.rest.split()[0].lower()
 
329
    else:
 
330
        if ievent.cmnd == 'DCC':
 
331
            return
 
332
        channel = ievent.channel
 
333
 
 
334
    ievent.reply('putting %s into loud mode' % ievent.channel)
 
335
 
 
336
    try:
 
337
        bot.channels[channel]['silent'] = 0
 
338
    except (KeyError, TypeError):
 
339
        ievent.reply("no %s channel in database" % channel)
 
340
        return 
 
341
 
 
342
    ievent.done()
 
343
 
 
344
cmnds.add('loud', handle_loud, 'OPER')
 
345
examples.add('loud', 'disable silent mode of channel command was given in', 'loud')
 
346
tests.add('loud')
 
347
 
 
348
def handle_withnotice(bot, ievent):
 
349
 
 
350
    """ withnotice .. make bot use notice in channel. """
 
351
 
 
352
    if ievent.rest:
 
353
        channel = ievent.rest.split()[0].lower()
 
354
    else:
 
355
        if ievent.cmnd == 'DCC':
 
356
            return
 
357
        channel = ievent.channel
 
358
 
 
359
    ievent.reply('setting notice in %s' % channel)
 
360
 
 
361
    try:
 
362
        bot.channels[channel]['notice'] = 1
 
363
    except (KeyError, TypeError):
 
364
        ievent.reply("no %s channel in database" % channel)
 
365
        return 
 
366
 
 
367
    ievent.done()
 
368
    
 
369
cmnds.add('withnotice', handle_withnotice, 'OPER')
 
370
examples.add('withnotice', 'make bot use notice on channel the command was given in', 'withnotice')
 
371
tests.add('withnotice').add('withprivmsg')
 
372
 
 
373
def handle_withprivmsg(bot, ievent):
 
374
 
 
375
    """ withprivmsg .. make bot use privmsg in channel. """
 
376
 
 
377
    if ievent.rest:
 
378
        channel = ievent.rest.split()[0].lower()
 
379
    else:
 
380
        if ievent.cmnd == 'DCC':
 
381
            return
 
382
        channel = ievent.channel
 
383
 
 
384
    ievent.reply('setting privmsg in %s' % ievent.channel)
 
385
 
 
386
    try:
 
387
        bot.channels[channel]['notice'] = 0
 
388
    except (KeyError, TypeError):
 
389
        ievent.reply("no %s channel in database" % channel)
 
390
        return 
 
391
 
 
392
    ievent.done()
 
393
 
 
394
cmnds.add('withprivmsg', handle_withprivmsg, 'OPER')
 
395
examples.add('withprivmsg', 'make bot use privmsg on channel command was given in', 'withprivmsg')
 
396
tests.add('withprivmsg')
 
397
 
 
398
def handle_reconnect(bot, ievent):
 
399
 
 
400
    """ reconnect .. reconnect to server. """
 
401
 
 
402
    ievent.reply('reconnecting')
 
403
    bot.reconnect()
 
404
    ievent.done()
 
405
 
 
406
cmnds.add('reconnect', handle_reconnect, 'OPER', threaded=True)
 
407
examples.add('reconnect', 'reconnect to server', 'reconnect')
 
408
 
 
409
def handle_channelmode(bot, ievent):
 
410
 
 
411
    """ show channel mode. """
 
412
 
 
413
    if bot.type != 'irc':
 
414
        ievent.reply('channelmode only works on irc bots')
 
415
        return
 
416
 
 
417
    try:
 
418
        chan = ievent.args[0].lower()
 
419
    except IndexError:
 
420
        chan = ievent.channel.lower()
 
421
 
 
422
    if not chan in bot.state['joinedchannels']:
 
423
        ievent.reply("i'm not on channel %s" % chan)
 
424
        return
 
425
 
 
426
    ievent.reply('channel mode of %s is %s' % (chan, bot.channels.get(chan, 'mode')))
 
427
 
 
428
cmnds.add('channelmode', handle_channelmode, 'OPER')
 
429
examples.add('channelmode', 'show mode of channel', '1) channelmode 2) channelmode #test')
 
430
tests.add('channelmode --chan #dunkbots')
 
431
 
 
432
def handle_action(bot, ievent):
 
433
 
 
434
    """ make the bot send an action string. """
 
435
 
 
436
    try:
 
437
        channel, txt = ievent.rest.split(' ', 1)
 
438
    except ValueError:
 
439
        ievent.missing('<channel> <txt>')
 
440
        return
 
441
 
 
442
    bot.action(channel, txt)
 
443
 
 
444
cmnds.add('action', handle_action, ['ACTION', 'OPER'], speed=1)
 
445
examples.add('action', 'send an action message', 'action #test yoo dudes')
 
446
tests.add('action #dunkbots mekker')
 
447
 
 
448
def handle_say(bot, ievent):
 
449
 
 
450
    """ make the bot say something. """
 
451
 
 
452
    try:
 
453
        channel, txt = ievent.rest.split(' ', 1)
 
454
    except ValueError:
 
455
        ievent.missing('<channel> <txt>')
 
456
        return
 
457
 
 
458
    bot.say(channel, txt)
 
459
 
 
460
cmnds.add('say', handle_say, ['SAY', 'OPER'], speed=1)
 
461
examples.add('say', 'send txt to channel/user', 'say #test good morning')
 
462
tests.add('say #dunkbots mekkerbot')
 
463
 
 
464
def handle_server(bot, ievent):
 
465
 
 
466
    """ show the server to which the bot is connected. """
 
467
 
 
468
    ievent.reply(bot.server)
 
469
 
 
470
cmnds.add('server', handle_server, 'OPER')
 
471
examples.add('server', 'show server hostname of bot', 'server')
 
472
tests.add('server')
 
473
 
 
474
def handle_voice(bot, ievent):
 
475
 
 
476
    """ give voice. """
 
477
 
 
478
    if bot.type != 'irc':
 
479
        ievent.reply('voice only works on irc bots')
 
480
        return
 
481
 
 
482
    if len(ievent.args)==0:
 
483
        ievent.missing('<nickname>')
 
484
        return
 
485
 
 
486
    ievent.reply('setting voide on %s' % str(ievent.args))
 
487
 
 
488
    for nick in sets.Set(ievent.args):
 
489
        bot.voice(ievent.channel, nick)
 
490
 
 
491
    ievent.done()
 
492
 
 
493
cmnds.add('voice', handle_voice, 'OPER')
 
494
examples.add('voice', 'give voice to user', 'voice test')
 
495
tests.add('voice dunker')