diff options
Diffstat (limited to 'src/core/commands.py')
-rw-r--r-- | src/core/commands.py | 650 |
1 files changed, 334 insertions, 316 deletions
diff --git a/src/core/commands.py b/src/core/commands.py index 4a8f7f19..3830d72a 100644 --- a/src/core/commands.py +++ b/src/core/commands.py @@ -6,37 +6,35 @@ import logging log = logging.getLogger(__name__) -import functools import os -import sys from datetime import datetime -from gettext import gettext as _ from xml.etree import cElementTree as ET from slixmpp.xmlstream.stanzabase import StanzaBase from slixmpp.xmlstream.handler import Callback from slixmpp.xmlstream.matcher import StanzaPath -import bookmark import common import fixes import pep import tabs +from bookmarks import Bookmark from common import safeJID -from config import config, options as config_opts +from config import config, DEFAULT_CONFIG, options as config_opts import multiuserchat as muc from plugin import PluginConfig from roster import roster from theming import dump_tuple, get_theme +from decorators import command_args_parser from . structs import Command, possible_show -def command_help(self, arg): +@command_args_parser.quoted(0, 1) +def command_help(self, args): """ - /help <command_name> + /help [command_name] """ - args = arg.split() if not args: color = dump_tuple(get_theme().COLOR_HELP_COMMANDS) acc = [] @@ -66,8 +64,8 @@ def command_help(self, arg): buff.extend(acc) msg = '\n'.join(buff) - msg += _("\nType /help <command_name> to know what each command does") - if args: + msg += "\nType /help <command_name> to know what each command does" + else: command = args[0].lstrip('/').strip() if command in self.current_tab().commands: @@ -75,16 +73,17 @@ def command_help(self, arg): elif command in self.commands: tup = self.commands[command] else: - self.information(_('Unknown command: %s') % command, 'Error') + self.information('Unknown command: %s' % command, 'Error') return if isinstance(tup, Command): - msg = _('Usage: /%s %s\n' % (command, tup.usage)) + msg = 'Usage: /%s %s\n' % (command, tup.usage) msg += tup.desc else: msg = tup[1] self.information(msg, 'Help') -def command_runkey(self, arg): +@command_args_parser.quoted(1) +def command_runkey(self, args): """ /runkey <key> """ @@ -93,7 +92,9 @@ def command_runkey(self, arg): if key == '^J': return '\n' return key - char = arg.strip() + if args is None: + return self.command_help('runkey') + char = args[0] func = self.key_func.get(char, None) if func: func() @@ -102,21 +103,20 @@ def command_runkey(self, arg): if res: self.refresh_window() -def command_status(self, arg): +@command_args_parser.quoted(1, 1, [None]) +def command_status(self, args): """ /status <status> [msg] """ - args = common.shell_split(arg) - if len(args) < 1: - return + if args is None: + return self.command_help('status') + if not args[0] in possible_show.keys(): - self.command_help('status') - return + return self.command_help('status') + show = possible_show[args[0]] - if len(args) == 2: - msg = args[1] - else: - msg = None + msg = args[1] + pres = self.xmpp.make_presence() if msg: pres['status'] = msg @@ -136,19 +136,15 @@ def command_status(self, arg): if is_muctab and current.joined and show not in ('away', 'xa'): current.send_chat_state('active') -def command_presence(self, arg): +@command_args_parser.quoted(1, 2, [None, None]) +def command_presence(self, args): """ /presence <JID> [type] [status] """ - args = common.shell_split(arg) - if len(args) == 1: - jid, type, status = args[0], None, None - elif len(args) == 2: - jid, type, status = args[0], args[1], None - elif len(args) == 3: - jid, type, status = args[0], args[1], args[2] - else: - return + if args is None: + return self.command_help('presence') + + jid, type, status = args[0], args[1], args[2] if jid == '.' and isinstance(self.current_tab(), tabs.ChatTab): jid = self.current_tab().name if type == 'available': @@ -158,7 +154,7 @@ def command_presence(self, arg): self.events.trigger('send_normal_presence', pres) pres.send() except: - self.information(_('Could not send directed presence'), 'Error') + self.information('Could not send directed presence', 'Error') log.debug('Could not send directed presence to %s', jid, exc_info=True) return tab = self.get_tab_by_name(jid) @@ -177,24 +173,26 @@ def command_presence(self, arg): if self.current_tab() in tab.privates: self.current_tab().send_chat_state(chatstate, True) -def command_theme(self, arg=''): +@command_args_parser.quoted(1) +def command_theme(self, args=None): """/theme <theme name>""" - args = arg.split() - if args: - self.command_set('theme %s' % (args[0],)) + if args is None: + return self.command_help('theme') + self.command_set('theme %s' % (args[0],)) -def command_win(self, arg): +@command_args_parser.quoted(1) +def command_win(self, args): """ /win <number> """ - arg = arg.strip() - if not arg: - self.command_help('win') - return + if args is None: + return self.command_help('win') + + nb = args[0] try: - nb = int(arg.split()[0]) + nb = int(nb) except ValueError: - nb = arg + pass if self.current_tab_nb == nb: return self.previous_tab_nb = self.current_tab_nb @@ -219,15 +217,15 @@ def command_win(self, arg): self.current_tab().on_gain_focus() self.refresh_window() -def command_move_tab(self, arg): +@command_args_parser.quoted(2) +def command_move_tab(self, args): """ /move_tab old_pos new_pos """ - args = common.shell_split(arg) - current_tab = self.current_tab() - if len(args) != 2: + if args is None: return self.command_help('move_tab') + current_tab = self.current_tab() if args[0] == '.': args[0] = current_tab.nb if args[1] == '.': @@ -259,16 +257,16 @@ def command_move_tab(self, arg): self.current_tab_nb = self.tabs.index(current_tab) self.refresh_window() -def command_list(self, arg): +@command_args_parser.quoted(0, 1) +def command_list(self, args): """ - /list <server> + /list [server] Opens a MucListTab containing the list of the room in the specified server """ - arg = arg.split() - if len(arg) > 1: + if args is None: return self.command_help('list') - elif arg: - server = safeJID(arg[0]).server + elif args: + server = safeJID(args[0]) else: if not isinstance(self.current_tab(), tabs.MucTab): return self.information('Please provide a server', 'Error') @@ -279,26 +277,27 @@ def command_list(self, arg): self.xmpp.plugin['xep_0030'].get_items(jid=server, callback=cb) -def command_version(self, arg): +@command_args_parser.quoted(1) +def command_version(self, args): """ /version <jid> """ def callback(res): "Callback for /version" if not res: - return self.information(_('Could not get the software' - ' version from %s') % jid, - _('Warning')) - version = _('%s is running %s version %s on %s') % ( + return self.information('Could not get the software' + ' version from %s' % jid, + 'Warning') + version = '%s is running %s version %s on %s' % ( jid, - res.get('name') or _('an unknown software'), - res.get('version') or _('unknown'), - res.get('os') or _('an unknown platform')) + res.get('name') or 'an unknown software', + res.get('version') or 'unknown', + res.get('os') or 'an unknown platform') self.information(version, 'Info') - args = common.shell_split(arg) - if len(args) < 1: + if args is None: return self.command_help('version') + jid = safeJID(args[0]) if jid.resource or jid not in roster: fixes.get_version(self.xmpp, jid, callback=callback) @@ -308,11 +307,11 @@ def command_version(self, arg): else: fixes.get_version(self.xmpp, jid, callback=callback) -def command_join(self, arg, histo_length=None): +@command_args_parser.quoted(0, 2) +def command_join(self, args, histo_length=None): """ /join [room][/nick] [password] """ - args = common.shell_split(arg) password = None if len(args) == 0: tab = self.current_tab() @@ -388,13 +387,15 @@ def command_join(self, arg, histo_length=None): seconds = int(seconds) else: seconds = 0 + if password: + tab.password = password muc.join_groupchat(self, room, nick, password, histo_length, current_status.message, current_status.show, seconds=seconds) if not tab: - self.open_new_room(room, nick) + self.open_new_room(room, nick, password=password) muc.join_groupchat(self, room, nick, password, histo_length, current_status.message, @@ -409,196 +410,162 @@ def command_join(self, arg, histo_length=None): tab.refresh() self.doupdate() -def command_bookmark_local(self, arg=''): +@command_args_parser.quoted(0, 2) +def command_bookmark_local(self, args): """ /bookmark_local [room][/nick] [password] """ - args = common.shell_split(arg) - nick = None - password = None if not args and not isinstance(self.current_tab(), tabs.MucTab): return - if not args: - tab = self.current_tab() - roomname = tab.name - if tab.joined and tab.own_nick != self.own_nick: - nick = tab.own_nick - elif args[0] == '*': - new_bookmarks = [] - for tab in self.get_tabs(tabs.MucTab): - b = bookmark.get_by_jid(tab.name) - if not b: - b = bookmark.Bookmark(tab.name, - autojoin=True, - method="local") - new_bookmarks.append(b) - else: - b.method = "local" - new_bookmarks.append(b) - bookmark.bookmarks.remove(b) - new_bookmarks.extend(bookmark.bookmarks) - bookmark.bookmarks = new_bookmarks - bookmark.save_local() - bookmark.save_remote(self.xmpp, None) - self.information('Bookmarks added and saved.', 'Info') - return - else: - info = safeJID(args[0]) - if info.resource != '': - nick = info.resource - roomname = info.bare - if not roomname: - if not isinstance(self.current_tab(), tabs.MucTab): - return - roomname = self.current_tab().name - if len(args) > 1: - password = args[1] - - bm = bookmark.get_by_jid(roomname) - if not bm: - bm = bookmark.Bookmark(jid=roomname) - bookmark.bookmarks.append(bm) - self.information('Bookmark added.', 'Info') - else: - self.information('Bookmark updated.', 'Info') - if nick: - bm.nick = nick - bm.autojoin = True - bm.password = password - bm.method = "local" - bookmark.save_local() - self.information(_('Your local bookmarks are now: %s') % - [b for b in bookmark.bookmarks if b.method == 'local'], 'Info') + password = args[1] if len(args) > 1 else None + jid = args[0] if args else None + + _add_bookmark(self, jid, True, password, 'local') -def command_bookmark(self, arg=''): +@command_args_parser.quoted(0, 3) +def command_bookmark(self, args): """ /bookmark [room][/nick] [autojoin] [password] """ + if not args and not isinstance(self.current_tab(), tabs.MucTab): + return + jid = args[0] if args else '' + password = args[2] if len(args) > 2 else None if not config.get('use_remote_bookmarks'): - self.command_bookmark_local(arg) - return - args = common.shell_split(arg) + return _add_bookmark(self, jid, True, password, 'local') + + if len(args) > 1: + autojoin = False if args[1].lower() != 'true' else True + else: + autojoin = True + + _add_bookmark(self, jid, autojoin, password, 'remote') + +def _add_bookmark(self, jid, autojoin, password, method): nick = None - if not args and not isinstance(self.current_tab(), tabs.MucTab): - return - if not args: + if not jid: tab = self.current_tab() roomname = tab.name - if tab.joined: + if tab.joined and tab.own_nick != self.own_nick: nick = tab.own_nick - autojoin = True - password = None - elif args[0] == '*': - if len(args) > 1: - autojoin = False if args[1].lower() != 'true' else True - else: - autojoin = True - new_bookmarks = [] - for tab in self.get_tabs(tabs.MucTab): - b = bookmark.get_by_jid(tab.name) - if not b: - b = bookmark.Bookmark(tab.name, autojoin=autojoin, - method=bookmark.preferred) - new_bookmarks.append(b) - else: - b.method = bookmark.preferred - bookmark.bookmarks.remove(b) - new_bookmarks.append(b) - new_bookmarks.extend(bookmark.bookmarks) - bookmark.bookmarks = new_bookmarks - def _cb(self, iq): - if iq["type"] != "error": - bookmark.save_local() - self.information("Bookmarks added.", "Info") - else: - self.information("Could not add the bookmarks.", "Info") - bookmark.save_remote(self.xmpp, functools.partial(_cb, self)) - return + if password is None and tab.password is not None: + password = tab.password + elif jid == '*': + return _add_wildcard_bookmarks(self, method) else: - info = safeJID(args[0]) - if info.resource != '': - nick = info.resource - roomname = info.bare + info = safeJID(jid) + roomname, nick = info.bare, info.resource if roomname == '': if not isinstance(self.current_tab(), tabs.MucTab): return roomname = self.current_tab().name - if len(args) > 1: - autojoin = False if args[1].lower() != 'true' else True - else: - autojoin = True - if len(args) > 2: - password = args[2] - else: - password = None - bm = bookmark.get_by_jid(roomname) - if not bm: - bm = bookmark.Bookmark(roomname) - bookmark.bookmarks.append(bm) - bm.method = config.get('use_bookmarks_method') + bookmark = self.bookmarks[roomname] + if bookmark is None: + bookmark = Bookmark(roomname) + self.bookmarks.append(bookmark) + bookmark.method = method + bookmark.autojoin = autojoin if nick: - bm.nick = nick + bookmark.nick = nick if password: - bm.password = password - bm.autojoin = autojoin - def _cb(self, iq): + bookmark.password = password + def callback(iq): if iq["type"] != "error": self.information('Bookmark added.', 'Info') else: self.information("Could not add the bookmarks.", "Info") - bookmark.save_remote(self.xmpp, functools.partial(_cb, self)) - remote = [] - for each in bookmark.bookmarks: - if each.method in ('pep', 'privatexml'): - remote.append(each) + self.bookmarks.save_local() + self.bookmarks.save_remote(self.xmpp, callback) + +def _add_wildcard_bookmarks(self, method): + new_bookmarks = [] + for tab in self.get_tabs(tabs.MucTab): + bookmark = self.bookmarks[tab.name] + if not bookmark: + bookmark = Bookmark(tab.name, autojoin=True, + method=method) + new_bookmarks.append(bookmark) + else: + bookmark.method = method + new_bookmarks.append(bookmark) + self.bookmarks.remove(bookmark) + new_bookmarks.extend(self.bookmarks.bookmarks) + self.bookmarks.set(new_bookmarks) + def _cb(iq): + if iq["type"] != "error": + self.information("Bookmarks saved.", "Info") + else: + self.information("Could not save the remote bookmarks.", "Info") + self.bookmarks.save_local() + self.bookmarks.save_remote(self.xmpp, _cb) -def command_bookmarks(self, arg=''): +@command_args_parser.ignored +def command_bookmarks(self): """/bookmarks""" - local = [] - remote = [] - for each in bookmark.bookmarks: - if each.method in ('pep', 'privatexml'): - remote.append(each) - elif each.method == 'local': - local.append(each) - - self.information(_('Your remote bookmarks are: %s') % remote, - _('Info')) - self.information(_('Your local bookmarks are: %s') % local, - _('Info')) - -def command_remove_bookmark(self, arg=''): + tab = self.get_tab_by_name('Bookmarks', tabs.BookmarksTab) + old_tab = self.current_tab() + if tab: + self.current_tab_nb = tab.nb + else: + tab = tabs.BookmarksTab(self.bookmarks) + self.tabs.append(tab) + self.current_tab_nb = tab.nb + old_tab.on_lose_focus() + tab.on_gain_focus() + self.refresh_window() + +@command_args_parser.quoted(0, 1) +def command_remove_bookmark(self, args): """/remove_bookmark [jid]""" - args = common.shell_split(arg) + + def cb(success): + if success: + self.information('Bookmark deleted', 'Info') + else: + self.information('Error while deleting the bookmark', 'Error') + if not args: tab = self.current_tab() - if isinstance(tab, tabs.MucTab) and bookmark.get_by_jid(tab.name): - bookmark.remove(tab.name) - bookmark.save(self.xmpp) - if bookmark.save(self.xmpp): - self.information('Bookmark deleted', 'Info') + if isinstance(tab, tabs.MucTab) and self.bookmarks[tab.name]: + self.bookmarks.remove(tab.name) + self.bookmarks.save(self.xmpp, callback=cb) else: self.information('No bookmark to remove', 'Info') else: - if bookmark.get_by_jid(args[0]): - bookmark.remove(args[0]) - if bookmark.save(self.xmpp): - self.information('Bookmark deleted', 'Info') - + if self.bookmarks[args[0]]: + self.bookmarks.remove(args[0]) + self.bookmarks.save(self.xmpp, callback=cb) else: self.information('No bookmark to remove', 'Info') -def command_set(self, arg): +@command_args_parser.quoted(0, 3) +def command_set(self, args): """ /set [module|][section] <option> [value] """ - args = common.shell_split(arg) - if len(args) == 1: + if args is None or len(args) == 0: + config_dict = config.to_dict() + lines = [] + theme = get_theme() + for section_name, section in config_dict.items(): + lines.append('\x19%(section_col)s}[%(section)s]\x19o' % + { + 'section': section_name, + 'section_col': dump_tuple(theme.COLOR_INFORMATION_TEXT), + }) + for option_name, option_value in section.items(): + lines.append('%s\x19%s}=\x19o%s' % (option_name, + dump_tuple(theme.COLOR_REVISIONS_MESSAGE), + option_value)) + info = ('Current options:\n%s' % '\n'.join(lines), 'Info') + elif len(args) == 1: option = args[0] value = config.get(option) + if value is None and '=' in option: + args = option.split('=', 1) info = ('%s=%s' % (option, value), 'Info') - elif len(args) == 2: + if len(args) == 2: if '|' in args[0]: plugin_name, section = args[0].split('|')[:2] if not section: @@ -639,44 +606,72 @@ def command_set(self, arg): plugin_config = self.plugin_manager.plugins[plugin_name].config info = plugin_config.set_and_save(option, value, section) else: - section = args[0] + if args[0] == '.': + name = safeJID(self.current_tab().name).bare + if not name: + self.information('Invalid tab to use the "." argument.', + 'Error') + return + section = name + else: + section = args[0] option = args[1] value = args[2] info = config.set_and_save(option, value, section) self.trigger_configuration_change(option, value) - else: - self.command_help('set') - return - self.call_for_resize() + elif len(args) > 3: + return self.command_help('set') self.information(*info) -def command_toggle(self, arg): +@command_args_parser.quoted(1, 2) +def command_set_default(self, args): + """ + /set_default [section] <option> + """ + if len(args) == 1: + option = args[0] + section = 'Poezio' + elif len(args) == 2: + section = args[0] + option = args[1] + else: + return self.command_help('set_default') + + default_config = DEFAULT_CONFIG.get(section, tuple()) + if option not in default_config: + info = ("Option %s has no default value" % (option), "Error") + return self.information(*info) + self.command_set('%s %s %s' % (section, option, default_config[option])) + +@command_args_parser.quoted(1) +def command_toggle(self, args): """ /toggle <option> shortcut for /set <option> toggle """ - arg = arg.split() - if arg and arg[0]: - self.command_set('%s toggle' % arg[0]) + if args is None: + return self.command_help('toggle') -def command_server_cycle(self, arg=''): + if args[0]: + self.command_set('%s toggle' % args[0]) + +@command_args_parser.quoted(1, 1) +def command_server_cycle(self, args): """ Do a /cycle on each room of the given server. If none, do it on the current tab """ - args = common.shell_split(arg) tab = self.current_tab() message = "" - if len(args): + if args: domain = args[0] - if len(args) > 1: + if len(args) == 2: message = args[1] else: if isinstance(tab, tabs.MucTab): domain = safeJID(tab.name).domain else: - self.information(_("No server specified"), "Error") - return + return self.information("No server specified", "Error") for tab in self.get_tabs(tabs.MucTab): if tab.name.endswith(domain): if tab.joined: @@ -690,7 +685,8 @@ def command_server_cycle(self, arg=''): else: self.command_join('"%s/%s"' %(tab.name, tab.own_nick)) -def command_last_activity(self, arg): +@command_args_parser.quoted(1) +def command_last_activity(self, args): """ /last_activity <jid> """ @@ -698,11 +694,11 @@ def command_last_activity(self, arg): "Callback for the last activity" if iq['type'] != 'result': if iq['error']['type'] == 'auth': - self.information(_('You are not allowed to see the ' - 'activity of this contact.'), - _('Error')) + self.information('You are not allowed to see the ' + 'activity of this contact.', + 'Error') else: - self.information(_('Error retrieving the activity'), 'Error') + self.information('Error retrieving the activity', 'Error') return seconds = iq['last_activity']['seconds'] status = iq['last_activity']['status'] @@ -717,46 +713,47 @@ def command_last_activity(self, arg): common.parse_secs_to_str(seconds), (' and his/her last status was %s' % status) if status else '') self.information(msg, 'Info') - jid = safeJID(arg) - if jid == '': + + if args is None: return self.command_help('last_activity') + jid = safeJID(args[0]) self.xmpp.plugin['xep_0012'].get_last_activity(jid, callback=callback) -def command_mood(self, arg): +@command_args_parser.quoted(0, 2) +def command_mood(self, args): """ /mood [<mood> [text]] """ - args = common.shell_split(arg) if not args: - self.xmpp.plugin['xep_0107'].stop() - return + return self.xmpp.plugin['xep_0107'].stop() + mood = args[0] if mood not in pep.MOODS: - return self.information(_('%s is not a correct value for a mood.') - % mood, - _('Error')) - if len(args) > 1: + return self.information('%s is not a correct value for a mood.' + % mood, + 'Error') + if len(args) == 2: text = args[1] else: text = None self.xmpp.plugin['xep_0107'].publish_mood(mood, text, callback=dumb_callback) -def command_activity(self, arg): +@command_args_parser.quoted(0, 3) +def command_activity(self, args): """ /activity [<general> [specific] [text]] """ - args = common.shell_split(arg) length = len(args) if not length: - self.xmpp.plugin['xep_0108'].stop() - return + return self.xmpp.plugin['xep_0108'].stop() + general = args[0] if general not in pep.ACTIVITIES: - return self.information(_('%s is not a correct value for an activity') + return self.information('%s is not a correct value for an activity' % general, - _('Error')) + 'Error') specific = None text = None if length == 2: @@ -768,20 +765,20 @@ def command_activity(self, arg): specific = args[1] text = args[2] if specific and specific not in pep.ACTIVITIES[general]: - return self.information(_('%s is not a correct value ' - 'for an activity') % specific, - _('Error')) + return self.information('%s is not a correct value ' + 'for an activity' % specific, + 'Error') self.xmpp.plugin['xep_0108'].publish_activity(general, specific, text, callback=dumb_callback) -def command_gaming(self, arg): +@command_args_parser.quoted(0, 2) +def command_gaming(self, args): """ /gaming [<game name> [server address]] """ - args = common.shell_split(arg) if not args: - self.xmpp.plugin['xep_0196'].stop() - return + return self.xmpp.plugin['xep_0196'].stop() + name = args[0] if len(args) > 1: address = args[1] @@ -791,25 +788,27 @@ def command_gaming(self, arg): server_address=address, callback=dumb_callback) -def command_invite(self, arg): +@command_args_parser.quoted(2, 1, [None]) +def command_invite(self, args): """/invite <to> <room> [reason]""" - args = common.shell_split(arg) - if len(args) < 2: - return - reason = args[2] if len(args) > 2 else None + + if args is None: + return self.command_help('invite') + + reason = args[2] to = safeJID(args[0]) room = safeJID(args[1]).bare self.invite(to.full, room, reason=reason) -def command_decline(self, arg): +@command_args_parser.quoted(1, 1, ['']) +def command_decline(self, args): """/decline <room@server.tld> [reason]""" - args = common.shell_split(arg) - if not len(args): - return + if args is None: + return self.command_help('decline') jid = safeJID(args[0]) if jid.bare not in self.pending_invites: return - reason = args[1] if len(args) > 1 else '' + reason = args[1] del self.pending_invites[jid.bare] self.xmpp.plugin['xep_0045'].decline_invite(jid.bare, self.pending_invites[jid.bare], @@ -817,7 +816,8 @@ def command_decline(self, arg): ### Commands without a completion in this class ### -def command_invitations(self, arg=''): +@command_args_parser.ignored +def command_invitations(self): """/invitations""" build = "" for invite in self.pending_invites: @@ -829,17 +829,16 @@ def command_invitations(self, arg=''): build = "You do not have any pending invitations." self.information(build, 'Info') -def command_quit(self, arg=''): +@command_args_parser.quoted(0, 1, [None]) +def command_quit(self, args): """ - /quit + /quit [message] """ if not self.xmpp.is_connected(): self.exit() return - if len(arg.strip()) != 0: - msg = arg - else: - msg = None + + msg = args[0] if config.get('enable_user_mood'): self.xmpp.plugin['xep_0107'].stop() if config.get('enable_user_activity'): @@ -851,44 +850,47 @@ def command_quit(self, arg=''): self.disconnect(msg) self.xmpp.add_event_handler("disconnected", self.exit, disposable=True) -def command_destroy_room(self, arg=''): +@command_args_parser.quoted(0, 1, ['']) +def command_destroy_room(self, args): """ /destroy_room [JID] """ - room = safeJID(arg).bare + room = safeJID(args[0]).bare if room: muc.destroy_room(self.xmpp, room) - elif isinstance(self.current_tab(), tabs.MucTab) and not arg: + elif isinstance(self.current_tab(), tabs.MucTab) and not args[0]: muc.destroy_room(self.xmpp, self.current_tab().general_jid) else: - self.information(_('Invalid JID: "%s"') % arg, _('Error')) + self.information('Invalid JID: "%s"' % args[0], 'Error') -def command_bind(self, arg): +@command_args_parser.quoted(1, 1, ['']) +def command_bind(self, args): """ Bind a key. """ - args = common.shell_split(arg) - if len(args) < 1: + if args is None: return self.command_help('bind') - elif len(args) < 2: - args.append("") + if not config.silent_set(args[0], args[1], section='bindings'): - self.information(_('Unable to write in the config file'), 'Error') + self.information('Unable to write in the config file', 'Error') + if args[1]: self.information('%s is now bound to %s' % (args[0], args[1]), 'Info') else: self.information('%s is now unbound' % args[0], 'Info') -def command_rawxml(self, arg): +@command_args_parser.raw +def command_rawxml(self, args): """ /rawxml <xml stanza> """ - if not arg: - return + if not args: + return + stanza = args try: - stanza = StanzaBase(self.xmpp, xml=ET.fromstring(arg)) + stanza = StanzaBase(self.xmpp, xml=ET.fromstring(stanza)) if stanza.xml.tag == 'iq' and \ stanza.xml.attrib.get('type') in ('get', 'set') and \ stanza.xml.attrib.get('id'): @@ -910,78 +912,85 @@ def command_rawxml(self, arg): stanza.send() except: - self.information(_('Could not send custom stanza'), 'Error') + self.information('Could not send custom stanza', 'Error') log.debug('/rawxml: Could not send custom stanza (%s)', - repr(arg), + repr(stanza), exc_info=True) -def command_load(self, arg): +@command_args_parser.quoted(1, 256) +def command_load(self, args): """ /load <plugin> [<otherplugin> …] + # TODO: being able to load more than 256 plugins at once, hihi. """ - args = arg.split() for plugin in args: self.plugin_manager.load(plugin) -def command_unload(self, arg): +@command_args_parser.quoted(1, 256) +def command_unload(self, args): """ /unload <plugin> [<otherplugin> …] """ - args = arg.split() for plugin in args: self.plugin_manager.unload(plugin) -def command_plugins(self, arg=''): +@command_args_parser.ignored +def command_plugins(self): """ /plugins """ - self.information(_("Plugins currently in use: %s") % + self.information("Plugins currently in use: %s" % repr(list(self.plugin_manager.plugins.keys())), - _('Info')) + 'Info') -def command_message(self, arg): +@command_args_parser.quoted(1, 1) +def command_message(self, args): """ /message <jid> [message] """ - args = common.shell_split(arg) - if len(args) < 1: - self.command_help('message') - return + if args is None: + return self.command_help('message') jid = safeJID(args[0]) if not jid.user and not jid.domain and not jid.resource: return self.information('Invalid JID.', 'Error') tab = self.get_conversation_by_jid(jid.full, False, fallback_barejid=False) - if not tab: + muc = self.get_tab_by_name(jid.bare, typ=tabs.MucTab) + if not tab and not muc: tab = self.open_conversation_window(jid.full, focus=True) + elif muc: + tab = self.get_tab_by_name(jid.full, typ=tabs.PrivateTab) + if tab: + self.focus_tab_named(tab.name) + else: + tab = self.open_private_window(jid.bare, jid.resource) else: self.focus_tab_named(tab.name) - if len(args) > 1: + if len(args) == 2: tab.command_say(args[1]) -def command_xml_tab(self, arg=''): +@command_args_parser.ignored +def command_xml_tab(self): """/xml_tab""" - self.xml_tab = True xml_tab = self.focus_tab_named('XMLTab', tabs.XMLTab) if not xml_tab: tab = tabs.XMLTab() self.add_tab(tab, True) + self.xml_tab = tab -def command_adhoc(self, arg): - arg = arg.split() - if len(arg) > 1: +@command_args_parser.quoted(1) +def command_adhoc(self, args): + if not args: return self.command_help('ad-hoc') - elif arg: - jid = safeJID(arg[0]) - else: - return self.information('Please provide a jid', 'Error') + jid = safeJID(args[0]) list_tab = tabs.AdhocCommandsListTab(jid) self.add_tab(list_tab, True) cb = list_tab.on_list_received self.xmpp.plugin['xep_0050'].get_commands(jid=jid, local=False, callback=cb) -def command_self(self, arg=None): +@command_args_parser.ignored +def command_self(self): """ /self """ @@ -998,5 +1007,14 @@ def command_self(self, arg=None): config_opts.version)) self.information(info, 'Info') + +@command_args_parser.ignored +def command_reload(self): + """ + /reload + """ + self.reload_config() + def dumb_callback(*args, **kwargs): "mock callback" + |