diff --git a/gajim/chat_control.py b/gajim/chat_control.py index 36dea2c60071ee3ec88a006d4231254064a98505..2a142ef02b9943f7868d56f2dcf4aed1a52d0a61 100644 --- a/gajim/chat_control.py +++ b/gajim/chat_control.py @@ -651,6 +651,7 @@ def _on_zeroconf_error(self, event): def _on_update_roster_avatar(self, obj): self._update_avatar() + @event_filter(['account']) def _nec_ping(self, event): if self.contact != event.contact: return @@ -660,7 +661,7 @@ def _nec_ping(self, event): self.add_info_message( _('Pong! (%s seconds)') % event.seconds) elif event.name == 'ping-error': - self.add_info_message(_('Error.')) + self.add_info_message(event.error) def change_resource(self, resource): old_full_jid = self.get_full_jid() diff --git a/gajim/command_system/implementation/standard.py b/gajim/command_system/implementation/standard.py index 530d801084de1dc0c48b5ca93a66605db6174848..c1ba19d2522454c4af7f64d79daa9a821005b797 100644 --- a/gajim/command_system/implementation/standard.py +++ b/gajim/command_system/implementation/standard.py @@ -419,4 +419,6 @@ def ping(self, nick): raise CommandError( _('Command is not supported for zeroconf accounts')) gc_c = app.contacts.get_gc_contact(self.account, self.room_jid, nick) + if gc_c is None: + raise CommandError(_("Unknown nickname")) app.connections[self.account].get_module('Ping').send_ping(gc_c) diff --git a/gajim/common/modules/ping.py b/gajim/common/modules/ping.py index 5a4224d2cbe392fed08f69a0035a9ce6d01bf63e..02849d92ba2f1733ddd2fc804571dca44254c585 100644 --- a/gajim/common/modules/ping.py +++ b/gajim/common/modules/ping.py @@ -19,91 +19,62 @@ import time -import nbxmpp -from nbxmpp.namespaces import Namespace -from nbxmpp.structs import StanzaHandler +from nbxmpp.errors import is_error from gajim.common import app -from gajim.common.nec import NetworkIncomingEvent +from gajim.common.nec import NetworkEvent from gajim.common.types import ConnectionT from gajim.common.types import ContactsT from gajim.common.modules.base import BaseModule +from gajim.common.modules.util import as_task class Ping(BaseModule): + + _nbxmpp_extends = 'Ping' + _nbxmpp_methods = [ + 'ping', + ] + def __init__(self, con: ConnectionT) -> None: BaseModule.__init__(self, con) - self.handlers = [ - StanzaHandler(name='iq', - callback=self._answer_request, - typ='get', - ns=Namespace.PING), - ] - - @staticmethod - def _get_ping_iq(to: str) -> nbxmpp.Iq: - iq = nbxmpp.Iq('get', to=to) - iq.addChild(name='ping', namespace=Namespace.PING) - return iq + self.handlers = [] + @as_task def send_ping(self, contact: ContactsT) -> None: + _task = yield + if not app.account_is_available(self._account): return - to = contact.get_full_jid() - iq = self._get_ping_iq(to) + jid = contact.get_full_jid() - self._log.info('Send ping to %s', to) + self._log.info('Send ping to %s', jid) - self._con.connection.SendAndCallForResponse( - iq, self._pong_received, {'ping_time': time.time(), - 'contact': contact}) + app.nec.push_incoming_event(NetworkEvent('ping-sent', + account=self._account, + contact=contact)) - app.nec.push_incoming_event( - PingSentEvent(None, conn=self._con, contact=contact)) + ping_time = time.time() - def _pong_received(self, - _nbxmpp_client: Any, - stanza: nbxmpp.Iq, - ping_time: int, - contact: ContactsT) -> None: - if not nbxmpp.isResultNode(stanza): - self._log.info('Error: %s', stanza.getError()) - app.nec.push_incoming_event( - PingErrorEvent(None, conn=self._con, contact=contact)) + response = yield self.ping(jid, timeout=10) + if is_error(response): + app.nec.push_incoming_event(NetworkEvent( + 'ping-error', + account=self._account, + contact=contact, + error=str(response))) return + diff = round(time.time() - ping_time, 2) self._log.info('Received pong from %s after %s seconds', - stanza.getFrom(), diff) - app.nec.push_incoming_event( - PingReplyEvent(None, conn=self._con, - contact=contact, - seconds=diff)) - - def _answer_request(self, - _con: ConnectionT, - stanza: nbxmpp.Iq, - _properties: Any) -> None: - iq = stanza.buildReply('result') - ping = iq.getTag('ping') - if ping is not None: - iq.delChild(ping) - self._con.connection.send(iq) - self._log.info('Send pong to %s', stanza.getFrom()) - raise nbxmpp.NodeProcessed - - -class PingSentEvent(NetworkIncomingEvent): - name = 'ping-sent' - - -class PingReplyEvent(NetworkIncomingEvent): - name = 'ping-reply' - + response.jid, diff) -class PingErrorEvent(NetworkIncomingEvent): - name = 'ping-error' + app.nec.push_incoming_event(NetworkEvent('ping-reply', + account=self._account, + contact=contact, + seconds=diff)) def get_instance(*args: Any, **kwargs: Any) -> Tuple[Ping, str]: diff --git a/gajim/groupchat_control.py b/gajim/groupchat_control.py index 47c1e52acb1d7d9fd5726d00b3f4308e6ac2c7de..77954c930d52d3a636990d2be9b1062cc3ec6119 100644 --- a/gajim/groupchat_control.py +++ b/gajim/groupchat_control.py @@ -1070,7 +1070,11 @@ def _nec_our_status(self, event): if self.parent_win: self.parent_win.redraw_tab(self) + @event_filter(['account']) def _nec_ping(self, event): + if not event.contact.is_groupchat: + return + if self.contact.jid != event.contact.room_jid: return @@ -1082,7 +1086,7 @@ def _nec_ping(self, event): _('Pong! (%(nick)s %(delay)s s.)') % {'nick': nick, 'delay': event.seconds}) elif event.name == 'ping-error': - self.add_info_message(_('Error.')) + self.add_info_message(event.error) @property def is_connected(self) -> bool: