diff options
Diffstat (limited to 'poezio/multiuserchat.py')
-rw-r--r-- | poezio/multiuserchat.py | 233 |
1 files changed, 61 insertions, 172 deletions
diff --git a/poezio/multiuserchat.py b/poezio/multiuserchat.py index 30c36a77..3278e1bd 100644 --- a/poezio/multiuserchat.py +++ b/poezio/multiuserchat.py @@ -3,77 +3,51 @@ # This file is part of Poezio. # # Poezio is free software: you can redistribute it and/or modify -# it under the terms of the zlib license. See the COPYING file. +# it under the terms of the GPL-3.0+ license. See the COPYING file. """ Implementation of the XEP-0045: Multi-User Chat. Add some facilities that are not available on the XEP_0045 slix plugin """ +from __future__ import annotations + +import asyncio from xml.etree import ElementTree as ET +from typing import ( + Optional, + Union, + TYPE_CHECKING, +) + +from slixmpp import ( + JID, + ClientXMPP, + Iq, + Presence, +) -from poezio.common import safeJID -from slixmpp import JID -from slixmpp.exceptions import IqError, IqTimeout import logging log = logging.getLogger(__name__) -NS_MUC_ADMIN = 'http://jabber.org/protocol/muc#admin' -NS_MUC_OWNER = 'http://jabber.org/protocol/muc#owner' - - -def destroy_room(xmpp, room, reason='', altroom=''): - """ - destroy a room - """ - room = safeJID(room) - if not room: - return False - iq = xmpp.make_iq_set() - iq['to'] = room - query = ET.Element('{%s}query' % NS_MUC_OWNER) - destroy = ET.Element('{%s}destroy' % NS_MUC_OWNER) - if altroom: - destroy.attrib['jid'] = altroom - if reason: - xreason = ET.Element('{%s}reason' % NS_MUC_OWNER) - xreason.text = reason - destroy.append(xreason) - query.append(destroy) - iq.append(query) - - def callback(iq): - if not iq or iq['type'] == 'error': - xmpp.core.information('Unable to destroy room %s' % room, 'Info') - else: - xmpp.core.information('Room %s destroyed' % room, 'Info') - - iq.send(callback=callback) - return True - -def send_private_message(xmpp, jid, line): - """ - Send a private message - """ - jid = safeJID(jid) - xmpp.send_message(mto=jid, mbody=line, mtype='chat') - - -def send_groupchat_message(xmpp, jid, line): - """ - Send a message to the groupchat - """ - jid = safeJID(jid) - xmpp.send_message(mto=jid, mbody=line, mtype='groupchat') +if TYPE_CHECKING: + from poezio.core.core import Core + from poezio.tabs import MucTab -def change_show(xmpp, jid: JID, own_nick: str, show, status): +def change_show( + xmpp: ClientXMPP, + jid: JID, + own_nick: str, + show: str, + status: Optional[str] +) -> None: """ Change our 'Show' """ - jid = safeJID(jid) - pres = xmpp.make_presence(pto='%s/%s' % (jid, own_nick)) + jid = JID(jid) + pres: Presence = xmpp.make_presence(pto='%s/%s' % (jid, own_nick)) if show: # if show is None, don't put a <show /> tag. It means "available" pres['type'] = show if status: @@ -81,46 +55,45 @@ def change_show(xmpp, jid: JID, own_nick: str, show, status): pres.send() -def change_subject(xmpp, jid, subject): - """ - Change the room subject - """ - jid = safeJID(jid) - msg = xmpp.make_message(jid) - msg['type'] = 'groupchat' - msg['subject'] = subject - msg.send() - - -def change_nick(core, jid, nick, status=None, show=None): +def change_nick( + core: Core, + jid: Union[JID, str], + nick: str, + status: Optional[str] = None, + show: Optional[str] = None +) -> None: """ Change our own nick in a room """ xmpp = core.xmpp - presence = xmpp.make_presence( - pshow=show, pstatus=status, pto=safeJID('%s/%s' % (jid, nick))) + presence: Presence = xmpp.make_presence( + pshow=show, pstatus=status, pto=JID('%s/%s' % (jid, nick))) core.events.trigger('changing_nick', presence) presence.send() -def join_groupchat(core, - jid, - nick, - passwd='', - status=None, - show=None, - seconds=None, - tab=None): +def join_groupchat( + core: Core, + jid: JID, + nick: str, + passwd: str = '', + status: Optional[str] = None, + show: Optional[str] = None, + seconds: Optional[int] = None, + tab: Optional['MucTab'] = None +) -> None: xmpp = core.xmpp - stanza = xmpp.make_presence( + stanza: Presence = xmpp.make_presence( pto='%s/%s' % (jid, nick), pstatus=status, pshow=show) x = ET.Element('{http://jabber.org/protocol/muc}x') if passwd: passelement = ET.Element('password') passelement.text = passwd x.append(passelement) - def on_disco(iq): - if 'urn:xmpp:mam:2' in iq['disco_info'].get_features() or (tab and tab._text_buffer.last_message): + + def on_disco(iq: Iq) -> None: + if ('urn:xmpp:mam:2' in iq['disco_info'].get_features() + or (tab and tab._text_buffer.last_message)): history = ET.Element('{http://jabber.org/protocol/muc}history') history.attrib['seconds'] = str(0) x.append(history) @@ -136,17 +109,21 @@ def join_groupchat(core, xmpp.plugin['xep_0045'].rooms[jid] = {} xmpp.plugin['xep_0045'].our_nicks[jid] = to.resource - try: + asyncio.create_task( xmpp.plugin['xep_0030'].get_info(jid=jid, callback=on_disco) - except (IqError, IqTimeout): - return core.information('Failed to retrieve messages', 'Error') + ) -def leave_groupchat(xmpp, jid, own_nick, msg): +def leave_groupchat( + xmpp: ClientXMPP, + jid: JID, + own_nick: str, + msg: str +) -> None: """ Leave the groupchat """ - jid = safeJID(jid) + jid = JID(jid) try: xmpp.plugin['xep_0045'].leave_muc(jid, own_nick, msg) except KeyError: @@ -154,91 +131,3 @@ def leave_groupchat(xmpp, jid, own_nick, msg): "muc.leave_groupchat: could not leave the room %s", jid, exc_info=True) - - -def set_user_role(xmpp, jid, nick, reason, role, callback=None): - """ - (try to) Set the role of a MUC user - (role = 'none': eject user) - """ - jid = safeJID(jid) - iq = xmpp.make_iq_set() - query = ET.Element('{%s}query' % NS_MUC_ADMIN) - item = ET.Element('{%s}item' % NS_MUC_ADMIN, {'nick': nick, 'role': role}) - if reason: - reason_el = ET.Element('{%s}reason' % NS_MUC_ADMIN) - reason_el.text = reason - item.append(reason_el) - query.append(item) - iq.append(query) - iq['to'] = jid - if callback: - return iq.send(callback=callback) - try: - return iq.send() - except (IqError, IqTimeout) as e: - return e.iq - - -def set_user_affiliation(xmpp, - muc_jid, - affiliation, - nick=None, - jid=None, - reason=None, - callback=None): - """ - (try to) Set the affiliation of a MUC user - """ - muc_jid = safeJID(muc_jid) - query = ET.Element('{http://jabber.org/protocol/muc#admin}query') - if nick: - item = ET.Element('{http://jabber.org/protocol/muc#admin}item', { - 'affiliation': affiliation, - 'nick': nick - }) - else: - item = ET.Element('{http://jabber.org/protocol/muc#admin}item', { - 'affiliation': affiliation, - 'jid': str(jid) - }) - - if reason: - reason_item = ET.Element( - '{http://jabber.org/protocol/muc#admin}reason') - reason_item.text = reason - item.append(reason_item) - - query.append(item) - iq = xmpp.make_iq_set(query) - iq['to'] = muc_jid - if callback: - return iq.send(callback=callback) - try: - return xmpp.plugin['xep_0045'].set_affiliation( - str(muc_jid), - str(jid) if jid else None, nick, affiliation) - except: - log.debug('Error setting the affiliation: %s', exc_info=True) - return False - - -def cancel_config(xmpp, room): - query = ET.Element('{http://jabber.org/protocol/muc#owner}query') - x = ET.Element('{jabber:x:data}x', type='cancel') - query.append(x) - iq = xmpp.make_iq_set(query) - iq['to'] = room - iq.send() - - -def configure_room(xmpp, room, form): - if form is None: - return - iq = xmpp.make_iq_set() - iq['to'] = room - query = ET.Element('{http://jabber.org/protocol/muc#owner}query') - form['type'] = 'submit' - query.append(form.xml) - iq.append(query) - iq.send() |