Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits: a161f7fa by Philipp Hörist at 2019-04-03T16:54:07Z Add Software Version (XEP-0092) module
- - - - - 79330a50 by Philipp Hörist at 2019-04-03T19:30:17Z Detect direct invite correctly
- - - - -
4 changed files:
- nbxmpp/dispatcher.py - nbxmpp/modules/muc.py - + nbxmpp/modules/software_version.py - nbxmpp/structs.py
Changes:
===================================== nbxmpp/dispatcher.py ===================================== @@ -66,6 +66,7 @@ from nbxmpp.modules.openpgp import OpenPGP from nbxmpp.modules.omemo import OMEMO from nbxmpp.modules.annotations import Annotations from nbxmpp.modules.muclumbus import Muclumbus +from nbxmpp.modules.software_version import SoftwareVersion from nbxmpp.modules.misc import unwrap_carbon from nbxmpp.modules.misc import unwrap_mam from nbxmpp.util import get_properties_struct @@ -200,6 +201,7 @@ class XMPPDispatcher(PlugIn): self._modules['OMEMO'] = OMEMO(self._owner) self._modules['Annotations'] = Annotations(self._owner) self._modules['Muclumbus'] = Muclumbus(self._owner) + self._modules['SoftwareVersion'] = SoftwareVersion(self._owner)
for instance in self._modules.values(): for handler in instance.handlers:
===================================== nbxmpp/modules/muc.py ===================================== @@ -82,7 +82,7 @@ class MUC: callback=self._process_direct_invite, typ='normal', ns=NS_CONFERENCE, - priority=11), + priority=12), StanzaHandler(name='message', callback=self._process_voice_request, ns=NS_DATA, @@ -90,7 +90,7 @@ class MUC: StanzaHandler(name='message', callback=self._process_message, ns=NS_MUC_USER, - priority=12), + priority=13), ]
@staticmethod @@ -225,15 +225,14 @@ class MUC: if direct is None: return
- muc_jid = direct.getAttr('jid') - if muc_jid is None: - # Not a direct invite + if stanza.getTag('x', namespace=NS_MUC_USER) is not None: + # not a direct invite # See https://xmpp.org/extensions/xep-0045.html#example-57 # read implementation notes return
data = {} - data['muc'] = JID(muc_jid) + data['muc'] = JID(direct.getAttr('jid')) data['from_'] = properties.jid data['reason'] = direct.getAttr('reason') data['password'] = direct.getAttr('password')
===================================== nbxmpp/modules/software_version.py ===================================== @@ -0,0 +1,105 @@ +# Copyright (C) 2019 Philipp Hörist <philipp AT hoerist.com> +# +# This file is part of nbxmpp. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; If not, see http://www.gnu.org/licenses/. + +import logging + +from nbxmpp.protocol import NS_VERSION +from nbxmpp.protocol import Iq +from nbxmpp.protocol import isResultNode +from nbxmpp.protocol import ErrorNode +from nbxmpp.protocol import NodeProcessed +from nbxmpp.protocol import ERR_SERVICE_UNAVAILABLE +from nbxmpp.structs import SoftwareVersionResult +from nbxmpp.structs import StanzaHandler +from nbxmpp.util import call_on_response +from nbxmpp.util import callback +from nbxmpp.util import raise_error + +log = logging.getLogger('nbxmpp.m.software_version') + + +class SoftwareVersion: + def __init__(self, client): + self._client = client + self.handlers = [ + StanzaHandler(name='iq', + callback=self._answer_request, + typ='get', + ns=NS_VERSION), + ] + + self._name = None + self._version = None + self._os = None + + self._enabled = False + + def disable(self): + self._enabled = False + + @call_on_response('_software_version_received') + def request_software_version(self, jid): + log.info('Request software version for %s', jid) + return Iq(typ='get', to=jid, queryNS=NS_VERSION) + + @callback + def _software_version_received(self, stanza): + if not isResultNode(stanza): + return raise_error(log.info, stanza) + + try: + return SoftwareVersionResult(*self._parse_info(stanza)) + except Exception as error: + log.warning(error) + return raise_error(log.warning, stanza, 'stanza-malformed') + + @staticmethod + def _parse_info(stanza): + name = stanza.getQueryChild('name').getData() + version = stanza.getQueryChild('version').getData() + + os_info = stanza.getQueryChild('os') + if os_info is not None: + os_info = os_info.getData() + + return name, version, os_info + + def set_software_version(self, name, version, os=None): + self._name, self._version, self._os = name, version, os + self._enabled = True + + def _answer_request(self, _con, stanza, _properties): + log.info('Request received from %s', stanza.getFrom()) + if (not self._enabled or + self._name is None or + self._version is None): + iq = stanza.buildReply('error') + iq.addChild(node=ErrorNode(ERR_SERVICE_UNAVAILABLE)) + log.info('Send service-unavailable') + + else: + iq = stanza.buildReply('result') + query = iq.getQuery() + query.setTagData('name', self._name) + query.setTagData('version', self._version) + if self._os is not None: + query.setTagData('os', self._os) + log.info('Send software version: %s %s %s', + self._name, self._version, self._os) + + self._client.send(iq) + raise NodeProcessed
===================================== nbxmpp/structs.py ===================================== @@ -104,6 +104,8 @@ MuclumbusResult = namedtuple('MuclumbusResult', 'first last max end items')
MuclumbusItem = namedtuple('MuclumbusItem', 'jid name nusers description language is_open anonymity_mode')
+SoftwareVersionResult = namedtuple('SoftwareVersionResult', 'name version os') +
class OMEMOBundle(namedtuple('OMEMOBundle', 'spk spk_signature ik otpks')): def pick_prekey(self):
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/6bdd04662e78d57dc015661bcd...