Add simple communication blocking (Fixes #1837)

- Add /block, /unblock, and /list_blocks commands
- Enable the commands only if the server advertises the feature
- http://xmpp.org/extensions/xep-0191.html#example-9 was not tested, but
  should work (could not find a server to test with)
- Add documentation for the commands
This commit is contained in:
mathieui 2012-08-02 01:09:10 +02:00
parent 0cb39b32a4
commit 18074c3c23
3 changed files with 129 additions and 1 deletions

View file

@ -436,6 +436,17 @@ Roster tab commands
unsubscribe you from its presence, cancel its subscription to yours, and unsubscribe you from its presence, cancel its subscription to yours, and
remove the item from your roster. remove the item from your roster.
NOTE: The following commands only exist if your server supports them. If it
does not, you will be notified when you start poezio.
*/block [jid]*:: Block the following JID using simple blocking. You will not
receive any of his messages and wont be able to send some to him either.
*/unblock [jid]*:: Unblock a previously blocked JID using simple blocking. You
will be able to send and receive messages from him again.
*/list_blocks*:: List the blocked JIDs.
NOTE: The following commands do not comply with any XEP or whatever, but they NOTE: The following commands do not comply with any XEP or whatever, but they
can still prove useful when you are migrating to an other JID. can still prove useful when you are migrating to an other JID.

View file

@ -60,6 +60,7 @@ class Connection(sleekxmpp.ClientXMPP):
self.register_plugin('xep_0048') self.register_plugin('xep_0048')
self.register_plugin('xep_0071') self.register_plugin('xep_0071')
self.register_plugin('xep_0085') self.register_plugin('xep_0085')
self.register_plugin('xep_0191')
if config.get('send_poezio_info', 'true') == 'true': if config.get('send_poezio_info', 'true') == 'true':
info = {'name':'poezio', info = {'name':'poezio',
'version':'0.8-dev'} 'version':'0.8-dev'}

View file

@ -39,7 +39,7 @@ import multiuserchat as muc
from theming import get_theme from theming import get_theme
from sleekxmpp.xmlstream.stanzabase import JID from sleekxmpp import JID, InvalidJID
from sleekxmpp.xmlstream import matcher from sleekxmpp.xmlstream import matcher
from sleekxmpp.xmlstream.handler import Callback from sleekxmpp.xmlstream.handler import Callback
from config import config from config import config
@ -1859,10 +1859,126 @@ class RosterInfoTab(Tab):
self.commands['export'] = (self.command_export, _("Usage: /export [/path/to/file]\nExport: Export your contacts into /path/to/file if specified, or $HOME/poezio_contacts if not."), self.completion_file) self.commands['export'] = (self.command_export, _("Usage: /export [/path/to/file]\nExport: Export your contacts into /path/to/file if specified, or $HOME/poezio_contacts if not."), self.completion_file)
self.commands['import'] = (self.command_import, _("Usage: /import [/path/to/file]\nImport: Import your contacts from /path/to/file if specified, or $HOME/poezio_contacts if not."), self.completion_file) self.commands['import'] = (self.command_import, _("Usage: /import [/path/to/file]\nImport: Import your contacts from /path/to/file if specified, or $HOME/poezio_contacts if not."), self.completion_file)
self.commands['clear_infos'] = (self.command_clear_infos, _("Usage: /clear_infos\nClear Infos: Use this command to clear the info buffer."), None) self.commands['clear_infos'] = (self.command_clear_infos, _("Usage: /clear_infos\nClear Infos: Use this command to clear the info buffer."), None)
self.core.xmpp.add_event_handler('session_start',
lambda event: self.core.xmpp.plugin['xep_0030'].get_info(
jid=self.core.xmpp.boundjid.domain,
block=False, timeout=5, callback=self.check_blocking)
)
self.resize() self.resize()
self.update_commands() self.update_commands()
self.update_keys() self.update_keys()
def check_blocking(self, iq):
if iq['type'] == 'error':
return
if 'urn:xmpp:blocking' in iq['disco_info'].get_features():
self.commands['block'] = (self.command_block, _("Usage: /block [jid]\nBlock: prevent a JID from talking to you."), self.completion_block)
self.commands['unblock'] = (self.command_unblock, _("Usage: /unblock [jid]\nUnblock: allow a JID to talk to you."), self.completion_unblock)
self.commands['list_blocks'] = (self.command_list_blocks, _("Usage: /list_blocks\nList Blocks: Retrieve the list of the blocked contacts."), None)
self.core.xmpp.del_event_handler('session_start', self.check_blocking)
self.core.xmpp.add_event_handler('blocked_message', self.on_blocked_message)
else:
self.core.information('Simple blocking not supported by the server', 'Info')
def on_blocked_message(self, message):
"""
When we try to send a message to a blocked contact
"""
tab = self.core.get_conversation_by_jid(message['from'], False)
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' % {
'info_col': get_theme().COLOR_INFORMATION_TEXT[0],
'jid': message['from'],
}
tab.add_message(message)
def command_block(self, arg):
"""
/block [jid]
"""
def callback(iq):
if iq['type'] == 'error':
return self.core.information('Could not block the contact.', 'Error')
elif iq['type'] == 'result':
return self.core.information('Contact blocked.', 'Info')
item = self.roster_win.selected_row
if arg:
try:
jid = JID(arg)
except InvalidJID:
self.core.information('JID not well-formed', 'Error')
return
elif isinstance(item, Contact):
jid = item.bare_jid
elif isinstance(item, Resource):
jid = item.jid.bare
self.core.xmpp.plugin['xep_0191'].block(jid, block=False, callback=callback)
def completion_block(self, the_input):
"""
Completion for /block
"""
jids = roster.jids()
return the_input.auto_completion(jids, '', quotify=False)
def command_unblock(self, arg):
"""
/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 arg:
try:
jid = JID(arg)
except InvalidJID:
self.core.information('JID not well-formed', 'Error')
return
elif isinstance(item, Contact):
jid = item.bare_jid
elif isinstance(item, Resource):
jid = item.jid.bare
self.core.xmpp.plugin['xep_0191'].unblock(jid, block=False, callback=callback)
def completion_unblock(self, the_input):
"""
Completion for /unblock
"""
try:
iq = self.core.xmpp.plugin['xep_0191'].get_blocked(block=True)
except Exception as e:
iq = e.iq
finally:
if iq['type'] == 'error':
return
l = [str(item) for item in iq['blocklist']['items']]
return the_input.auto_completion(l, quotify=False)
def command_list_blocks(self, arg=None):
"""
/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'
log.debug('COCUCOCOCOCOCOCOC\n%s\n\n', iq['blocklist']['items'])
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(block=False, callback=callback)
def resize(self): def resize(self):
if not self.visible: if not self.visible:
return return