Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
06782727
by Philipp Hörist at 2019-04-05T17:40:14Z
-
471d9ca0
by Philipp Hörist at 2019-04-05T17:43:01Z
-
239ab145
by Philipp Hörist at 2019-04-05T17:44:30Z
8 changed files:
- gajim/common/connection.py
- gajim/common/i18n.py
- gajim/common/modules/presence.py
- gajim/common/modules/software_version.py
- gajim/gtk/preferences.py
- gajim/gtk/server_info.py
- gajim/remote_control.py
- gajim/vcard.py
Changes:
| ... | ... | @@ -1486,6 +1486,9 @@ class Connection(CommonConnection, ConnectionHandlers): |
| 1486 | 1486 |
# Get bookmarks
|
| 1487 | 1487 |
self.get_module('Bookmarks').request_bookmarks()
|
| 1488 | 1488 |
|
| 1489 |
+ # Enable Software Version
|
|
| 1490 |
+ self.get_module('SoftwareVersion').set_enabled(True)
|
|
| 1491 |
+ |
|
| 1489 | 1492 |
# Get annotations
|
| 1490 | 1493 |
self.get_module('Annotations').request_annotations()
|
| 1491 | 1494 |
|
| ... | ... | @@ -170,7 +170,9 @@ try: |
| 170 | 170 |
if os.name == 'nt':
|
| 171 | 171 |
# Set the env var on Windows because gettext.find() uses it to
|
| 172 | 172 |
# find the translation
|
| 173 |
- os.environ['LANG'] = LANG
|
|
| 173 |
+ # Use LANGUAGE instead of LANG, LANG sets LC_ALL and thus
|
|
| 174 |
+ # doesn't retain other region settings like LC_TIME
|
|
| 175 |
+ os.environ['LANGUAGE'] = LANG
|
|
| 174 | 176 |
except Exception as error:
|
| 175 | 177 |
print('Failed to determine default language', file=sys.stderr)
|
| 176 | 178 |
import traceback
|
| ... | ... | @@ -356,6 +356,10 @@ class Presence(BaseModule): |
| 356 | 356 |
def get_presence(self, to=None, typ=None, priority=None,
|
| 357 | 357 |
show=None, status=None, nick=None, caps=True,
|
| 358 | 358 |
sign=None, idle_time=None):
|
| 359 |
+ if show not in ('chat', 'away', 'xa', 'dnd'):
|
|
| 360 |
+ # Gajim sometimes passes invalid show values here
|
|
| 361 |
+ # until this is fixed this is a workaround
|
|
| 362 |
+ show = None
|
|
| 359 | 363 |
presence = nbxmpp.Presence(to, typ, priority, show, status)
|
| 360 | 364 |
if nick is not None:
|
| 361 | 365 |
nick_tag = presence.setTag('nick', namespace=nbxmpp.NS_NICK)
|
| ... | ... | @@ -6,101 +6,39 @@ |
| 6 | 6 |
#
|
| 7 | 7 |
# Gajim is distributed in the hope that it will be useful,
|
| 8 | 8 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 9 |
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| 9 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
| 10 | 10 |
# GNU General Public License for more details.
|
| 11 | 11 |
#
|
| 12 | 12 |
# You should have received a copy of the GNU General Public License
|
| 13 |
-# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
| 13 |
+# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
| 14 | 14 |
|
| 15 | 15 |
# XEP-0092: Software Version
|
| 16 | 16 |
|
| 17 |
-import nbxmpp
|
|
| 18 |
-from nbxmpp.structs import StanzaHandler
|
|
| 19 |
- |
|
| 20 | 17 |
from gajim.common import app
|
| 21 | 18 |
from gajim.common.helpers import get_os_info
|
| 22 |
-from gajim.common.nec import NetworkIncomingEvent
|
|
| 23 | 19 |
from gajim.common.modules.base import BaseModule
|
| 24 | 20 |
|
| 25 | 21 |
|
| 26 | 22 |
class SoftwareVersion(BaseModule):
|
| 27 |
- def __init__(self, con):
|
|
| 28 |
- BaseModule.__init__(self, con)
|
|
| 29 |
- |
|
| 30 |
- self.handlers = [
|
|
| 31 |
- StanzaHandler(name='iq',
|
|
| 32 |
- callback=self._answer_request,
|
|
| 33 |
- typ='get',
|
|
| 34 |
- ns=nbxmpp.NS_VERSION),
|
|
| 35 |
- ]
|
|
| 36 | 23 |
|
| 37 |
- def request_os_info(self, jid, resource):
|
|
| 38 |
- if not app.account_is_connected(self._account):
|
|
| 39 |
- return
|
|
| 40 |
- # If we are invisible, do not request
|
|
| 41 |
- if self._con.connected == app.SHOW_LIST.index('invisible'):
|
|
| 42 |
- return
|
|
| 24 |
+ _nbxmpp_extends = 'SoftwareVersion'
|
|
| 25 |
+ _nbxmpp_methods = [
|
|
| 26 |
+ 'set_software_version',
|
|
| 27 |
+ 'request_software_version',
|
|
| 28 |
+ 'disable',
|
|
| 29 |
+ ]
|
|
| 43 | 30 |
|
| 44 |
- if resource:
|
|
| 45 |
- jid += '/' + resource
|
|
| 46 |
- iq = nbxmpp.Iq(to=jid, typ='get', queryNS=nbxmpp.NS_VERSION)
|
|
| 47 |
- |
|
| 48 |
- self._log.info('Requested: %s', jid)
|
|
| 49 |
- |
|
| 50 |
- self._con.connection.SendAndCallForResponse(iq, self._result_received)
|
|
| 51 |
- |
|
| 52 |
- def _result_received(self, stanza):
|
|
| 53 |
- client_info, os_info = None, None
|
|
| 54 |
- if not nbxmpp.isResultNode(stanza):
|
|
| 55 |
- self._log.info('Error: %s', stanza.getError())
|
|
| 56 |
- else:
|
|
| 57 |
- try:
|
|
| 58 |
- client_info, os_info = self._extract_info(stanza)
|
|
| 59 |
- except Exception:
|
|
| 60 |
- self._log.exception('Error')
|
|
| 61 |
- self._log.error(stanza)
|
|
| 62 |
- |
|
| 63 |
- self._log.info('Received: %s %s %s',
|
|
| 64 |
- stanza.getFrom(), client_info, os_info)
|
|
| 65 |
- |
|
| 66 |
- app.nec.push_incoming_event(
|
|
| 67 |
- VersionResultReceivedEvent(None, conn=self._con,
|
|
| 68 |
- jid=stanza.getFrom(),
|
|
| 69 |
- client_info=client_info,
|
|
| 70 |
- os_info=os_info))
|
|
| 71 |
- |
|
| 72 |
- @staticmethod
|
|
| 73 |
- def _extract_info(stanza):
|
|
| 74 |
- query = stanza.getTag('query')
|
|
| 75 |
- name = query.getTag('name').getData()
|
|
| 76 |
- version = query.getTag('version').getData()
|
|
| 77 |
- client_info = '%s %s' % (name, version)
|
|
| 78 |
- os_info = query.getTag('os')
|
|
| 79 |
- if os_info is not None:
|
|
| 80 |
- os_info = os_info.getData()
|
|
| 81 |
- return client_info, os_info
|
|
| 31 |
+ def __init__(self, con):
|
|
| 32 |
+ BaseModule.__init__(self, con)
|
|
| 82 | 33 |
|
| 83 |
- def _answer_request(self, _con, stanza, _properties):
|
|
| 84 |
- self._log.info('%s asked for the software version', stanza.getFrom())
|
|
| 85 |
- if app.config.get_per('accounts', self._account, 'send_os_info'):
|
|
| 86 |
- os_info = get_os_info()
|
|
| 87 |
- iq = stanza.buildReply('result')
|
|
| 88 |
- query = iq.getQuery()
|
|
| 89 |
- query.setTagData('name', 'Gajim')
|
|
| 90 |
- query.setTagData('version', app.version)
|
|
| 91 |
- query.setTagData('os', os_info)
|
|
| 92 |
- self._log.info('Answer: Gajim %s %s', app.version, os_info)
|
|
| 34 |
+ def set_enabled(self, enabled):
|
|
| 35 |
+ if enabled:
|
|
| 36 |
+ if not app.config.get_per('accounts', self._account, 'send_os_info'):
|
|
| 37 |
+ return
|
|
| 38 |
+ self._nbxmpp('SoftwareVersion').set_software_version(
|
|
| 39 |
+ 'Gajim', app.version, get_os_info())
|
|
| 93 | 40 |
else:
|
| 94 |
- iq = stanza.buildReply('error')
|
|
| 95 |
- err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
|
|
| 96 |
- iq.addChild(node=err)
|
|
| 97 |
- self._log.info('Send service-unavailable')
|
|
| 98 |
- self._con.connection.send(iq)
|
|
| 99 |
- raise nbxmpp.NodeProcessed
|
|
| 100 |
- |
|
| 101 |
- |
|
| 102 |
-class VersionResultReceivedEvent(NetworkIncomingEvent):
|
|
| 103 |
- name = 'version-result-received'
|
|
| 41 |
+ self._nbxmpp('SoftwareVersion').disable()
|
|
| 104 | 42 |
|
| 105 | 43 |
|
| 106 | 44 |
def get_instance(*args, **kwargs):
|
| ... | ... | @@ -879,6 +879,8 @@ class Preferences(Gtk.ApplicationWindow): |
| 879 | 879 |
def on_send_os_info_checkbutton_toggled(self, widget):
|
| 880 | 880 |
widget.set_inconsistent(False)
|
| 881 | 881 |
self.on_per_account_checkbutton_toggled(widget, 'send_os_info')
|
| 882 |
+ for con in app.connections.values():
|
|
| 883 |
+ con.get_module('SoftwareVersion').set_enabled(widget.get_active())
|
|
| 882 | 884 |
|
| 883 | 885 |
def on_ignore_events_from_unknown_contacts_checkbutton_toggled(self, widget):
|
| 884 | 886 |
widget.set_inconsistent(False)
|
| ... | ... | @@ -17,6 +17,7 @@ from collections import namedtuple |
| 17 | 17 |
from datetime import timedelta
|
| 18 | 18 |
|
| 19 | 19 |
import nbxmpp
|
| 20 |
+from nbxmpp.util import is_error_result
|
|
| 20 | 21 |
from gi.repository import Gtk
|
| 21 | 22 |
from gi.repository import Gdk
|
| 22 | 23 |
|
| ... | ... | @@ -24,6 +25,8 @@ from gajim.common import app |
| 24 | 25 |
from gajim.common import ged
|
| 25 | 26 |
from gajim.common.i18n import _
|
| 26 | 27 |
|
| 28 |
+from gajim.gtk.util import ensure_not_destroyed
|
|
| 29 |
+ |
|
| 27 | 30 |
log = logging.getLogger('gajim.gtk.serverinfo')
|
| 28 | 31 |
|
| 29 | 32 |
|
| ... | ... | @@ -34,6 +37,7 @@ class ServerInfoDialog(Gtk.Dialog): |
| 34 | 37 |
destroy_with_parent=True)
|
| 35 | 38 |
|
| 36 | 39 |
self.account = account
|
| 40 |
+ self._destroyed = False
|
|
| 37 | 41 |
self.set_transient_for(app.interface.roster.window)
|
| 38 | 42 |
self.set_resizable(False)
|
| 39 | 43 |
|
| ... | ... | @@ -69,10 +73,6 @@ class ServerInfoDialog(Gtk.Dialog): |
| 69 | 73 |
self.connect('response', self.on_response)
|
| 70 | 74 |
self.connect('destroy', self.on_destroy)
|
| 71 | 75 |
|
| 72 |
- app.ged.register_event_handler('version-result-received',
|
|
| 73 |
- ged.CORE,
|
|
| 74 |
- self._nec_version_result_received)
|
|
| 75 |
- |
|
| 76 | 76 |
app.ged.register_event_handler('server-disco-received',
|
| 77 | 77 |
ged.GUI1,
|
| 78 | 78 |
self._server_disco_received)
|
| ... | ... | @@ -81,7 +81,8 @@ class ServerInfoDialog(Gtk.Dialog): |
| 81 | 81 |
self.uptime = ''
|
| 82 | 82 |
self.hostname = app.get_hostname_from_account(account)
|
| 83 | 83 |
con = app.connections[account]
|
| 84 |
- con.get_module('SoftwareVersion').request_os_info(self.hostname, None)
|
|
| 84 |
+ con.get_module('SoftwareVersion').request_software_version(
|
|
| 85 |
+ self.hostname, callback=self._software_version_received)
|
|
| 85 | 86 |
self.request_last_activity()
|
| 86 | 87 |
|
| 87 | 88 |
for feature in self.get_features():
|
| ... | ... | @@ -138,10 +139,12 @@ class ServerInfoDialog(Gtk.Dialog): |
| 138 | 139 |
'days': delta.days, 'hours': hours}
|
| 139 | 140 |
self.update(self.get_infos, self.info_listbox)
|
| 140 | 141 |
|
| 141 |
- def _nec_version_result_received(self, obj):
|
|
| 142 |
- if obj.jid != self.hostname:
|
|
| 143 |
- return
|
|
| 144 |
- self.version = obj.client_info or _('Unknown')
|
|
| 142 |
+ @ensure_not_destroyed
|
|
| 143 |
+ def _software_version_received(self, result):
|
|
| 144 |
+ if is_error_result(result):
|
|
| 145 |
+ self.version = _('Unknown')
|
|
| 146 |
+ else:
|
|
| 147 |
+ self.version = '%s %s' % (result.name, result.version)
|
|
| 145 | 148 |
self.update(self.get_infos, self.info_listbox)
|
| 146 | 149 |
|
| 147 | 150 |
def _server_disco_received(self, obj):
|
| ... | ... | @@ -229,11 +232,8 @@ class ServerInfoDialog(Gtk.Dialog): |
| 229 | 232 |
self.destroy()
|
| 230 | 233 |
|
| 231 | 234 |
def on_destroy(self, *args):
|
| 235 |
+ self._destroyed = True
|
|
| 232 | 236 |
del app.interface.instances[self.account]['server_info']
|
| 233 |
- app.ged.remove_event_handler('version-result-received',
|
|
| 234 |
- ged.CORE,
|
|
| 235 |
- self._nec_version_result_received)
|
|
| 236 |
- |
|
| 237 | 237 |
app.ged.remove_event_handler('server-disco-received',
|
| 238 | 238 |
ged.GUI1,
|
| 239 | 239 |
self._server_disco_received)
|
| ... | ... | @@ -267,9 +267,6 @@ class GajimRemote(Server): |
| 267 | 267 |
<signal name='NewMessage'>
|
| 268 | 268 |
<arg type='av' />
|
| 269 | 269 |
</signal>
|
| 270 |
- <signal name='OsInfo'>
|
|
| 271 |
- <arg type='av' />
|
|
| 272 |
- </signal>
|
|
| 273 | 270 |
<signal name='Roster'>
|
| 274 | 271 |
<arg type='av' />
|
| 275 | 272 |
</signal>
|
| ... | ... | @@ -299,8 +296,6 @@ class GajimRemote(Server): |
| 299 | 296 |
super().__init__(self.con, '/org/gajim/dbus/RemoteObject')
|
| 300 | 297 |
self.first_show = True
|
| 301 | 298 |
|
| 302 |
- app.ged.register_event_handler('version-result-received', ged.POSTGUI,
|
|
| 303 |
- self.on_os_info)
|
|
| 304 | 299 |
app.ged.register_event_handler('time-result-received', ged.POSTGUI,
|
| 305 | 300 |
self.on_time)
|
| 306 | 301 |
app.ged.register_event_handler('roster-info', ged.POSTGUI,
|
| ... | ... | @@ -346,12 +341,6 @@ class GajimRemote(Server): |
| 346 | 341 |
self.raise_signal('MessageSent', (obj.conn.name, [
|
| 347 | 342 |
obj.jid, obj.message, obj.keyID, chatstate]))
|
| 348 | 343 |
|
| 349 |
- def on_os_info(self, obj):
|
|
| 350 |
- self.raise_signal('OsInfo', (obj.conn.name, [obj.jid.getStripped(),
|
|
| 351 |
- obj.jid.getResource(),
|
|
| 352 |
- obj.client_info,
|
|
| 353 |
- obj.os_info]))
|
|
| 354 |
- |
|
| 355 | 344 |
def on_time(self, obj):
|
| 356 | 345 |
self.raise_signal('EntityTime', (obj.conn.name, [obj.jid.getStripped(),
|
| 357 | 346 |
obj.jid.getResource(),
|
| ... | ... | @@ -33,6 +33,8 @@ from gi.repository import Gtk |
| 33 | 33 |
from gi.repository import GLib
|
| 34 | 34 |
from gi.repository import Gdk
|
| 35 | 35 |
from nbxmpp.structs import AnnotationNote
|
| 36 |
+from nbxmpp.util import is_error_result
|
|
| 37 |
+from nbxmpp.protocol import JID
|
|
| 36 | 38 |
|
| 37 | 39 |
from gajim import gtkgui_helpers
|
| 38 | 40 |
from gajim.gui_menu_builder import show_save_as_menu
|
| ... | ... | @@ -102,8 +104,6 @@ class VcardWindow: |
| 102 | 104 |
self.update_progressbar_timeout_id = GLib.timeout_add(self.update_intervall,
|
| 103 | 105 |
self.update_progressbar)
|
| 104 | 106 |
|
| 105 |
- app.ged.register_event_handler('version-result-received', ged.GUI1,
|
|
| 106 |
- self.set_os_info)
|
|
| 107 | 107 |
app.ged.register_event_handler('time-result-received', ged.GUI1,
|
| 108 | 108 |
self.set_entity_time)
|
| 109 | 109 |
|
| ... | ... | @@ -148,8 +148,6 @@ class VcardWindow: |
| 148 | 148 |
if note is None or new_annotation != note.data:
|
| 149 | 149 |
new_note = AnnotationNote(jid=self.contact.jid, data=new_annotation)
|
| 150 | 150 |
con.get_module('Annotations').set_note(new_note)
|
| 151 |
- app.ged.remove_event_handler('version-result-received', ged.GUI1,
|
|
| 152 |
- self.set_os_info)
|
|
| 153 | 151 |
app.ged.remove_event_handler('time-result-received', ged.GUI1,
|
| 154 | 152 |
self.set_entity_time)
|
| 155 | 153 |
|
| ... | ... | @@ -263,34 +261,27 @@ class VcardWindow: |
| 263 | 261 |
self.clear_values()
|
| 264 | 262 |
self._set_values(vcard, jid)
|
| 265 | 263 |
|
| 266 |
- def set_os_info(self, obj):
|
|
| 267 |
- if obj.conn.name != self.account:
|
|
| 268 |
- return
|
|
| 264 |
+ def set_os_info(self, result, jid):
|
|
| 269 | 265 |
if self.xml.get_object('information_notebook').get_n_pages() < 5:
|
| 270 | 266 |
return
|
| 271 |
- if self.gc_contact:
|
|
| 272 |
- if obj.jid != self.contact.jid:
|
|
| 273 |
- return
|
|
| 274 |
- elif obj.jid.getStripped() != self.contact.jid:
|
|
| 275 |
- return
|
|
| 267 |
+ |
|
| 268 |
+ error = is_error_result(result)
|
|
| 276 | 269 |
i = 0
|
| 277 | 270 |
client = ''
|
| 278 | 271 |
os_info = ''
|
| 279 | 272 |
while i in self.os_info:
|
| 280 |
- if self.os_info[i]['resource'] == obj.jid.getResource():
|
|
| 281 |
- if obj.client_info:
|
|
| 282 |
- self.os_info[i]['client'] = obj.client_info
|
|
| 273 |
+ if self.os_info[i]['resource'] == JID(jid).getResource():
|
|
| 274 |
+ if not error:
|
|
| 275 |
+ self.os_info[i]['client'] = '%s %s' % (result.name,
|
|
| 276 |
+ result.version)
|
|
| 283 | 277 |
else:
|
| 284 | 278 |
self.os_info[i]['client'] = Q_('?Client:Unknown')
|
| 285 |
- if obj.os_info:
|
|
| 286 |
- self.os_info[i]['os'] = obj.os_info
|
|
| 279 |
+ |
|
| 280 |
+ if not error and result.os is not None:
|
|
| 281 |
+ self.os_info[i]['os'] = result.os
|
|
| 287 | 282 |
else:
|
| 288 | 283 |
self.os_info[i]['os'] = Q_('?OS:Unknown')
|
| 289 |
- else:
|
|
| 290 |
- if not self.os_info[i]['client']:
|
|
| 291 |
- self.os_info[i]['client'] = Q_('?Client:Unknown')
|
|
| 292 |
- if not self.os_info[i]['os']:
|
|
| 293 |
- self.os_info[i]['os'] = Q_('?OS:Unknown')
|
|
| 284 |
+ |
|
| 294 | 285 |
if i > 0:
|
| 295 | 286 |
client += '\n'
|
| 296 | 287 |
os_info += '\n'
|
| ... | ... | @@ -417,12 +408,16 @@ class VcardWindow: |
| 417 | 408 |
self.os_info_arrived = True
|
| 418 | 409 |
else: # Request os info if contact is connected
|
| 419 | 410 |
if self.gc_contact:
|
| 420 |
- j, r = app.get_room_and_nick_from_fjid(self.real_jid)
|
|
| 421 |
- GLib.idle_add(con.get_module('SoftwareVersion').request_os_info,
|
|
| 422 |
- j, r)
|
|
| 411 |
+ con.get_module('SoftwareVersion').request_software_version(
|
|
| 412 |
+ self.real_jid,
|
|
| 413 |
+ callback=self.set_os_info,
|
|
| 414 |
+ user_data=self.real_jid)
|
|
| 423 | 415 |
else:
|
| 424 |
- GLib.idle_add(con.get_module('SoftwareVersion').request_os_info,
|
|
| 425 |
- self.contact.jid, self.contact.resource)
|
|
| 416 |
+ jid = self.contact.get_full_jid()
|
|
| 417 |
+ con.get_module('SoftwareVersion').request_software_version(
|
|
| 418 |
+ jid,
|
|
| 419 |
+ callback=self.set_os_info,
|
|
| 420 |
+ user_data=jid)
|
|
| 426 | 421 |
|
| 427 | 422 |
# do not wait for entity_time if contact is not connected or has error
|
| 428 | 423 |
# additional check for observer is needed, as show is offline for him
|
| ... | ... | @@ -451,8 +446,9 @@ class VcardWindow: |
| 451 | 446 |
uf_resources += '\n' + c.resource + \
|
| 452 | 447 |
_(' resource with priority ') + str(c.priority)
|
| 453 | 448 |
if c.show not in ('offline', 'error'):
|
| 454 |
- GLib.idle_add(con.get_module('SoftwareVersion').request_os_info,
|
|
| 455 |
- c.jid, c.resource)
|
|
| 449 |
+ jid = c.get_full_jid()
|
|
| 450 |
+ con.get_module('SoftwareVersion').request_software_version(
|
|
| 451 |
+ jid, callback=self.set_os_info, user_data=jid)
|
|
| 456 | 452 |
GLib.idle_add(con.get_module('EntityTime').request_entity_time,
|
| 457 | 453 |
c.jid, c.resource)
|
| 458 | 454 |
self.os_info[i] = {'resource': c.resource, 'client': '',
|