Philipp Hörist pushed to branch master at gajim / gajim

Commits:

8 changed files:

Changes:

  • gajim/common/connection.py
    ... ... @@ -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
     
    

  • gajim/common/i18n.py
    ... ... @@ -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
    

  • gajim/common/modules/presence.py
    ... ... @@ -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)
    

  • gajim/common/modules/software_version.py
    ... ... @@ -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):
    

  • gajim/gtk/preferences.py
    ... ... @@ -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)
    

  • gajim/gtk/server_info.py
    ... ... @@ -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)
    

  • gajim/remote_control.py
    ... ... @@ -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(),
    

  • gajim/vcard.py
    ... ... @@ -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': '',