Mercurial > xib
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)