From 12a9528d6282303e5e130301a1beca621cfa2e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Fri, 20 Dec 2019 16:27:32 +0100 Subject: WIP: Allow blocking commands in ConversationTab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- poezio/core/commands.py | 106 ++++++++++++++++++++++++++++++++++++++++++++- poezio/core/completions.py | 40 +++++++++++++++++ poezio/core/core.py | 16 +++++++ poezio/core/handlers.py | 1 + poezio/tabs/rostertab.py | 80 ---------------------------------- 5 files changed, 161 insertions(+), 82 deletions(-) (limited to 'poezio') diff --git a/poezio/core/commands.py b/poezio/core/commands.py index 33bd3ecf..50bbca68 100644 --- a/poezio/core/commands.py +++ b/poezio/core/commands.py @@ -7,7 +7,7 @@ from xml.etree import cElementTree as ET from typing import List, Optional, Tuple import logging -from slixmpp import JID, InvalidJID +from slixmpp import Iq, JID, InvalidJID from slixmpp.exceptions import XMPPError from slixmpp.xmlstream.xmlstream import NotConnectedError from slixmpp.xmlstream.stanzabase import StanzaBase @@ -21,7 +21,7 @@ from poezio.bookmarks import Bookmark from poezio.common import safeJID from poezio.config import config, DEFAULT_CONFIG, options as config_opts from poezio import multiuserchat as muc -from poezio.contact import Contact +from poezio.contact import Contact, Resource from poezio.plugin import PluginConfig from poezio.roster import roster from poezio.theming import dump_tuple, get_theme @@ -899,6 +899,108 @@ class CommandCore: self.core.xmpp.plugin['xep_0045'].decline_invite( jid.bare, self.core.pending_invites[jid.bare], reason) + @command_args_parser.quoted(0, 1) + def block(self, args: List[str]) -> None: + """ + /block [jid] + + If a JID is specified, use it. Otherwise if in RosterInfoTab, use the + selected JID, if in ConversationsTab use the Tab's JID. + """ + + jid = None + if args: + try: + jid = JID(args[0]).full + except InvalidJID: + self.core.information('Invalid JID %s' % args, 'Error') + + current_tab = self.core.tabs.current_tab + if jid is None: + if isinstance(current_tab, tabs.RosterInfoTab): + roster_win = self.core.tabs.by_name_and_class( + 'Roster', + tabs.RosterInfoTab, + ) + item = roster_win.selected_row + if isinstance(item, Contact): + jid = item.bare_jid + elif isinstance(item, Resource): + jid = item.jid + + chattabs = ( + tabs.ConversationTab, + tabs.StaticConversationTab, + tabs.DynamicConversationTab, + ) + if isinstance(current_tab, chattabs): + jid = current_tab.jid.bare + + def callback(iq: Iq) -> None: + if iq['type'] == 'error': + return self.core.information( + 'Could not block %s.' % jid, 'Error', + ) + if iq['type'] == 'result': + return self.core.information('Blocked %s.' % jid, 'Info') + return None + + + if jid is not None: + self.core.xmpp.plugin['xep_0191'].block(jid, callback=callback) + else: + self.core.information('No specified JID to block', 'Error') + + @command_args_parser.quoted(0, 1) + def unblock(self, args: List[str]) -> None: + """ + /unblock [jid] + """ + + item = self.core.tabs.by_name_and_class( + 'Roster', + tabs.RosterInfoTab, + ).selected_row + + jid = None + if args: + try: + jid = JID(args[0]).full + except InvalidJID: + self.core.information('Invalid JID %s' % args, 'Error') + + current_tab = self.core.tabs.current_tab + if jid is None: + if isinstance(current_tab, tabs.RosterInfoTab): + roster_win = self.core.tabs.by_name_and_class( + 'Roster', + tabs.RosterInfoTab, + ) + item = roster_win.selected_row + if isinstance(item, Contact): + jid = item.bare_jid + elif isinstance(item, Resource): + jid = item.jid + + chattabs = ( + tabs.ConversationTab, + tabs.StaticConversationTab, + tabs.DynamicConversationTab, + ) + if isinstance(current_tab, chattabs): + jid = current_tab.jid.bare + + if jid is not None: + def callback(iq: Iq): + if iq['type'] == 'error': + return self.core.information('Could not unblock the contact.', + 'Error') + elif iq['type'] == 'result': + return self.core.information('Unblocked %s.' % jid, 'Info') + + self.core.xmpp.plugin['xep_0191'].unblock(jid, callback=callback) + else: + self.core.information('No specified JID to unblock', 'Error') ### Commands without a completion in this class ### diff --git a/poezio/core/completions.py b/poezio/core/completions.py index 84de77ca..ee3e95bf 100644 --- a/poezio/core/completions.py +++ b/poezio/core/completions.py @@ -2,6 +2,7 @@ Completions for the global commands """ import logging +from typing import List, Optional log = logging.getLogger(__name__) @@ -9,6 +10,8 @@ import os from pathlib import Path from functools import reduce +from slixmpp import JID + from poezio import common from poezio import pep from poezio import tabs @@ -461,3 +464,40 @@ class CompletionCore: muc_list = [tab.name for tab in self.core.get_tabs(tabs.MucTab)] muc_list.append('*') return Completion(the_input.new_completion, muc_list, 1, quotify=True) + + def block(self, the_input) -> Optional[Completion]: + """ + Completion for /block + """ + if the_input.get_argument_position() == 1: + + current_tab = self.core.tabs.current_tab + chattabs = ( + tabs.ConversationTab, + tabs.StaticConversationTab, + tabs.DynamicConversationTab, + ) + tabjid = [] # type: List[JID] + if isinstance(current_tab, chattabs): + tabjid = [current_tab.jid.bare] + + jids = roster.jids() + jids += tabjid + return Completion( + the_input.new_completion, jids, 1, '', quotify=False) + return None + + def unblock(self, the_input) -> Optional[Completion]: + """ + Completion for /unblock + """ + + def on_result(iq): + if iq['type'] == 'error': + return None + 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 None diff --git a/poezio/core/core.py b/poezio/core/core.py index 5b18a8e1..717ee305 100644 --- a/poezio/core/core.py +++ b/poezio/core/core.py @@ -1984,6 +1984,22 @@ class Core: shortdesc='Send your gaming activity.', completion=None) + def check_blocking(self, features): + if 'urn:xmpp:blocking' in features and not self.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.xmpp.del_event_handler('session_start', self.check_blocking) ####################### Random things to move ################################# diff --git a/poezio/core/handlers.py b/poezio/core/handlers.py index fcd8d731..fc5938f3 100644 --- a/poezio/core/handlers.py +++ b/poezio/core/handlers.py @@ -89,6 +89,7 @@ class HandlerCore: 'Roster', tabs.RosterInfoTab) rostertab.check_blocking(features) rostertab.check_saslexternal(features) + self.core.check_blocking(features) if (config.get('enable_carbons') and 'urn:xmpp:carbons:2' in features): self.core.xmpp.plugin['xep_0280'].enable() diff --git a/poezio/tabs/rostertab.py b/poezio/tabs/rostertab.py index 8c80a652..6f43cca1 100644 --- a/poezio/tabs/rostertab.py +++ b/poezio/tabs/rostertab.py @@ -170,18 +170,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, @@ -420,74 +408,6 @@ class RosterInfoTab(Tab): } 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 - @command_args_parser.ignored def command_list_blocks(self): """ -- cgit v1.2.3