Refactor Software Version

- Simplify modules because nbxmpp handles more stuff
This commit is contained in:
Philipp Hörist 2019-04-05 17:41:19 +02:00
parent 471d9ca043
commit 239ab1455b
6 changed files with 60 additions and 132 deletions

View File

@ -1486,6 +1486,9 @@ class Connection(CommonConnection, ConnectionHandlers):
# Get bookmarks # Get bookmarks
self.get_module('Bookmarks').request_bookmarks() self.get_module('Bookmarks').request_bookmarks()
# Enable Software Version
self.get_module('SoftwareVersion').set_enabled(True)
# Get annotations # Get annotations
self.get_module('Annotations').request_annotations() self.get_module('Annotations').request_annotations()

View File

@ -6,101 +6,39 @@
# #
# Gajim is distributed in the hope that it will be useful, # Gajim is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # 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. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>. # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
# XEP-0092: Software Version # XEP-0092: Software Version
import nbxmpp
from nbxmpp.structs import StanzaHandler
from gajim.common import app from gajim.common import app
from gajim.common.helpers import get_os_info from gajim.common.helpers import get_os_info
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.modules.base import BaseModule from gajim.common.modules.base import BaseModule
class SoftwareVersion(BaseModule): class SoftwareVersion(BaseModule):
_nbxmpp_extends = 'SoftwareVersion'
_nbxmpp_methods = [
'set_software_version',
'request_software_version',
'disable',
]
def __init__(self, con): def __init__(self, con):
BaseModule.__init__(self, con) BaseModule.__init__(self, con)
self.handlers = [ def set_enabled(self, enabled):
StanzaHandler(name='iq', if enabled:
callback=self._answer_request, if not app.config.get_per('accounts', self._account, 'send_os_info'):
typ='get', return
ns=nbxmpp.NS_VERSION), self._nbxmpp('SoftwareVersion').set_software_version(
] 'Gajim', app.version, get_os_info())
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())
else: else:
try: self._nbxmpp('SoftwareVersion').disable()
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'
def get_instance(*args, **kwargs): def get_instance(*args, **kwargs):

View File

@ -879,6 +879,8 @@ class Preferences(Gtk.ApplicationWindow):
def on_send_os_info_checkbutton_toggled(self, widget): def on_send_os_info_checkbutton_toggled(self, widget):
widget.set_inconsistent(False) widget.set_inconsistent(False)
self.on_per_account_checkbutton_toggled(widget, 'send_os_info') 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): def on_ignore_events_from_unknown_contacts_checkbutton_toggled(self, widget):
widget.set_inconsistent(False) widget.set_inconsistent(False)

View File

@ -17,6 +17,7 @@ from collections import namedtuple
from datetime import timedelta from datetime import timedelta
import nbxmpp import nbxmpp
from nbxmpp.util import is_error_result
from gi.repository import Gtk from gi.repository import Gtk
from gi.repository import Gdk from gi.repository import Gdk
@ -24,6 +25,8 @@ from gajim.common import app
from gajim.common import ged from gajim.common import ged
from gajim.common.i18n import _ from gajim.common.i18n import _
from gajim.gtk.util import ensure_not_destroyed
log = logging.getLogger('gajim.gtk.serverinfo') log = logging.getLogger('gajim.gtk.serverinfo')
@ -34,6 +37,7 @@ class ServerInfoDialog(Gtk.Dialog):
destroy_with_parent=True) destroy_with_parent=True)
self.account = account self.account = account
self._destroyed = False
self.set_transient_for(app.interface.roster.window) self.set_transient_for(app.interface.roster.window)
self.set_resizable(False) self.set_resizable(False)
@ -69,10 +73,6 @@ class ServerInfoDialog(Gtk.Dialog):
self.connect('response', self.on_response) self.connect('response', self.on_response)
self.connect('destroy', self.on_destroy) 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', app.ged.register_event_handler('server-disco-received',
ged.GUI1, ged.GUI1,
self._server_disco_received) self._server_disco_received)
@ -81,7 +81,8 @@ class ServerInfoDialog(Gtk.Dialog):
self.uptime = '' self.uptime = ''
self.hostname = app.get_hostname_from_account(account) self.hostname = app.get_hostname_from_account(account)
con = app.connections[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() self.request_last_activity()
for feature in self.get_features(): for feature in self.get_features():
@ -138,10 +139,12 @@ class ServerInfoDialog(Gtk.Dialog):
'days': delta.days, 'hours': hours} 'days': delta.days, 'hours': hours}
self.update(self.get_infos, self.info_listbox) self.update(self.get_infos, self.info_listbox)
def _nec_version_result_received(self, obj): @ensure_not_destroyed
if obj.jid != self.hostname: def _software_version_received(self, result):
return if is_error_result(result):
self.version = obj.client_info or _('Unknown') self.version = _('Unknown')
else:
self.version = '%s %s' % (result.name, result.version)
self.update(self.get_infos, self.info_listbox) self.update(self.get_infos, self.info_listbox)
def _server_disco_received(self, obj): def _server_disco_received(self, obj):
@ -229,11 +232,8 @@ class ServerInfoDialog(Gtk.Dialog):
self.destroy() self.destroy()
def on_destroy(self, *args): def on_destroy(self, *args):
self._destroyed = True
del app.interface.instances[self.account]['server_info'] 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', app.ged.remove_event_handler('server-disco-received',
ged.GUI1, ged.GUI1,
self._server_disco_received) self._server_disco_received)

