diff options
author | lovetox <philipp@hoerist.com> | 2020-09-24 15:34:23 +0300 |
---|---|---|
committer | lovetox <philipp@hoerist.com> | 2020-09-25 17:46:41 +0300 |
commit | aa662a443cc23c9f89d081bcfc81d2eb85f5c011 (patch) | |
tree | 21f88c99509859df1d50f21c5d85ef89c8e4aa2b /nbxmpp | |
parent | bcb25603ea3f44a8060f4c7f0970117d17067f56 (diff) |
MUC: Add request_info()
This method returns the disco info and vcard of a MUC
Diffstat (limited to 'nbxmpp')
-rw-r--r-- | nbxmpp/modules/muc.py | 55 | ||||
-rw-r--r-- | nbxmpp/modules/util.py | 22 |
2 files changed, 77 insertions, 0 deletions
diff --git a/nbxmpp/modules/muc.py b/nbxmpp/modules/muc.py index 50b8d7d..5e9e806 100644 --- a/nbxmpp/modules/muc.py +++ b/nbxmpp/modules/muc.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU General Public License # along with this program; If not, see <http://www.gnu.org/licenses/>. +from dataclasses import dataclass + from nbxmpp.namespaces import Namespace from nbxmpp.protocol import ERR_NOT_ACCEPTABLE from nbxmpp.protocol import JID @@ -41,14 +43,24 @@ from nbxmpp.structs import CommonResult from nbxmpp.structs import MucConfigResult from nbxmpp.structs import MucUserData from nbxmpp.structs import MucDestroyed +from nbxmpp.task import iq_request_task from nbxmpp.util import call_on_response from nbxmpp.util import callback from nbxmpp.util import raise_error +from nbxmpp.errors import is_error +from nbxmpp.modules.util import raise_if_error +from nbxmpp.modules.util import parse_xmpp_uri from nbxmpp.modules.dataforms import extend_form from nbxmpp.modules.base import BaseModule class MUC(BaseModule): + + _depends = { + 'disco_info': 'Discovery', + 'request_vcard': 'VCardTemp', + } + def __init__(self, client): BaseModule.__init__(self, client) @@ -380,6 +392,42 @@ class MUC(BaseModule): room_jid, reason, jid) return iq + @iq_request_task + def request_info(self, jid, request_vcard=True, allow_redirect=False): + _task = yield + + redirected = False + + disco_info = yield self.disco_info(jid) + if is_error(disco_info): + error_response = disco_info + + if not allow_redirect: + raise error_response + + if error_response.condition != 'gone': + raise error_response + + try: + jid = parse_xmpp_uri(error_response.condition_data)[0] + except Exception: + raise error_response + + redirected = True + disco_info = yield self.disco_info(jid) + raise_if_error(disco_info) + + if not request_vcard or not disco_info.supports(Namespace.VCARD): + yield MucInfoResult(info=disco_info, redirected=redirected) + + vcard = yield self.request_vcard(jid) + if is_error(vcard): + yield MucInfoResult(info=disco_info, redirected=redirected) + + yield MucInfoResult(info=disco_info, + vcard=vcard, + redirected=redirected) + @call_on_response('_default_response') def set_config(self, room_jid, form): iq = Iq(typ='set', to=room_jid, queryNS=Namespace.MUC_OWNER) @@ -577,3 +625,10 @@ class MUC(BaseModule): role=role, actor=item.getTagAttr('actor', 'nick'), reason=item.getTagData('reason')) + + +@dataclass +class MucInfoResult: + info: object + vcard: object = None + redirected: bool = False diff --git a/nbxmpp/modules/util.py b/nbxmpp/modules/util.py index 919175b..2f0035f 100644 --- a/nbxmpp/modules/util.py +++ b/nbxmpp/modules/util.py @@ -15,6 +15,9 @@ # You should have received a copy of the GNU General Public License # along with this program; If not, see <http://www.gnu.org/licenses/>. +from urllib.parse import urlparse +from urllib.parse import unquote + from nbxmpp.structs import CommonResult from nbxmpp.errors import StanzaError from nbxmpp.errors import is_error @@ -39,3 +42,22 @@ def finalize(task, result): if isinstance(result, Node): return task.set_result(result) return result + + +def parse_xmpp_uri(uri): + url = urlparse(uri) + if url.scheme != 'xmpp': + raise ValueError('not a xmpp uri') + + if not ';' in url.query: + return (url.path, url.query, {}) + + action, query = url.query.split(';', 1) + key_value_pairs = query.split(';') + + dict_ = {} + for key_value in key_value_pairs: + key, value = key_value.split('=') + dict_[key] = unquote(value) + + return (url.path, action, dict_) |