comparison bot.py @ 134:931a5edc7971

moved commands to a separate file Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Fri, 15 Jan 2010 23:11:25 +0100
parents e662ff6ecf50
children 9f39cead20cb
comparison
equal deleted inserted replaced
133:e662ff6ecf50 134:931a5edc7971
14 # You should have received a copy of the GNU General Public License 14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>. 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16
17 17
18 import re 18 import re
19 import shlex
20 import sys 19 import sys
21 import threading 20 import threading
22 from time import sleep 21 from time import sleep
23 import traceback 22 import traceback
24 import xml.parsers.expat 23 import xml.parsers.expat
25 24
26 from argparse_modified import ArgumentParser
27 from encoding import * 25 from encoding import *
28 import irclib 26 import irclib
29 import muc 27 import muc
30 xmpp = muc.xmpp 28 xmpp = muc.xmpp
31 del muc 29 del muc
32 30
33 from bridge import Bridge 31 from bridge import Bridge
34 from participant import Participant 32 from participant import Participant
33 import commands
35 34
36 35
37 class Bot(threading.Thread): 36 class Bot(threading.Thread):
38
39 commands = ['xmpp-participants', 'irc-participants', 'bridges']
40 admin_commands = ['add-bridge', 'add-xmpp-admin', 'change-bridge-mode', 'halt', 'remove-bridge', 'restart-bot', 'restart-bridge', 'stop-bridge']
41 37
42 def __init__(self, jid, password, nickname, admins_jid=[], error_fd=sys.stderr, debug=False): 38 def __init__(self, jid, password, nickname, admins_jid=[], error_fd=sys.stderr, debug=False):
43 threading.Thread.__init__(self) 39 threading.Thread.__init__(self)
44 self.bare_jid = xmpp.protocol.JID(jid=jid) 40 self.bare_jid = xmpp.protocol.JID(jid=jid)
45 self.bare_jid.setResource('') 41 self.bare_jid.setResource('')
822 self.bridges.remove(bridge) 818 self.bridges.remove(bridge)
823 bridge.stop(message) 819 bridge.stop(message)
824 820
825 821
826 def respond(self, message, participant=None, bot_admin=False): 822 def respond(self, message, participant=None, bot_admin=False):
827 ret = '' 823 if isinstance(participant, Participant):
828 command = shlex.split(message) 824 bridge = participant.bridge
829 args_array = [] 825 if bot_admin != participant.bot_admin:
830 if len(command) > 1: 826 bot_admin = participant.bot_admin
831 args_array = command[1:]
832 command = command[0]
833
834 if isinstance(participant, Participant) and bot_admin != participant.bot_admin:
835 bot_admin = participant.bot_admin
836
837 if command == 'xmpp-participants':
838 if not isinstance(participant, Participant):
839 for b in self.bridges:
840 xmpp_participants_nicknames = b.get_participants_nicknames_list(protocols=['xmpp'])
841 ret += '\nparticipants on '+b.xmpp_room_jid+' ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
842 return ret
843 else:
844 xmpp_participants_nicknames = participant.bridge.get_participants_nicknames_list(protocols=['xmpp'])
845 return '\nparticipants on '+participant.bridge.xmpp_room_jid+' ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
846
847 elif command == 'irc-participants':
848 if not isinstance(participant, Participant):
849 for b in self.bridges:
850 irc_participants_nicknames = b.get_participants_nicknames_list(protocols=['irc'])
851 ret += '\nparticipants on '+b.irc_room+' at '+b.irc_server+' ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
852 return ret
853 else:
854 irc_participants_nicknames = participant.bridge.get_participants_nicknames_list(protocols=['irc'])
855 return '\nparticipants on '+participant.bridge.irc_room+' at '+participant.bridge.irc_server+' ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
856
857 elif command == 'bridges':
858 parser = ArgumentParser(prog=command)
859 parser.add_argument('--show-mode', default=False, action='store_true')
860 parser.add_argument('--show-say-level', default=False, action='store_true')
861 parser.add_argument('--show-participants', default=False, action='store_true')
862 try:
863 args = parser.parse_args(args_array)
864 except ArgumentParser.ParseException as e:
865 return '\n'+e.args[1]
866 ret = 'List of bridges:'
867 for i, b in enumerate(self.bridges):
868 ret += '\n'+str(i+1)+' - '+str(b)
869 if args.show_mode:
870 ret += ' - mode='+b.mode
871 if args.show_say_level:
872 ret += ' - say_level='+Bridge._say_levels[b.say_level]
873 if args.show_participants:
874 xmpp_participants_nicknames = b.get_participants_nicknames_list(protocols=['xmpp'])
875 ret += '\nparticipants on XMPP ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
876 irc_participants_nicknames = b.get_participants_nicknames_list(protocols=['irc'])
877 ret += '\nparticipants on IRC ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
878 if b.irc_connection == None:
879 ret += ' - this bridge is stopped, use "restart-bridge '+str(i+1)+'" to restart it'
880 return ret
881
882 elif command in Bot.admin_commands:
883 if bot_admin == False:
884 return 'You have to be a bot admin to use this command.'
885
886 if command == 'add-bridge':
887 parser = ArgumentParser(prog=command)
888 parser.add_argument('xmpp_room_jid', type=str)
889 parser.add_argument('irc_chan', type=str)
890 parser.add_argument('irc_server', type=str)
891 parser.add_argument('--mode', choices=Bridge._modes, default='normal')
892 parser.add_argument('--say-level', choices=Bridge._say_levels, default='all')
893 parser.add_argument('--irc-port', type=int, default=6667)
894 try:
895 args = parser.parse_args(args_array)
896 except ArgumentParser.ParseException as e:
897 return '\n'+e.args[1]
898
899 self.new_bridge(args.xmpp_room_jid, args.irc_chan, args.irc_server, args.mode, args.say_level, irc_port=args.irc_port)
900
901 return 'Bridge added.'
902
903 elif command == 'add-xmpp-admin':
904 parser = ArgumentParser(prog=command)
905 parser.add_argument('jid', type=str)
906 try:
907 args = parser.parse_args(args_array)
908 except ArgumentParser.ParseException as e:
909 return '\n'+e.args[1]
910 self.admins_jid.append(args.jid)
911 for b in self.bridges:
912 for p in b.participants:
913 if p.real_jid != None and xmpp.protocol.JID(args.jid).bareMatch(p.real_jid):
914 p.bot_admin = True
915
916 return 'XMPP admin added.'
917
918 elif command == 'restart-bot':
919 self.restart()
920 return
921 elif command == 'halt':
922 self.stop()
923 return
924
925
926 elif command in ['change-bridge-mode', 'remove-bridge', 'restart-bridge', 'stop-bridge']:
927 # we need to know which bridge the command is for
928 if len(args_array) == 0:
929 if isinstance(participant, Participant):
930 b = participant.bridge
931 else:
932 return 'You must specify a bridge. '+self.respond('bridges')
933 else:
934 try:
935 bn = int(args_array[0])
936 if bn < 1:
937 raise IndexError
938 b = self.bridges[bn-1]
939 except IndexError:
940 return 'Invalid bridge number "'+str(bn)+'". '+self.respond('bridges')
941 except ValueError:
942 bridges = self.findBridges(args_array[0])
943 if len(bridges) == 0:
944 return 'No bridge found matching "'+args_array[0]+'". '+self.respond('bridges')
945 elif len(bridges) == 1:
946 b = bridges[0]
947 elif len(bridges) > 1:
948 return 'More than one bridge matches "'+args_array[0]+'", please be more specific. '+self.respond('bridges')
949
950 if command == 'change-bridge-mode':
951 new_mode = args_array[1]
952 if not new_mode in Bridge._modes:
953 return '"'+new_mode+'" is not a valid mode, list of modes: '+' '.join(Bridge._modes)
954 r = b.changeMode(new_mode)
955 if r:
956 return r
957 return 'Mode changed.'
958 elif command == 'remove-bridge':
959 self.removeBridge(b)
960 return 'Bridge removed.'
961 elif command == 'restart-bridge':
962 b.restart()
963 return 'Bridge restarted.'
964 elif command == 'stop-bridge':
965 b.stop()
966 return 'Bridge stopped.'
967
968 else: 827 else:
969 ret = 'Error: "'+command+'" is not a valid command.\ncommands: '+' '.join(Bot.commands) 828 bridge = None
970 if bot_admin == True: 829
971 return ret+'\n'+'admin commands: '+' '.join(Bot.admin_commands) 830 return commands.execute(self, message, bot_admin, bridge)
972 else:
973 return ret
974 831
975 832
976 def restart(self): 833 def restart(self):
977 # Stop the bridges 834 # Stop the bridges
978 for b in self.bridges: 835 for b in self.bridges: