diff --git a/gajim/common/connection.py b/gajim/common/connection.py
index 6a0f2c63a..f004520cd 100644
--- a/gajim/common/connection.py
+++ b/gajim/common/connection.py
@@ -1486,6 +1486,9 @@ class Connection(CommonConnection, ConnectionHandlers):
# Get bookmarks
self.get_module('Bookmarks').request_bookmarks()
+ # Enable Software Version
+ self.get_module('SoftwareVersion').set_enabled(True)
+
# Get annotations
self.get_module('Annotations').request_annotations()
diff --git a/gajim/common/modules/software_version.py b/gajim/common/modules/software_version.py
index 56f891b8a..86f5cb0fa 100644
--- a/gajim/common/modules/software_version.py
+++ b/gajim/common/modules/software_version.py
@@ -6,101 +6,39 @@
#
# Gajim 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
+# 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 Gajim. If not, see .
+# along with Gajim. If not, see .
# XEP-0092: Software Version
-import nbxmpp
-from nbxmpp.structs import StanzaHandler
-
from gajim.common import app
from gajim.common.helpers import get_os_info
-from gajim.common.nec import NetworkIncomingEvent
from gajim.common.modules.base import BaseModule
class SoftwareVersion(BaseModule):
+
+ _nbxmpp_extends = 'SoftwareVersion'
+ _nbxmpp_methods = [
+ 'set_software_version',
+ 'request_software_version',
+ 'disable',
+ ]
+
def __init__(self, con):
BaseModule.__init__(self, con)
- self.handlers = [
- StanzaHandler(name='iq',
- callback=self._answer_request,
- typ='get',
- ns=nbxmpp.NS_VERSION),
- ]
-
- def request_os_info(self, jid, resource):
- if not app.account_is_connected(self._account):
- return
- # If we are invisible, do not request
- if self._con.connected == app.SHOW_LIST.index('invisible'):
- return
-
- if resource:
- jid += '/' + resource
- iq = nbxmpp.Iq(to=jid, typ='get', queryNS=nbxmpp.NS_VERSION)
-
- self._log.info('Requested: %s', jid)
-
- self._con.connection.SendAndCallForResponse(iq, self._result_received)
-
- def _result_received(self, stanza):
- client_info, os_info = None, None
- if not nbxmpp.isResultNode(stanza):
- self._log.info('Error: %s', stanza.getError())
+ def set_enabled(self, enabled):
+ if enabled:
+ if not app.config.get_per('accounts', self._account, 'send_os_info'):
+ return
+ self._nbxmpp('SoftwareVersion').set_software_version(
+ 'Gajim', app.version, get_os_info())
else:
- try:
- client_info, os_info = self._extract_info(stanza)
- except Exception:
- self._log.exception('Error')
- self._log.error(stanza)
-
- self._log.info('Received: %s %s %s',
- stanza.getFrom(), client_info, os_info)
-
- app.nec.push_incoming_event(
- VersionResultReceivedEvent(None, conn=self._con,
- jid=stanza.getFrom(),
- client_info=client_info,
- os_info=os_info))
-
- @staticmethod
- def _extract_info(stanza):
- query = stanza.getTag('query')
- name = query.getTag('name').getData()
- version = query.getTag('version').getData()
- client_info = '%s %s' % (name, version)
- os_info = query.getTag('os')
- if os_info is not None:
- os_info = os_info.getData()
- return client_info, os_info
-
- def _answer_request(self, _con, stanza, _properties):
- self._log.info('%s asked for the software version', stanza.getFrom())
- if app.config.get_per('accounts', self._account, 'send_os_info'):
- os_info = get_os_info()
- iq = stanza.buildReply('result')
- query = iq.getQuery()
- query.setTagData('name', 'Gajim')
- query.setTagData('version', app.version)
- query.setTagData('os', os_info)
- self._log.info('Answer: Gajim %s %s', app.version, os_info)
- else:
- iq = stanza.buildReply('error')
- err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
- iq.addChild(node=err)
- self._log.info('Send service-unavailable')
- self._con.connection.send(iq)
- raise nbxmpp.NodeProcessed
-
-
-class VersionResultReceivedEvent(NetworkIncomingEvent):
- name = 'version-result-received'
+ self._nbxmpp('SoftwareVersion').disable()
def get_instance(*args, **kwargs):
diff --git a/gajim/gtk/preferences.py b/gajim/gtk/preferences.py
index 2b542c5ab..f0b4bf776 100644
--- a/gajim/gtk/preferences.py
+++ b/gajim/gtk/preferences.py
@@ -879,6 +879,8 @@ class Preferences(Gtk.ApplicationWindow):
def on_send_os_info_checkbutton_toggled(self, widget):
widget.set_inconsistent(False)
self.on_per_account_checkbutton_toggled(widget, 'send_os_info')
+ for con in app.connections.values():
+ con.get_module('SoftwareVersion').set_enabled(widget.get_active())
def on_ignore_events_from_unknown_contacts_checkbutton_toggled(self, widget):
widget.set_inconsistent(False)
diff --git a/gajim/gtk/server_info.py b/gajim/gtk/server_info.py
index 7aa4e2b4a..670d7b54a 100644
--- a/gajim/gtk/server_info.py
+++ b/gajim/gtk/server_info.py
@@ -17,6 +17,7 @@ from collections import namedtuple
from datetime import timedelta
import nbxmpp
+from nbxmpp.util import is_error_result
from gi.repository import Gtk
from gi.repository import Gdk
@@ -24,6 +25,8 @@ from gajim.common import app
from gajim.common import ged
from gajim.common.i18n import _
+from gajim.gtk.util import ensure_not_destroyed
+
log = logging.getLogger('gajim.gtk.serverinfo')
@@ -34,6 +37,7 @@ class ServerInfoDialog(Gtk.Dialog):
destroy_with_parent=True)
self.account = account
+ self._destroyed = False
self.set_transient_for(app.interface.roster.window)
self.set_resizable(False)
@@ -69,10 +73,6 @@ class ServerInfoDialog(Gtk.Dialog):
self.connect('response', self.on_response)
self.connect('destroy', self.on_destroy)
- app.ged.register_event_handler('version-result-received',
- ged.CORE,
- self._nec_version_result_received)
-
app.ged.register_event_handler('server-disco-received',
ged.GUI1,
self._server_disco_received)
@@ -81,7 +81,8 @@ class ServerInfoDialog(Gtk.Dialog):
self.uptime = ''
self.hostname = app.get_hostname_from_account(account)
con = app.connections[account]
- con.get_module('SoftwareVersion').request_os_info(self.hostname, None)
+ con.get_module('SoftwareVersion').request_software_version(
+ self.hostname, callback=self._software_version_received)
self.request_last_activity()
for feature in self.get_features():
@@ -138,10 +139,12 @@ class ServerInfoDialog(Gtk.Dialog):
'days': delta.days, 'hours': hours}
self.update(self.get_infos, self.info_listbox)
- def _nec_version_result_received(self, obj):
- if obj.jid != self.hostname:
- return
- self.version = obj.client_info or _('Unknown')
+ @ensure_not_destroyed
+ def _software_version_received(self, result):
+ if is_error_result(result):
+ self.version = _('Unknown')
+ else:
+ self.version = '%s %s' % (result.name, result.version)
self.update(self.get_infos, self.info_listbox)
def _server_disco_received(self, obj):
@@ -229,11 +232,8 @@ class ServerInfoDialog(Gtk.Dialog):
self.destroy()
def on_destroy(self, *args):
+ self._destroyed = True
del app.interface.instances[self.account]['server_info']
- app.ged.remove_event_handler('version-result-received',
- ged.CORE,
- self._nec_version_result_received)
-
app.ged.remove_event_handler('server-disco-received',
ged.GUI1,
self._server_disco_received)
diff --git a/gajim/remote_control.py b/gajim/remote_control.py
index 45364b1d6..ca1ee742a 100644
--- a/gajim/remote_control.py
+++ b/gajim/remote_control.py
@@ -267,9 +267,6 @@ class GajimRemote(Server):
-
-
-
@@ -299,8 +296,6 @@ class GajimRemote(Server):
super().__init__(self.con, '/org/gajim/dbus/RemoteObject')
self.first_show = True
- app.ged.register_event_handler('version-result-received', ged.POSTGUI,
- self.on_os_info)
app.ged.register_event_handler('time-result-received', ged.POSTGUI,
self.on_time)
app.ged.register_event_handler('roster-info', ged.POSTGUI,
@@ -346,12 +341,6 @@ class GajimRemote(Server):
self.raise_signal('MessageSent', (obj.conn.name, [
obj.jid, obj.message, obj.keyID, chatstate]))
- def on_os_info(self, obj):
- self.raise_signal('OsInfo', (obj.conn.name, [obj.jid.getStripped(),
- obj.jid.getResource(),
- obj.client_info,
- obj.os_info]))
-
def on_time(self, obj):
self.raise_signal('EntityTime', (obj.conn.name, [obj.jid.getStripped(),
obj.jid.getResource(),
diff --git a/gajim/vcard.py b/gajim/vcard.py
index 9dae488e6..ca3550e8e 100644
--- a/gajim/vcard.py
+++ b/gajim/vcard.py
@@ -33,6 +33,8 @@ from gi.repository import Gtk
from gi.repository import GLib
from gi.repository import Gdk
from nbxmpp.structs import AnnotationNote
+from nbxmpp.util import is_error_result
+from nbxmpp.protocol import JID
from gajim import gtkgui_helpers
from gajim.gui_menu_builder import show_save_as_menu
@@ -102,8 +104,6 @@ class VcardWindow:
self.update_progressbar_timeout_id = GLib.timeout_add(self.update_intervall,
self.update_progressbar)
- app.ged.register_event_handler('version-result-received', ged.GUI1,
- self.set_os_info)
app.ged.register_event_handler('time-result-received', ged.GUI1,
self.set_entity_time)
@@ -148,8 +148,6 @@ class VcardWindow:
if note is None or new_annotation != note.data:
new_note = AnnotationNote(jid=self.contact.jid, data=new_annotation)
con.get_module('Annotations').set_note(new_note)
- app.ged.remove_event_handler('version-result-received', ged.GUI1,
- self.set_os_info)
app.ged.remove_event_handler('time-result-received', ged.GUI1,
self.set_entity_time)
@@ -263,34 +261,27 @@ class VcardWindow:
self.clear_values()
self._set_values(vcard, jid)
- def set_os_info(self, obj):
- if obj.conn.name != self.account:
- return
+ def set_os_info(self, result, jid):
if self.xml.get_object('information_notebook').get_n_pages() < 5:
return
- if self.gc_contact:
- if obj.jid != self.contact.jid:
- return
- elif obj.jid.getStripped() != self.contact.jid:
- return
+
+ error = is_error_result(result)
i = 0
client = ''
os_info = ''
while i in self.os_info:
- if self.os_info[i]['resource'] == obj.jid.getResource():
- if obj.client_info:
- self.os_info[i]['client'] = obj.client_info
+ if self.os_info[i]['resource'] == JID(jid).getResource():
+ if not error:
+ self.os_info[i]['client'] = '%s %s' % (result.name,
+ result.version)
else:
self.os_info[i]['client'] = Q_('?Client:Unknown')
- if obj.os_info:
- self.os_info[i]['os'] = obj.os_info
+
+ if not error and result.os is not None:
+ self.os_info[i]['os'] = result.os
else:
self.os_info[i]['os'] = Q_('?OS:Unknown')
- else:
- if not self.os_info[i]['client']:
- self.os_info[i]['client'] = Q_('?Client:Unknown')
- if not self.os_info[i]['os']:
- self.os_info[i]['os'] = Q_('?OS:Unknown')
+
if i > 0:
client += '\n'
os_info += '\n'
@@ -417,12 +408,16 @@ class VcardWindow:
self.os_info_arrived = True
else: # Request os info if contact is connected
if self.gc_contact:
- j, r = app.get_room_and_nick_from_fjid(self.real_jid)
- GLib.idle_add(con.get_module('SoftwareVersion').request_os_info,
- j, r)
+ con.get_module('SoftwareVersion').request_software_version(
+ self.real_jid,
+ callback=self.set_os_info,
+ user_data=self.real_jid)
else:
- GLib.idle_add(con.get_module('SoftwareVersion').request_os_info,
- self.contact.jid, self.contact.resource)
+ jid = self.contact.get_full_jid()
+ con.get_module('SoftwareVersion').request_software_version(
+ jid,
+ callback=self.set_os_info,
+ user_data=jid)
# do not wait for entity_time if contact is not connected or has error
# additional check for observer is needed, as show is offline for him
@@ -451,8 +446,9 @@ class VcardWindow:
uf_resources += '\n' + c.resource + \
_(' resource with priority ') + str(c.priority)
if c.show not in ('offline', 'error'):
- GLib.idle_add(con.get_module('SoftwareVersion').request_os_info,
- c.jid, c.resource)
+ jid = c.get_full_jid()
+ con.get_module('SoftwareVersion').request_software_version(
+ jid, callback=self.set_os_info, user_data=jid)
GLib.idle_add(con.get_module('EntityTime').request_entity_time,
c.jid, c.resource)
self.os_info[i] = {'resource': c.resource, 'client': '',