Mercurial > xib
comparison bot.py @ 232:02c58515edde
improved Bot._xmpp_message_handler
Signed-off-by: Charly COSTE <changaco@changaco.net>
author | Charly COSTE <changaco@changaco.net> |
---|---|
date | Sun, 07 Mar 2010 23:35:31 +0100 |
parents | d5a126cf119c |
children | 533a5db79389 |
comparison
equal
deleted
inserted
replaced
231:5f1e9211af03 | 232:02c58515edde |
---|---|
281 elif resource != bridge.bot.nickname: | 281 elif resource != bridge.bot.nickname: |
282 real_jid = None | 282 real_jid = None |
283 if item and item.has_attr('jid'): | 283 if item and item.has_attr('jid'): |
284 real_jid = item.getAttr('jid') | 284 real_jid = item.getAttr('jid') |
285 | 285 |
286 p = bridge.add_participant('xmpp', resource, real_jid) | 286 p = bridge.add_participant('xmpp', resource, real_jid=real_jid) |
287 | 287 |
288 # if we have the real jid check if the participant is a bot admin | 288 # if we have the real jid check if the participant is a bot admin |
289 if real_jid and isinstance(p, Participant): | 289 if real_jid and isinstance(p, Participant): |
290 for admin in self.admins: | 290 for admin in self.admins: |
291 if xmpp.protocol.JID(admin.jid).bareMatch(real_jid): | 291 if xmpp.protocol.JID(admin.jid).bareMatch(real_jid): |
319 xmpp_c = dispatcher._owner | 319 xmpp_c = dispatcher._owner |
320 | 320 |
321 if message.getBody() == None: | 321 if message.getBody() == None: |
322 return | 322 return |
323 | 323 |
324 | |
325 # Private message | |
324 if message.getType() == 'chat': | 326 if message.getType() == 'chat': |
325 from_bare_jid = unicode(message.getFrom().getNode()+'@'+message.getFrom().getDomain()) | 327 from_bare_jid = unicode(message.getFrom().getNode()+'@'+message.getFrom().getDomain()) |
326 for bridge in self.bridges: | 328 |
327 if from_bare_jid == bridge.xmpp_room_jid: | 329 try: |
328 # message comes from a room participant | 330 bridge = self.get_bridge(xmpp_room_jid=from_bare_jid) |
331 except KeyError: | |
332 bridge = None | |
333 | |
334 if bridge: | |
335 # message comes from a room participant | |
336 self.error(2, 'Received XMPP chat message.\n'+message.__str__(fancy=1), debug=True) | |
337 | |
338 try: | |
339 from_ = bridge.get_participant(message.getFrom().getResource()) | |
340 to_ = bridge.get_participant(xmpp_c.nickname) | |
329 | 341 |
330 self.error(2, 'Received XMPP chat message.\n'+message.__str__(fancy=1), debug=True) | 342 from_.say_on_irc_to(to_.nickname, message.getBody()) |
331 | 343 |
332 try: | 344 except Bridge.NoSuchParticipantException: |
333 from_ = bridge.get_participant(message.getFrom().getResource()) | 345 if xmpp_c.nickname == self.nickname: |
334 to_ = bridge.get_participant(xmpp_c.nickname) | 346 r = self.respond(str(message.getBody()), participant=from_) |
335 | 347 if isinstance(r, basestring) and len(r) > 0: |
336 from_.say_on_irc_to(to_.nickname, message.getBody()) | 348 s = xmpp.protocol.Message(to=message.getFrom(), body=r, typ='chat') |
337 | 349 self.error(2, 'Sending\n'+s.__str__(fancy=1), debug=True) |
338 except Bridge.NoSuchParticipantException: | 350 xmpp_c.send(s) |
339 if xmpp_c.nickname == self.nickname: | 351 else: |
340 r = self.respond(str(message.getBody()), participant=from_) | 352 self.error(1, 'won\'t answer.', debug=True) |
341 if isinstance(r, basestring) and len(r) > 0: | |
342 s = xmpp.protocol.Message(to=message.getFrom(), body=r, typ='chat') | |
343 self.error(2, 'Sending\n'+s.__str__(fancy=1), debug=True) | |
344 xmpp_c.send(s) | |
345 else: | |
346 self.error(1, 'won\'t answer.', debug=True) | |
347 return | |
348 self.error(say_levels.debug, 'XMPP chat message not relayed', no_debug_add='\n'+message.__str__(fancy=1)) | |
349 return | 353 return |
350 | 354 self.error(say_levels.debug, 'XMPP chat message not relayed', no_debug_add='\n'+message.__str__(fancy=1)) |
351 # message does not come from a room | 355 return |
352 if xmpp_c.nickname == self.nickname: | 356 |
357 else: | |
358 # message does not come from a room participant | |
359 if xmpp_c.nickname != self.nickname: | |
360 self.error(1, 'Ignoring XMPP chat message not received on bot connection.', debug=True) | |
361 return | |
362 | |
353 self.error(2, 'Received XMPP chat message.\n'+message.__str__(fancy=1), debug=True) | 363 self.error(2, 'Received XMPP chat message.\n'+message.__str__(fancy=1), debug=True) |
354 | 364 |
355 # Find out if the message comes from a bot admin | 365 # Find out if the message comes from a bot admin |
356 bot_admin = False | 366 bot_admin = False |
357 for admin in self.admins: | 367 for admin in self.admins: |
363 r = self.respond(str(message.getBody()), bot_admin=bot_admin) | 373 r = self.respond(str(message.getBody()), bot_admin=bot_admin) |
364 if isinstance(r, basestring) and len(r) > 0: | 374 if isinstance(r, basestring) and len(r) > 0: |
365 s = xmpp.protocol.Message(to=message.getFrom(), body=r, typ='chat') | 375 s = xmpp.protocol.Message(to=message.getFrom(), body=r, typ='chat') |
366 self.error(2, 'Sending\n'+s.__str__(fancy=1), debug=True) | 376 self.error(2, 'Sending\n'+s.__str__(fancy=1), debug=True) |
367 xmpp_c.send(s) | 377 xmpp_c.send(s) |
368 | 378 |
369 else: | 379 |
370 self.error(1, 'Ignoring XMPP chat message not received on bot connection.', debug=True) | 380 # MUC message |
371 | |
372 elif message.getType() == 'groupchat': | 381 elif message.getType() == 'groupchat': |
373 # message comes from a room | |
374 | 382 |
375 for child in message.getChildren(): | 383 for child in message.getChildren(): |
376 if child.getName() == 'delay': | 384 if child.getName() == 'delay': |
377 # MUC delayed message | 385 # MUC delayed message |
378 return | 386 return |
379 | 387 |
380 if xmpp_c.nickname != self.nickname: | 388 if xmpp_c.nickname != self.nickname: |
381 self.error(1, 'Ignoring XMPP MUC message not received on bot connection.', debug=True) | 389 self.error(1, 'Ignoring XMPP MUC message not received on bot connection.', debug=True) |
382 return | 390 return |
383 | 391 |
384 | |
385 from_ = xmpp.protocol.JID(message.getFrom()) | 392 from_ = xmpp.protocol.JID(message.getFrom()) |
386 | 393 |
387 if unicode(from_.getResource()) == self.nickname: | 394 resource = unicode(from_.getResource()) |
395 | |
396 if resource == self.nickname: | |
388 self.error(1, 'Ignoring XMPP MUC message sent by self.', debug=True) | 397 self.error(1, 'Ignoring XMPP MUC message sent by self.', debug=True) |
389 return | 398 return |
390 | 399 |
391 room_jid = unicode(from_.getNode()+'@'+from_.getDomain()) | 400 room_jid = unicode(from_.getNode()+'@'+from_.getDomain()) |
392 for bridge in self.bridges: | 401 bridge = self.get_bridge(xmpp_room_jid=room_jid) |
393 if room_jid == bridge.xmpp_room_jid: | 402 |
394 resource = unicode(from_.getResource()) | 403 if resource == '': |
395 if resource == '': | 404 # message comes from the room itself |
396 # message comes from the room itself | 405 self.error(1, 'Ignoring XMPP groupchat message sent by the room.', debug=True) |
397 self.error(1, 'Ignoring XMPP groupchat message sent by the room.', debug=True) | 406 return |
398 return | 407 else: |
399 else: | 408 # message comes from a participant of the room |
400 # message comes from a participant of the room | 409 self.error(2, 'Received XMPP groupchat message.\n'+message.__str__(fancy=1), debug=True) |
401 self.error(2, 'Received XMPP groupchat message.\n'+message.__str__(fancy=1), debug=True) | 410 |
402 | 411 try: |
403 try: | 412 participant = bridge.get_participant(resource) |
404 participant = bridge.get_participant(resource) | 413 participant.say_on_irc(message.getBody()) |
405 except Bridge.NoSuchParticipantException: | 414 except Bridge.NoSuchParticipantException: |
406 if resource != self.nickname: | 415 bridge.say_on_behalf(resource, message.getBody(), 'irc', action=(message.getBody()[:4] == '/me ')) |
407 self.error(say_levels.debug, 'NoSuchParticipantException "'+resource+'" on "'+str(bridge)+'", WTF ?', no_debug_add='\n'+message.__str__(fancy=1)) | 416 |
408 return | 417 return |
409 | 418 |
410 participant.say_on_irc(message.getBody()) | 419 |
411 return | 420 # Error message |
412 | |
413 elif message.getType() == 'error': | 421 elif message.getType() == 'error': |
414 for b in self.bridges: | 422 try: |
415 if message.getFrom() == b.xmpp_room_jid: | 423 b = self.get_bridge(xmpp_room_jid=message.getFrom()) |
416 # message comes from a room | 424 except KeyError: |
417 for c in message.getChildren(): | 425 self.error(say_levels.debug, 'received unknown error message\n'+message.__str__(fancy=1)) |
418 if c.getName() == 'error': | 426 return |
419 for cc in c.getChildren(): | 427 |
420 if cc.getNamespace() == 'urn:ietf:params:xml:ns:xmpp-stanzas' and cc.getName() != 'text': | 428 for c in message.getChildren(): |
421 err = cc.getName() | 429 if c.getName() == 'error': |
422 if err in ['not-acceptable', 'not-allowed']: | 430 for cc in c.getChildren(): |
423 # we sent a message to a room we are not in | 431 if cc.getNamespace() == 'urn:ietf:params:xml:ns:xmpp-stanzas' and cc.getName() != 'text': |
424 # can be due to a MUC server restart | 432 err = cc.getName() |
425 # can be a concurrency bug | 433 if err in ['not-acceptable', 'not-allowed']: |
426 if xmpp_c.nickname == self.nickname: | 434 # we sent a message to a room we are not in |
427 b.restart(message='Automatic restart of bridge') | 435 # can be due to a MUC server restart |
428 else: | 436 # can be a concurrency bug |
429 try: | 437 if xmpp_c.nickname == self.nickname: |
430 p = b.get_participant(xmpp_c.nickname) | 438 b.restart(message='Automatic restart of bridge') |
431 p.say_on_XMPP_through_bridge(message.getBody()) | 439 else: |
432 except Bridge.NoSuchParticipantException: | 440 try: |
433 b.restart(message='Automatic restart of bridge') | 441 p = b.get_participant(xmpp_c.nickname) |
434 | 442 p.say_on_XMPP_through_bridge(message.getBody()) |
435 elif err == 'forbidden': | 443 except Bridge.NoSuchParticipantException: |
436 # we don't have the permission to speak | 444 b.restart(message='Automatic restart of bridge') |
437 # let's remove the bridge and tell admins | 445 |
438 self.error(say_levels.error, 'Not allowed to speak on the XMPP MUC of bridge '+str(b)+', stopping it', send_to_admins=True) | 446 elif err == 'forbidden': |
439 b.stop(message='Not allowed to speak on the XMPP MUC, stopping the bridge') | 447 # we don't have the permission to speak |
440 else: | 448 # let's remove the bridge and tell admins |
441 self.error(say_levels.debug, 'recevied unknown error message\n'+message.__str__(fancy=1)) | 449 self.error(say_levels.error, 'Not allowed to speak on the XMPP MUC of bridge '+str(b)+', stopping it', send_to_admins=True) |
442 return | 450 b.stop(message='Not allowed to speak on the XMPP MUC, stopping the bridge') |
443 | 451 else: |
444 self.error(say_levels.debug, 'received unknown error message\n'+message.__str__(fancy=1)) | 452 self.error(say_levels.debug, 'recevied unknown error message\n'+message.__str__(fancy=1)) |
445 | 453 |
454 return | |
455 | |
456 | |
457 # Unknown message type | |
446 else: | 458 else: |
447 self.error(say_levels.debug, 'Received XMPP message of unknown type "'+str(message.getType())+'".\n'+message.__str__(fancy=1)) | 459 self.error(say_levels.debug, 'Received XMPP message of unknown type "'+str(message.getType())+'".\n'+message.__str__(fancy=1)) |
448 | 460 |
449 | 461 |
450 def _irc_event_handler(self, connection, event): | 462 def _irc_event_handler(self, connection, event): |
643 else: | 655 else: |
644 action = False | 656 action = False |
645 if isinstance(from_, Participant): | 657 if isinstance(from_, Participant): |
646 from_.say_on_xmpp(message, action=action) | 658 from_.say_on_xmpp(message, action=action) |
647 else: | 659 else: |
648 bridge.say_on_behalf(source_nickname, message, action=action) | 660 bridge.say_on_behalf(source_nickname, message, 'xmpp', action=action) |
649 return | 661 return |
650 | 662 |
651 | 663 |
652 # Mode event | 664 # Mode event |
653 if event.eventtype() == 'mode': | 665 if event.eventtype() == 'mode': |
718 | 730 |
719 See Bot.iter_bridges for the list of args""" | 731 See Bot.iter_bridges for the list of args""" |
720 | 732 |
721 bridges = [b for b in self.iter_bridges(**kwargs)] | 733 bridges = [b for b in self.iter_bridges(**kwargs)] |
722 if len(bridges) == 0: | 734 if len(bridges) == 0: |
723 raise Exception, 'no bridge matching '+str(kwargs) | 735 raise KeyError, 'no bridge matching '+str(kwargs) |
724 elif len(bridges) > 1: | 736 elif len(bridges) > 1: |
725 raise Exception, 'more than one bridge matching '+str(kwargs)+'\n'+'\n'.join([str(b) for b in bridges]) | 737 raise Exception, 'more than one bridge matching '+str(kwargs)+'\n'+'\n'.join([str(b) for b in bridges]) |
726 return bridges[0] | 738 return bridges[0] |
727 | 739 |
728 | 740 |