View File

@ -267,9 +267,6 @@ class GajimRemote(Server):
<signal name='NewMessage'> <signal name='NewMessage'>
<arg type='av' /> <arg type='av' />
</signal> </signal>
<signal name='OsInfo'>
<arg type='av' />
</signal>
<signal name='Roster'> <signal name='Roster'>
<arg type='av' /> <arg type='av' />
</signal> </signal>
@ -299,8 +296,6 @@ class GajimRemote(Server):
super().__init__(self.con, '/org/gajim/dbus/RemoteObject') super().__init__(self.con, '/org/gajim/dbus/RemoteObject')
self.first_show = True 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, app.ged.register_event_handler('time-result-received', ged.POSTGUI,
self.on_time) self.on_time)
app.ged.register_event_handler('roster-info', ged.POSTGUI, app.ged.register_event_handler('roster-info', ged.POSTGUI,
@ -346,12 +341,6 @@ class GajimRemote(Server):
self.raise_signal('MessageSent', (obj.conn.name, [ self.raise_signal('MessageSent', (obj.conn.name, [
obj.jid, obj.message, obj.keyID, chatstate])) 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): def on_time(self, obj):
self.raise_signal('EntityTime', (obj.conn.name, [obj.jid.getStripped(), self.raise_signal('EntityTime', (obj.conn.name, [obj.jid.getStripped(),
obj.jid.getResource(), obj.jid.getResource(),

View File

@ -33,6 +33,8 @@ from gi.repository import Gtk
from gi.repository import GLib from gi.repository import GLib
from gi.repository import Gdk from gi.repository import Gdk
from nbxmpp.structs import AnnotationNote from nbxmpp.structs import AnnotationNote
from nbxmpp.util import is_error_result
from nbxmpp.protocol import JID
from gajim import gtkgui_helpers from gajim import gtkgui_helpers
from gajim.gui_menu_builder import show_save_as_menu 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_timeout_id = GLib.timeout_add(self.update_intervall,
self.update_progressbar) 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, app.ged.register_event_handler('time-result-received', ged.GUI1,
self.set_entity_time) self.set_entity_time)
@ -148,8 +148,6 @@ class VcardWindow:
if note is None or new_annotation != note.data: if note is None or new_annotation != note.data:
new_note = AnnotationNote(jid=self.contact.jid, data=new_annotation) new_note = AnnotationNote(jid=self.contact.jid, data=new_annotation)
con.get_module('Annotations').set_note(new_note) 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, app.ged.remove_event_handler('time-result-received', ged.GUI1,
self.set_entity_time) self.set_entity_time)
@ -263,34 +261,27 @@ class VcardWindow:
self.clear_values() self.clear_values()
self._set_values(vcard, jid) self._set_values(vcard, jid)
def set_os_info(self, obj): def set_os_info(self, result, jid):
if obj.conn.name != self.account:
return
if self.xml.get_object('information_notebook').get_n_pages() < 5: if self.xml.get_object('information_notebook').get_n_pages() < 5:
return return
if self.gc_contact:
if obj.jid != self.contact.jid: error = is_error_result(result)
return
elif obj.jid.getStripped() != self.contact.jid:
return
i = 0 i = 0
client = '' client = ''
os_info = '' os_info = ''
while i in self.os_info: while i in self.os_info:
if self.os_info[i]['resource'] == obj.jid.getResource(): if self.os_info[i]['resource'] == JID(jid).getResource():
if obj.client_info: if not error:
self.os_info[i]['client'] = obj.client_info self.os_info[i]['client'] = '%s %s' % (result.name,
result.version)
else: else:
self.os_info[i]['client'] = Q_('?Client:Unknown') 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: else:
self.os_info[i]['os'] = Q_('?OS:Unknown') 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: if i > 0:
client += '\n' client += '\n'
os_info += '\n' os_info += '\n'
@ -417,12 +408,16 @@ class VcardWindow:
self.os_info_arrived = True self.os_info_arrived = True
else: # Request os info if contact is connected else: # Request os info if contact is connected
if self.gc_contact: if self.gc_contact:
j, r = app.get_room_and_nick_from_fjid(self.real_jid) con.get_module('SoftwareVersion').request_software_version(
GLib.idle_add(con.get_module('SoftwareVersion').request_os_info, self.real_jid,
j, r) callback=self.set_os_info,
user_data=self.real_jid)
else: else:
GLib.idle_add(con.get_module('SoftwareVersion').request_os_info, jid = self.contact.get_full_jid()
self.contact.jid, self.contact.resource) 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 # 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 # additional check for observer is needed, as show is offline for him
@ -451,8 +446,9 @@ class VcardWindow:
uf_resources += '\n' + c.resource + \ uf_resources += '\n' + c.resource + \
_(' resource with priority ') + str(c.priority) _(' resource with priority ') + str(c.priority)
if c.show not in ('offline', 'error'): if c.show not in ('offline', 'error'):
GLib.idle_add(con.get_module('SoftwareVersion').request_os_info, jid = c.get_full_jid()
c.jid, c.resource) 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, GLib.idle_add(con.get_module('EntityTime').request_entity_time,
c.jid, c.resource) c.jid, c.resource)
self.os_info[i] = {'resource': c.resource, 'client': '', self.os_info[i] = {'resource': c.resource, 'client': '',