changeset 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 922858915907
files bot.py commands.py
diffstat 2 files changed, 201 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/bot.py
+++ b/bot.py
@@ -16,14 +16,12 @@
 
 
 import re
-import shlex
 import sys
 import threading
 from time import sleep
 import traceback
 import xml.parsers.expat
 
-from argparse_modified import ArgumentParser
 from encoding import *
 import irclib
 import muc
@@ -32,13 +30,11 @@ del muc
 
 from bridge import Bridge
 from participant import Participant
+import commands
 
 
 class Bot(threading.Thread):
 	
-	commands = ['xmpp-participants', 'irc-participants', 'bridges']
-	admin_commands = ['add-bridge', 'add-xmpp-admin', 'change-bridge-mode', 'halt', 'remove-bridge', 'restart-bot', 'restart-bridge', 'stop-bridge']
-	
 	def __init__(self, jid, password, nickname, admins_jid=[], error_fd=sys.stderr, debug=False):
 		threading.Thread.__init__(self)
 		self.bare_jid = xmpp.protocol.JID(jid=jid)
@@ -824,153 +820,14 @@ class Bot(threading.Thread):
 	
 	
 	def respond(self, message, participant=None, bot_admin=False):
-		ret = ''
-		command = shlex.split(message)
-		args_array = []
-		if len(command) > 1:
-			args_array = command[1:]
-		command = command[0]
-		
-		if isinstance(participant, Participant) and bot_admin != participant.bot_admin:
-			bot_admin = participant.bot_admin
-		
-		if command == 'xmpp-participants':
-			if not isinstance(participant, Participant):
-				for b in self.bridges:
-					xmpp_participants_nicknames = b.get_participants_nicknames_list(protocols=['xmpp'])
-					ret += '\nparticipants on '+b.xmpp_room_jid+' ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
-				return ret
-			else:
-				xmpp_participants_nicknames = participant.bridge.get_participants_nicknames_list(protocols=['xmpp'])
-				return '\nparticipants on '+participant.bridge.xmpp_room_jid+' ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
-		
-		elif command == 'irc-participants':
-			if not isinstance(participant, Participant):
-				for b in self.bridges:
-					irc_participants_nicknames = b.get_participants_nicknames_list(protocols=['irc'])
-					ret += '\nparticipants on '+b.irc_room+' at '+b.irc_server+' ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
-				return ret
-			else:
-				irc_participants_nicknames = participant.bridge.get_participants_nicknames_list(protocols=['irc'])
-				return '\nparticipants on '+participant.bridge.irc_room+' at '+participant.bridge.irc_server+' ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
-		
-		elif command == 'bridges':
-			parser = ArgumentParser(prog=command)
-			parser.add_argument('--show-mode', default=False, action='store_true')
-			parser.add_argument('--show-say-level', default=False, action='store_true')
-			parser.add_argument('--show-participants', default=False, action='store_true')
-			try:
-				args = parser.parse_args(args_array)
-			except ArgumentParser.ParseException as e:
-				return '\n'+e.args[1]
-			ret = 'List of bridges:'
-			for i, b in enumerate(self.bridges):
-				ret += '\n'+str(i+1)+' - '+str(b)
-				if args.show_mode:
-					ret += ' - mode='+b.mode
-				if args.show_say_level:
-					ret += ' - say_level='+Bridge._say_levels[b.say_level]
-				if args.show_participants:
-					xmpp_participants_nicknames = b.get_participants_nicknames_list(protocols=['xmpp'])
-					ret += '\nparticipants on XMPP ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
-					irc_participants_nicknames = b.get_participants_nicknames_list(protocols=['irc'])
-					ret += '\nparticipants on IRC ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
-				if b.irc_connection == None:
-					ret += ' - this bridge is stopped, use "restart-bridge '+str(i+1)+'" to restart it'
-			return ret
+		if isinstance(participant, Participant):
+			bridge = participant.bridge
+			if bot_admin != participant.bot_admin:
+				bot_admin = participant.bot_admin
+		else:
+			bridge = None
 		
