From c97411495561daaab5f683158478f0f91ad985b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Fri, 8 Feb 2019 01:18:23 +0000 Subject: [PATCH] Fix #2280: Allow /affiliation to list all affiliations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- poezio/tabs/muctab.py | 49 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/poezio/tabs/muctab.py b/poezio/tabs/muctab.py index 3e754ae6..657908c2 100644 --- a/poezio/tabs/muctab.py +++ b/poezio/tabs/muctab.py @@ -7,6 +7,7 @@ It keeps track of many things such as part/joins, maintains an user list, and updates private tabs when necessary. """ +import asyncio import bisect import curses import logging @@ -20,6 +21,7 @@ from datetime import datetime from typing import Dict, Callable, List, Optional, Union, Set from slixmpp import InvalidJID, JID +from slixmpp.exceptions import IqError, IqTimeout from poezio.tabs import ChatTab, Tab, SHOW_NAME from poezio import common @@ -1596,24 +1598,55 @@ class MucTab(ChatTab): nick, role, reason = args[0], args[1].lower(), args[2] self.change_role(nick, role, reason) - @command_args_parser.quoted(2) - def command_affiliation(self, args): + @command_args_parser.quoted(0, 2) + def command_affiliation(self, args) -> None: """ - /affiliation + /affiliation [ []] Changes the affiliation of a user affiliations can be: outcast, none, member, admin, owner """ - def callback(iq): - if iq['type'] == 'error': - self.core.room_error(iq, self.jid.bare) + room = JID(self.name) + if not room: + self.core.information('affiliation: requires a valid chat address', 'Error') + return - if args is None: + # List affiliations + if not args: + asyncio.ensure_future(self.get_users_affiliations(room)) + return None + + if len(args) != 2: return self.core.command.help('affiliation') nick, affiliation = args[0], args[1].lower() + # Set affiliation self.change_affiliation(nick, affiliation) + async def get_users_affiliations(self, jid: JID) -> None: + MUC_ADMIN_NS = 'http://jabber.org/protocol/muc#admin' + + try: + iqs = await asyncio.gather( + self.core.xmpp['xep_0045'].get_users_by_affiliation(jid, 'owner'), + self.core.xmpp['xep_0045'].get_users_by_affiliation(jid, 'admin'), + self.core.xmpp['xep_0045'].get_users_by_affiliation(jid, 'member'), + self.core.xmpp['xep_0045'].get_users_by_affiliation(jid, 'outcast'), + ) + except (IqError, IqTimeout) as exn: + self.core.room_error(exn.iq, jid) + return None + + self._text_buffer.add_message('Affiliations:') + for iq in iqs: + query = iq.xml.find('{%s}query' % MUC_ADMIN_NS) + for item in query.findall('{%s}item' % MUC_ADMIN_NS): + self._text_buffer.add_message( + '%s: %s' % (item.get('jid'), item.get('affiliation')) + ) + self.refresh() + return None + @command_args_parser.raw def command_say(self, line, correct=False): """ @@ -1936,7 +1969,7 @@ class MucTab(ChatTab): 'func': self.command_affiliation, 'usage': - ' ', + '[ []]', 'desc': ('Set the affiliation of a user. Affiliations can be:' ' outcast, none, member, admin, owner.'), 'shortdesc':