diff options
Diffstat (limited to 'poezio/tabs/rostertab.py')
-rw-r--r-- | poezio/tabs/rostertab.py | 717 |
1 files changed, 236 insertions, 481 deletions
diff --git a/poezio/tabs/rostertab.py b/poezio/tabs/rostertab.py index 9f609f61..18334c20 100644 --- a/poezio/tabs/rostertab.py +++ b/poezio/tabs/rostertab.py @@ -14,33 +14,36 @@ import ssl from functools import partial from os import getenv, path from pathlib import Path -from typing import Dict, Callable +from typing import Dict, Callable, Union + +from slixmpp import JID, InvalidJID +from slixmpp.exceptions import IqError, IqTimeout -from poezio import common from poezio import windows -from poezio.common import safeJID, shell_split +from poezio.common import shell_split from poezio.config import config from poezio.contact import Contact, Resource from poezio.decorators import refresh_wrapper from poezio.roster import RosterGroup, roster from poezio.theming import get_theme, dump_tuple -from poezio.decorators import command_args_parser +from poezio.decorators import command_args_parser, deny_anonymous from poezio.core.structs import Command, Completion from poezio.tabs import Tab +from poezio.ui.types import InfoMessage log = logging.getLogger(__name__) class RosterInfoTab(Tab): """ - A tab, splitted in two, containing the roster and infos + A tab, split in two, containing the roster and infos """ - plugin_commands = {} # type: Dict[str, Command] - plugin_keys = {} # type: Dict[str, Callable] + plugin_commands: Dict[str, Command] = {} + plugin_keys: Dict[str, Callable] = {} def __init__(self, core): Tab.__init__(self, core) - self.name = "Roster" + self._name = "Roster" self.v_separator = windows.VerticalSeparator() self.information_win = windows.TextWin() self.core.information_buffer.add_window(self.information_win) @@ -71,96 +74,54 @@ class RosterInfoTab(Tab): self.key_func["s"] = self.start_search self.key_func["S"] = self.start_search_slow self.key_func["n"] = self.change_contact_name - self.register_command( - 'deny', - self.command_deny, - usage='[jid]', - desc='Deny your presence to the provided JID (or the ' - 'selected contact in your roster), who is asking' - 'you to be in his/here roster.', - shortdesc='Deny a user your presence.', - completion=self.completion_deny) - self.register_command( - 'accept', - self.command_accept, - usage='[jid]', - desc='Allow the provided JID (or the selected contact ' - 'in your roster), to see your presence.', - shortdesc='Allow a user your presence.', - completion=self.completion_deny) - self.register_command( - 'add', - self.command_add, - usage='<jid>', - desc='Add the specified JID to your roster, ask them to' - ' allow you to see his presence, and allow them to' - ' see your presence.', - shortdesc='Add a user to your roster.') - self.register_command( - 'name', - self.command_name, - usage='<jid> [name]', - shortdesc='Set the given JID\'s name.', - completion=self.completion_name) - self.register_command( - 'groupadd', - self.command_groupadd, - usage='[<jid> <group>]|<group>', - desc='Add the given JID or selected line to the given group.', - shortdesc='Add a user to a group', - completion=self.completion_groupadd) - self.register_command( - 'groupmove', - self.command_groupmove, - usage='<jid> <old group> <new group>', - desc='Move the given JID from the old group to the new group.', - shortdesc='Move a user to another group.', - completion=self.completion_groupmove) - self.register_command( - 'groupremove', - self.command_groupremove, - usage='<jid> <group>', - desc='Remove the given JID from the given group.', - shortdesc='Remove a user from a group.', - completion=self.completion_groupremove) - self.register_command( - 'remove', - self.command_remove, - usage='[jid]', - desc='Remove the specified JID from your roster. This ' - 'will unsubscribe you from its presence, cancel ' - 'its subscription to yours, and remove the item ' - 'from your roster.', - shortdesc='Remove a user from your roster.', - completion=self.completion_remove) - self.register_command( - 'export', - self.command_export, - usage='[/path/to/file]', - desc='Export your contacts into /path/to/file if ' - 'specified, or $HOME/poezio_contacts if not.', - shortdesc='Export your roster to a file.', - completion=partial(self.completion_file, 1)) - self.register_command( - 'import', - self.command_import, - usage='[/path/to/file]', - desc='Import your contacts from /path/to/file if ' - 'specified, or $HOME/poezio_contacts if not.', - shortdesc='Import your roster from a file.', - completion=partial(self.completion_file, 1)) - self.register_command( - 'password', - self.command_password, - usage='<password>', - shortdesc='Change your password') - self.register_command( - 'reconnect', - self.command_reconnect, - desc='Disconnect from the remote server if you are ' - 'currently connected and then connect to it again.', - shortdesc='Disconnect and reconnect to the server.') + 'name', + self.command_name, + usage='<jid> [name]', + shortdesc='Set the given JID\'s name.', + completion=self.completion_name) + self.register_command( + 'groupadd', + self.command_groupadd, + usage='[<jid> <group>]|<group>', + desc='Add the given JID or selected line to the given group.', + shortdesc='Add a user to a group', + completion=self.completion_groupadd) + self.register_command( + 'groupmove', + self.command_groupmove, + usage='<jid> <old group> <new group>', + desc='Move the given JID from the old group to the new group.', + shortdesc='Move a user to another group.', + completion=self.completion_groupmove) + self.register_command( + 'groupremove', + self.command_groupremove, + usage='<jid> <group>', + desc='Remove the given JID from the given group.', + shortdesc='Remove a user from a group.', + completion=self.completion_groupremove) + self.register_command( + 'export', + self.command_export, + usage='[/path/to/file]', + desc='Export your contacts into /path/to/file if ' + 'specified, or $HOME/poezio_contacts if not.', + shortdesc='Export your roster to a file.', + completion=partial(self.completion_file, 1)) + self.register_command( + 'import', + self.command_import, + usage='[/path/to/file]', + desc='Import your contacts from /path/to/file if ' + 'specified, or $HOME/poezio_contacts if not.', + shortdesc='Import your roster from a file.', + completion=partial(self.completion_file, 1)) + self.register_command( + 'password', + self.command_password, + usage='<password>', + shortdesc='Change your password') self.register_command( 'disconnect', self.command_disconnect, @@ -183,18 +144,6 @@ class RosterInfoTab(Tab): def check_blocking(self, features): if 'urn:xmpp:blocking' in features and not self.core.xmpp.anon: self.register_command( - 'block', - self.command_block, - usage='[jid]', - shortdesc='Prevent a JID from talking to you.', - completion=self.completion_block) - self.register_command( - 'unblock', - self.command_unblock, - usage='[jid]', - shortdesc='Allow a JID to talk to you.', - completion=self.completion_unblock) - self.register_command( 'list_blocks', self.command_list_blocks, shortdesc='Show the blocked contacts.') @@ -250,50 +199,40 @@ class RosterInfoTab(Tab): completion=self.completion_cert_fetch) @property - def selected_row(self): + def selected_row(self) -> Union[Contact, Resource]: return self.roster_win.get_selected_row() @command_args_parser.ignored - def command_certs(self): + async def command_certs(self): """ /certs """ - - def cb(iq): - if iq['type'] == 'error': - self.core.information( - 'Unable to retrieve the certificate list.', 'Error') - return - certs = [] - for item in iq['sasl_certs']['items']: - users = '\n'.join(item['users']) - certs.append((item['name'], users)) - - if not certs: - return self.core.information('No certificates found', 'Info') - msg = 'Certificates:\n' - msg += '\n'.join( - ((' %s%s' % (item[0] + (': ' if item[1] else ''), item[1])) - for item in certs)) - self.core.information(msg, 'Info') - - self.core.xmpp.plugin['xep_0257'].get_certs(callback=cb, timeout=3) + try: + iq = await self.core.xmpp.plugin['xep_0257'].get_certs(timeout=3) + except (IqError, IqTimeout): + self.core.information( + 'Unable to retrieve the certificate list.', 'Error') + return + certs = [] + for item in iq['sasl_certs']['items']: + users = '\n'.join(item['users']) + certs.append((item['name'], users)) + + if not certs: + return self.core.information('No certificates found', 'Info') + msg = 'Certificates:\n' + msg += '\n'.join( + ((' %s%s' % (item[0] + (': ' if item[1] else ''), item[1])) + for item in certs)) + self.core.information(msg, 'Info') @command_args_parser.quoted(2, 1) - def command_cert_add(self, args): + async def command_cert_add(self, args): """ /cert_add <name> <certfile> [cert-management] """ if not args or len(args) < 2: return self.core.command.help('cert_add') - - def cb(iq): - if iq['type'] == 'error': - self.core.information('Unable to add the certificate.', - 'Error') - else: - self.core.information('Certificate added.', 'Info') - name = args[0] try: @@ -319,8 +258,17 @@ class RosterInfoTab(Tab): else: management = True - self.core.xmpp.plugin['xep_0257'].add_cert( - name, crt, callback=cb, allow_management=management) + try: + await self.core.xmpp.plugin['xep_0257'].add_cert( + name, + crt, + allow_management=management + ) + self.core.information('Certificate added.', 'Info') + except (IqError, IqTimeout): + self.core.information('Unable to add the certificate.', + 'Error') + def completion_cert_add(self, the_input): """ @@ -336,76 +284,62 @@ class RosterInfoTab(Tab): return Completion(the_input.new_completion, ['true', 'false'], n) @command_args_parser.quoted(1) - def command_cert_disable(self, args): + async def command_cert_disable(self, args): """ /cert_disable <name> """ if not args: return self.core.command.help('cert_disable') - - def cb(iq): - if iq['type'] == 'error': - self.core.information('Unable to disable the certificate.', - 'Error') - else: - self.core.information('Certificate disabled.', 'Info') - name = args[0] - - self.core.xmpp.plugin['xep_0257'].disable_cert(name, callback=cb) + try: + await self.core.xmpp.plugin['xep_0257'].disable_cert(name) + self.core.information('Certificate disabled.', 'Info') + except (IqError, IqTimeout): + self.core.information('Unable to disable the certificate.', + 'Error') @command_args_parser.quoted(1) - def command_cert_revoke(self, args): + async def command_cert_revoke(self, args): """ /cert_revoke <name> """ if not args: return self.core.command.help('cert_revoke') - - def cb(iq): - if iq['type'] == 'error': - self.core.information('Unable to revoke the certificate.', - 'Error') - else: - self.core.information('Certificate revoked.', 'Info') - name = args[0] - - self.core.xmpp.plugin['xep_0257'].revoke_cert(name, callback=cb) + try: + await self.core.xmpp.plugin['xep_0257'].revoke_cert(name) + self.core.information('Certificate revoked.', 'Info') + except (IqError, IqTimeout): + self.core.information('Unable to revoke the certificate.', + 'Error') @command_args_parser.quoted(2) - def command_cert_fetch(self, args): + async def command_cert_fetch(self, args): """ /cert_fetch <name> <path> """ if not args or len(args) < 2: return self.core.command.help('cert_fetch') - - def cb(iq): - if iq['type'] == 'error': - self.core.information('Unable to fetch the certificate.', - 'Error') - return - - cert = None - for item in iq['sasl_certs']['items']: - if item['name'] == name: - cert = base64.b64decode(item['x509cert']) - break - - if not cert: - return self.core.information('Certificate not found.', 'Info') - - cert = ssl.DER_cert_to_PEM_cert(cert) - with open(path, 'w') as fd: - fd.write(cert) - - self.core.information('File stored at %s' % path, 'Info') - name = args[0] path = args[1] - self.core.xmpp.plugin['xep_0257'].get_certs(callback=cb) + try: + iq = await self.core.xmpp.plugin['xep_0257'].get_certs() + except (IqError, IqTimeout): + self.core.information('Unable to fetch the certificate.', + 'Error') + return + cert = None + for item in iq['sasl_certs']['items']: + if item['name'] == name: + cert = base64.b64decode(item['x509cert']) + break + if not cert: + return self.core.information('Certificate not found.', 'Info') + cert = ssl.DER_cert_to_PEM_cert(cert) + with open(path, 'w') as fd: + fd.write(cert) + self.core.information('File stored at %s' % path, 'Info') def completion_cert_fetch(self, the_input): """ @@ -426,110 +360,30 @@ class RosterInfoTab(Tab): if not tab: log.debug('Received message from nonexistent tab: %s', message['from']) - message = '\x19%(info_col)s}Cannot send message to %(jid)s: contact blocked' % { + message = 'Cannot send message to %(jid)s: contact blocked' % { 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT), 'jid': message['from'], } - tab.add_message(message) - - @command_args_parser.quoted(0, 1) - def command_block(self, args): - """ - /block [jid] - """ - item = self.roster_win.selected_row - if args: - jid = safeJID(args[0]) - elif isinstance(item, Contact): - jid = item.bare_jid - elif isinstance(item, Resource): - jid = item.jid.bare - - def callback(iq): - if iq['type'] == 'error': - return self.core.information('Could not block %s.' % jid, - 'Error') - elif iq['type'] == 'result': - return self.core.information('Blocked %s.' % jid, 'Info') - - self.core.xmpp.plugin['xep_0191'].block(jid, callback=callback) - - def completion_block(self, the_input): - """ - Completion for /block - """ - if the_input.get_argument_position() == 1: - jids = roster.jids() - return Completion( - the_input.new_completion, jids, 1, '', quotify=False) - - @command_args_parser.quoted(0, 1) - def command_unblock(self, args): - """ - /unblock [jid] - """ - - def callback(iq): - if iq['type'] == 'error': - return self.core.information('Could not unblock the contact.', - 'Error') - elif iq['type'] == 'result': - return self.core.information('Contact unblocked.', 'Info') - - item = self.roster_win.selected_row - if args: - jid = safeJID(args[0]) - elif isinstance(item, Contact): - jid = item.bare_jid - elif isinstance(item, Resource): - jid = item.jid.bare - self.core.xmpp.plugin['xep_0191'].unblock(jid, callback=callback) - - def completion_unblock(self, the_input): - """ - Completion for /unblock - """ - - def on_result(iq): - if iq['type'] == 'error': - return - l = sorted(str(item) for item in iq['blocklist']['items']) - return Completion(the_input.new_completion, l, 1, quotify=False) - - if the_input.get_argument_position(): - self.core.xmpp.plugin['xep_0191'].get_blocked(callback=on_result) - return True + tab.add_message(InfoMessage(message)) @command_args_parser.ignored - def command_list_blocks(self): + async def command_list_blocks(self): """ /list_blocks """ - - def callback(iq): - if iq['type'] == 'error': - return self.core.information( - 'Could not retrieve the blocklist.', 'Error') - s = 'List of blocked JIDs:\n' - items = (str(item) for item in iq['blocklist']['items']) - jids = '\n'.join(items) - if jids: - s += jids - else: - s = 'No blocked JIDs.' - self.core.information(s, 'Info') - - self.core.xmpp.plugin['xep_0191'].get_blocked(callback=callback) - - @command_args_parser.ignored - def command_reconnect(self): - """ - /reconnect - """ - if self.core.xmpp.is_connected(): - self.core.disconnect(reconnect=True) + try: + iq = await self.core.xmpp.plugin['xep_0191'].get_blocked() + except (IqError, IqTimeout) as iq: + return self.core.information( + 'Could not retrieve the blocklist.', 'Error') + s = 'List of blocked JIDs:\n' + items = (str(item) for item in iq['blocklist']['items']) + jids = '\n'.join(items) + if jids: + s += jids else: - self.core.xmpp.connect() + s = 'No blocked JIDs.' + self.core.information(s, 'Info') @command_args_parser.ignored def command_disconnect(self): @@ -580,7 +434,9 @@ class RosterInfoTab(Tab): roster_width) self.information_win.resize( self.height - 1 - tab_win_height - contact_win_h, info_width, - 0, roster_width + 1, self.core.information_buffer) + 0, roster_width + 1, self.core.information_buffer, + force=self.ui_config_changed) + self.ui_config_changed = False if display_contact_win: y = self.height - tab_win_height - contact_win_h - 1 avatar_width = contact_win_h * 2 @@ -652,83 +508,36 @@ class RosterInfoTab(Tab): self.core.information_buffer) self.refresh() + @deny_anonymous @command_args_parser.quoted(1) - def command_password(self, args): + async def command_password(self, args): """ /password <password> """ - - def callback(iq): - if iq['type'] == 'result': - self.core.information('Password updated', 'Account') - if config.get('password'): - config.silent_set('password', args[0]) - else: - self.core.information('Unable to change the password', - 'Account') - - self.core.xmpp.plugin['xep_0077'].change_password( - args[0], callback=callback) - - @command_args_parser.quoted(0, 1) - def command_deny(self, args): - """ - /deny [jid] - Denies a JID from our roster - """ - if not args: - item = self.roster_win.selected_row - if isinstance(item, Contact): - jid = item.bare_jid - else: - self.core.information('No subscription to deny', 'Warning') - return - else: - jid = safeJID(args[0]).bare - if jid not in [jid for jid in roster.jids()]: - self.core.information('No subscription to deny', 'Warning') - return - - contact = roster[jid] - if contact: - contact.unauthorize() - self.core.information('Subscription to %s was revoked' % jid, - 'Roster') - - @command_args_parser.quoted(1) - def command_add(self, args): - """ - Add the specified JID to the roster, and automatically - accept the reverse subscription - """ - if args is None: - self.core.information('No JID specified', 'Error') - return - jid = safeJID(safeJID(args[0]).bare) - if not str(jid): - self.core.information( - 'The provided JID (%s) is not valid' % (args[0], ), 'Error') - return - if jid in roster and roster[jid].subscription in ('to', 'both'): - return self.core.information('Already subscribed.', 'Roster') - roster.add(jid) - roster.modified() - self.core.information('%s was added to the roster' % jid, 'Roster') - + try: + await self.core.xmpp.plugin['xep_0077'].change_password( + args[0] + ) + self.core.information('Password updated', 'Account') + if config.getstr('password'): + config.silent_set('password', args[0]) + except (IqError, IqTimeout): + self.core.information('Unable to change the password', + 'Account') + + @deny_anonymous @command_args_parser.quoted(1, 1) - def command_name(self, args): + async def command_name(self, args): """ Set a name for the specified JID in your roster """ - - def callback(iq): - if not iq: - self.core.information('The name could not be set.', 'Error') - log.debug('Error in /name:\n%s', iq) - if args is None: return self.core.command.help('name') - jid = safeJID(args[0]).bare + try: + jid = JID(args[0]).bare + except InvalidJID: + self.core.information(f'Invalid JID: {args[0]}', 'Error') + return name = args[1] if len(args) == 2 else '' contact = roster[jid] @@ -740,15 +549,19 @@ class RosterInfoTab(Tab): if 'none' in groups: groups.remove('none') subscription = contact.subscription - self.core.xmpp.update_roster( - jid, - name=name, - groups=groups, - subscription=subscription, - callback=callback) + try: + await self.core.xmpp.update_roster( + jid, + name=name, + groups=groups, + subscription=subscription + ) + except (IqError, IqTimeout): + self.core.information('The name could not be set.', 'Error') + @deny_anonymous @command_args_parser.quoted(1, 1) - def command_groupadd(self, args): + async def command_groupadd(self, args): """ Add the specified JID to the specified group """ @@ -764,7 +577,11 @@ class RosterInfoTab(Tab): else: return self.core.command.help('groupadd') else: - jid = safeJID(args[0]).bare + try: + jid = JID(args[0]).bare + except InvalidJID: + self.core.information(f'Invalid JID: {args[0]}', 'Error') + return group = args[1] contact = roster[jid] @@ -787,28 +604,31 @@ class RosterInfoTab(Tab): name = contact.name subscription = contact.subscription - def callback(iq): - if iq: - roster.update_contact_groups(jid) - else: - self.core.information('The group could not be set.', 'Error') - log.debug('Error in groupadd:\n%s', iq) - self.core.xmpp.update_roster( - jid, - name=name, - groups=new_groups, - subscription=subscription, - callback=callback) + try: + await self.core.xmpp.update_roster( + jid, + name=name, + groups=new_groups, + subscription=subscription, + ) + roster.update_contact_groups(jid) + except (IqError, IqTimeout): + self.core.information('The group could not be set.', 'Error') + @deny_anonymous @command_args_parser.quoted(3) - def command_groupmove(self, args): + async def command_groupmove(self, args): """ Remove the specified JID from the first specified group and add it to the second one """ if args is None: return self.core.command.help('groupmove') - jid = safeJID(args[0]).bare + try: + jid = JID(args[0]).bare + except InvalidJID: + self.core.information(f'Invalid JID: {args[0]}', 'Error') + return group_from = args[1] group_to = args[2] @@ -845,30 +665,31 @@ class RosterInfoTab(Tab): new_groups.remove(group_from) name = contact.name subscription = contact.subscription + try: + await self.core.xmpp.update_roster( + jid, + name=name, + groups=new_groups, + subscription=subscription, + ) + roster.update_contact_groups(contact) + except (IqError, IqTimeout): + self.core.information('The group could not be set', 'Error') - def callback(iq): - if iq: - roster.update_contact_groups(contact) - else: - self.core.information('The group could not be set', 'Error') - log.debug('Error in groupmove:\n%s', iq) - - self.core.xmpp.update_roster( - jid, - name=name, - groups=new_groups, - subscription=subscription, - callback=callback) - + @deny_anonymous @command_args_parser.quoted(2) - def command_groupremove(self, args): + async def command_groupremove(self, args): """ Remove the specified JID from the specified group """ if args is None: return self.core.command.help('groupremove') - jid = safeJID(args[0]).bare + try: + jid = JID(args[0]).bare + except InvalidJID: + self.core.information(f'Invalid JID: {args[0]}', 'Error') + return group = args[1] contact = roster[jid] @@ -890,39 +711,18 @@ class RosterInfoTab(Tab): new_groups.remove(group) name = contact.name subscription = contact.subscription + try: + self.core.xmpp.update_roster( + jid, + name=name, + groups=new_groups, + subscription=subscription, + ) + roster.update_contact_groups(jid) + except (IqError, IqTimeout): + self.core.information('The group could not be set') - def callback(iq): - if iq: - roster.update_contact_groups(jid) - else: - self.core.information('The group could not be set') - log.debug('Error in groupremove:\n%s', iq) - - self.core.xmpp.update_roster( - jid, - name=name, - groups=new_groups, - subscription=subscription, - callback=callback) - - @command_args_parser.quoted(0, 1) - def command_remove(self, args): - """ - Remove the specified JID from the roster. i.e.: unsubscribe - from its presence, and cancel its subscription to our. - """ - if args: - jid = safeJID(args[0]).bare - else: - item = self.roster_win.selected_row - if isinstance(item, Contact): - jid = item.bare_jid - else: - self.core.information('No roster item to remove', 'Error') - return - roster.remove(jid) - del roster[jid] - + @deny_anonymous @command_args_parser.quoted(0, 1) def command_import(self, args): """ @@ -948,9 +748,10 @@ class RosterInfoTab(Tab): log.error('Unable to correct a message', exc_info=True) return for jid in lines: - self.command_add(jid.lstrip('\n')) + self.core.command.command_add(jid.lstrip('\n')) self.core.information('Contacts imported from %s' % filepath, 'Info') + @deny_anonymous @command_args_parser.quoted(0, 1) def command_export(self, args): """ @@ -1045,49 +846,6 @@ class RosterInfoTab(Tab): the_input.new_completion, groups, n, '', quotify=True) return False - def completion_deny(self, the_input): - """ - Complete the first argument from the list of the - contact with ask=='subscribe' - """ - jids = sorted( - str(contact.bare_jid) for contact in roster.contacts.values() - if contact.pending_in) - return Completion(the_input.new_completion, jids, 1, '', quotify=False) - - @command_args_parser.quoted(0, 1) - def command_accept(self, args): - """ - Accept a JID from in roster. Authorize it AND subscribe to it - """ - if not args: - item = self.roster_win.selected_row - if isinstance(item, Contact): - jid = item.bare_jid - else: - self.core.information('No subscription to accept', 'Warning') - return - else: - jid = safeJID(args[0]).bare - nodepart = safeJID(jid).user - jid = safeJID(jid) - # crappy transports putting resources inside the node part - if '\\2f' in nodepart: - jid.user = nodepart.split('\\2f')[0] - contact = roster[jid] - if contact is None: - return - contact.pending_in = False - roster.modified() - self.core.xmpp.send_presence(pto=jid, ptype='subscribed') - self.core.xmpp.client_roster.send_last_presence() - if contact.subscription in ('from', - 'none') and not contact.pending_out: - self.core.xmpp.send_presence( - pto=jid, ptype='subscribe', pnick=self.core.own_nick) - - self.core.information('%s is now authorized' % jid, 'Roster') - def refresh(self): if self.need_resize: self.resize() @@ -1128,7 +886,7 @@ class RosterInfoTab(Tab): Show or hide offline contacts """ option = 'roster_show_offline' - value = config.get(option) + value = config.getbool(option) success = config.silent_set(option, str(not value)) roster.modified() if not success: @@ -1272,15 +1030,6 @@ class RosterInfoTab(Tab): '%s connected resource%s' % (len(cont), '' if len(cont) == 1 else 's')) acc.append('Current status: %s' % res.status) - if cont.tune: - acc.append('Tune: %s' % common.format_tune_string(cont.tune)) - if cont.mood: - acc.append('Mood: %s' % cont.mood) - if cont.activity: - acc.append('Activity: %s' % cont.activity) - if cont.gaming: - acc.append( - 'Game: %s' % (common.format_gaming_string(cont.gaming))) msg = '\n'.join(acc) elif isinstance(selected_row, Resource): res = selected_row @@ -1306,7 +1055,7 @@ class RosterInfoTab(Tab): if isinstance(selected_row, Contact): jid = selected_row.bare_jid elif isinstance(selected_row, Resource): - jid = safeJID(selected_row.jid).bare + jid = JID(selected_row.jid).bare else: return self.on_slash() @@ -1388,8 +1137,11 @@ def jid_and_name_match(contact, txt): if not txt: return True txt = txt.lower() - if txt in safeJID(contact.bare_jid).bare.lower(): - return True + try: + if txt in JID(contact.bare_jid).bare.lower(): + return True + except InvalidJID: + pass if txt in contact.name.lower(): return True return False @@ -1402,9 +1154,12 @@ def jid_and_name_match_slow(contact, txt): """ if not txt: return True # Everything matches when search is empty - user = safeJID(contact.bare_jid).bare - if diffmatch(txt, user): - return True + try: + user = JID(contact.bare_jid).bare + if diffmatch(txt, user): + return True + except InvalidJID: + pass if contact.name and diffmatch(txt, contact.name): return True return False |