-		elif command in Bot.admin_commands:
-			if bot_admin == False:
-				return 'You have to be a bot admin to use this command.'
-			
-			if command == 'add-bridge':
-				parser = ArgumentParser(prog=command)
-				parser.add_argument('xmpp_room_jid', type=str)
-				parser.add_argument('irc_chan', type=str)
-				parser.add_argument('irc_server', type=str)
-				parser.add_argument('--mode', choices=Bridge._modes, default='normal')
-				parser.add_argument('--say-level', choices=Bridge._say_levels, default='all')
-				parser.add_argument('--irc-port', type=int, default=6667)
-				try:
-					args = parser.parse_args(args_array)
-				except ArgumentParser.ParseException as e:
-					return '\n'+e.args[1]
-				
-				self.new_bridge(args.xmpp_room_jid, args.irc_chan, args.irc_server, args.mode, args.say_level, irc_port=args.irc_port)
-				
-				return 'Bridge added.'
-			
-			elif command == 'add-xmpp-admin':
-				parser = ArgumentParser(prog=command)
-				parser.add_argument('jid', type=str)
-				try:
-					args = parser.parse_args(args_array)
-				except ArgumentParser.ParseException as e:
-					return '\n'+e.args[1]
-				self.admins_jid.append(args.jid)
-				for b in self.bridges:
-					for p in b.participants:
-						if p.real_jid != None and xmpp.protocol.JID(args.jid).bareMatch(p.real_jid):
-							p.bot_admin = True
-				
-				return 'XMPP admin added.'
-				
-			elif command == 'restart-bot':
-				self.restart()
-				return
-			elif command == 'halt':
-				self.stop()
-				return
-			
-			
-			elif command in ['change-bridge-mode', 'remove-bridge', 'restart-bridge', 'stop-bridge']:
-				# we need to know which bridge the command is for
-				if len(args_array) == 0:
-					if isinstance(participant, Participant):
-						b = participant.bridge
-					else:
-						return 'You must specify a bridge. '+self.respond('bridges')
-				else:
-					try:
-						bn = int(args_array[0])
-						if bn < 1:
-							raise IndexError
-						b = self.bridges[bn-1]
-					except IndexError:
-						return 'Invalid bridge number "'+str(bn)+'". '+self.respond('bridges')
-					except ValueError:
-						bridges = self.findBridges(args_array[0])
-						if len(bridges) == 0:
-							return 'No bridge found matching "'+args_array[0]+'". '+self.respond('bridges')
-						elif len(bridges) == 1:
-							b = bridges[0]
-						elif len(bridges) > 1:
-							return 'More than one bridge matches "'+args_array[0]+'", please be more specific. '+self.respond('bridges')
-					
-				if command == 'change-bridge-mode':
-					new_mode = args_array[1]
-					if not new_mode in Bridge._modes:
-						return '"'+new_mode+'" is not a valid mode, list of modes: '+' '.join(Bridge._modes)
-					r = b.changeMode(new_mode)
-					if r:
-						return r
-					return 'Mode changed.'
-				elif command == 'remove-bridge':
-					self.removeBridge(b)
-					return 'Bridge removed.'
-				elif command == 'restart-bridge':
-					b.restart()
-					return 'Bridge restarted.'
-				elif command == 'stop-bridge':
-					b.stop()
-					return 'Bridge stopped.'
-		
-		else:
-			ret = 'Error: "'+command+'" is not a valid command.\ncommands:  '+'  '.join(Bot.commands)
-			if bot_admin == True:
-				return ret+'\n'+'admin commands:  '+'  '.join(Bot.admin_commands)
-			else:
-				return ret
+		return commands.execute(self, message, bot_admin, bridge)
 	
 	
 	def restart(self):
new file mode 100644
--- /dev/null
+++ b/commands.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+import shlex
+
+from argparse_modified import ArgumentParser
+import muc
+xmpp = muc.xmpp
+del muc
+
+from bridge import Bridge
+
+
+commands = ['xmpp-participants', 'irc-participants', 'bridges']
+admin_commands = ['add-bridge', 'add-xmpp-admin', 'change-bridge-mode', 'halt', 'remove-bridge', 'restart-bot', 'restart-bridge', 'stop-bridge']
+
+def execute(bot, command_line, bot_admin, bridge):
+	ret = ''
+	command = shlex.split(command_line)
+	if len(command) > 1:
+		args_array = command[1:]
+	else:
+		args_array = []
+	command = command[0]
+	command_func = command.replace('-', '_')
+	
+	if not globals().has_key(command_func):
+		ret = 'Error: "'+command+'" is not a valid command.\ncommands:  '+'  '.join(commands)
+		if bot_admin:
+			return ret+'\n'+'admin commands:  '+'  '.join(admin_commands)
+		else:
+			return ret
+	elif command in admin_commands and not bot_admin:
+		return 'You have to be a bot admin to use this command.'
+	
+	b = bridge
+	
+	if command in ['change-bridge-mode', 'remove-bridge', 'restart-bridge', 'stop-bridge']:
+		# we need to know which bridge the command is for
+		if len(args_array) == 0:
+			if bridge:
+				b = bridge
+			else:
+				return 'You must specify a bridge. '+bridges(bot, 'bridges', [], bot_admin, None)
+		else:
+			try:
+				bn = int(args_array[0])
+				if bn < 1:
+					raise IndexError
+				b = bot.bridges[bn-1]
+			except IndexError:
+				return 'Invalid bridge number "'+str(bn)+'". '+bridges(bot, 'bridges', [], bot_admin, None)
+			except ValueError:
+				bridges = bot.findBridges(args_array[0])
+				if len(bridges) == 0:
+					return 'No bridge found matching "'+args_array[0]+'". '+bridges(bot, 'bridges', [], bot_admin, None)
+				elif len(bridges) == 1:
+					b = bridges[0]
+				elif len(bridges) > 1:
+					return 'More than one bridge matches "'+args_array[0]+'", please be more specific. '+bridges(bot, 'bridges', [], bot_admin, None)
+	
+	
+	return globals()[command_func](bot, command, args_array, bot_admin, b)
+
+
+def add_bridge(bot, command, args_array, bot_admin, bridge):
+	parser = ArgumentParser(prog=command)
+	parser.add_argument('xmpp_room_jid', type=str)
+	parser.add_argument('irc_chan', type=str)
+	parser.add_argument('irc_server', type=str)
+	parser.add_argument('--mode', choices=Bridge._modes, default='normal')
+	parser.add_argument('--say-level', choices=Bridge._say_levels, default='all')
+	parser.add_argument('--irc-port', type=int, default=6667)
+	try:
+		args = parser.parse_args(args_array)
+	except ArgumentParser.ParseException as e:
+		return '\n'+e.args[1]
+	
+	bot.new_bridge(args.xmpp_room_jid, args.irc_chan, args.irc_server, args.mode, args.say_level, irc_port=args.irc_port)
+	
+	return 'Bridge added.'
+
+
+def add_xmpp_admin(bot, command, args_array, bot_admin, bridge):
+	parser = ArgumentParser(prog=command)
+	parser.add_argument('jid', type=str)
+	try:
+		args = parser.parse_args(args_array)
+	except ArgumentParser.ParseException as e:
+		return '\n'+e.args[1]
+	bot.admins_jid.append(args.jid)
+	for b in bot.bridges:
+		for p in b.participants:
+			if p.real_jid != None and xmpp.protocol.JID(args.jid).bareMatch(p.real_jid):
+				p.bot_admin = True
+	
+	return 'XMPP admin added.'
+
+
+def bridges(bot, command, args_array, bot_admin, bridge):
+	parser = ArgumentParser(prog=command)
+	parser.add_argument('--show-mode', default=False, action='store_true')
+	parser.add_argument('--show-say-level', default=False, action='store_true')
+	parser.add_argument('--show-participants', default=False, action='store_true')
+	try:
+		args = parser.parse_args(args_array)
+	except ArgumentParser.ParseException as e:
+		return '\n'+e.args[1]
+	ret = 'List of bridges:'
+	for i, b in enumerate(bot.bridges):
+		ret += '\n'+str(i+1)+' - '+str(b)
+		if args.show_mode:
+			ret += ' - mode='+b.mode
+		if args.show_say_level:
+			ret += ' - say_level='+Bridge._say_levels[b.say_level]
+		if args.show_participants:
+			xmpp_participants_nicknames = b.get_participants_nicknames_list(protocols=['xmpp'])
+			ret += '\nparticipants on XMPP ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
+			irc_participants_nicknames = b.get_participants_nicknames_list(protocols=['irc'])
+			ret += '\nparticipants on IRC ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
+		if b.irc_connection == None:
+			ret += ' - this bridge is stopped, use "restart-bridge '+str(i+1)+'" to restart it'
+	return ret
+
+
+def change_bridge_mode(bot, command, args_array, bot_admin, bridge):
+	new_mode = args_array[1]
+	if not new_mode in Bridge._modes:
+		return '"'+new_mode+'" is not a valid mode, list of modes: '+' '.join(Bridge._modes)
+	r = bridge.changeMode(new_mode)
+	if r:
+		return r
+	return 'Mode changed.'
+
+
+def halt(bot, command, args_array, bot_admin, bridge):
+	bot.stop()
+	return
+
+
+def irc_participants(bot, command, args_array, bot_admin, bridge):
+	if not bridge:
+		for b in bot.bridges:
+			irc_participants_nicknames = b.get_participants_nicknames_list(protocols=['irc'])
+			ret += '\nparticipants on '+b.irc_room+' at '+b.irc_server+' ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
+		return ret
+	else:
+		irc_participants_nicknames = bridge.get_participants_nicknames_list(protocols=['irc'])
+		return '\nparticipants on '+bridge.irc_room+' at '+bridge.irc_server+' ('+str(len(irc_participants_nicknames))+'): '+' '.join(irc_participants_nicknames)
+
+
+def remove_bridge(bot, command, args_array, bot_admin, bridge):
+	bot.removeBridge(bridge)
+	return 'Bridge removed.'
+
+
+def restart_bot(bot, command, args_array, bot_admin, bridge):
+	bot.restart()
+	return
+
+def restart_bridge(bot, command, args_array, bot_admin, bridge):
+	bridge.restart()
+	return 'Bridge restarted.'
+
+
+def stop_bridge(bot, command, args_array, bot_admin, bridge):
+	bridge.stop()
+	return 'Bridge stopped.'
+
+
+def xmpp_participants(bot, command, args_array, bot_admin, bridge):
+	if not bridge:
+		for b in bot.bridges:
+			xmpp_participants_nicknames = b.get_participants_nicknames_list(protocols=['xmpp'])
+			ret += '\nparticipants on '+b.xmpp_room_jid+' ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)
+		return ret
+	else:
+		xmpp_participants_nicknames = bridge.get_participants_nicknames_list(protocols=['xmpp'])
+		return '\nparticipants on '+bridge.xmpp_room_jid+' ('+str(len(xmpp_participants_nicknames))+'): '+' '.join(xmpp_participants_nicknames)