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

Commits:

5 changed files:

Changes:

  • gajim/common/app.py
    ... ... @@ -702,11 +702,11 @@ def is_finalizer_ref(ref):
    702 702
                 return False
    
    703 703
     
    
    704 704
         def check_finalized():
    
    705
    +        gc.collect()
    
    705 706
             tup = finalizer.peek()
    
    706 707
             if tup is None:
    
    707 708
                 return
    
    708 709
     
    
    709
    -        gc.collect()
    
    710 710
             logger.warning('%s not finalized', name)
    
    711 711
             logger.warning('References:')
    
    712 712
             for ref in gc.get_referrers(tup[0]):
    

  • gajim/common/client.py
    ... ... @@ -439,6 +439,7 @@ def _finish_connect(self):
    439 439
     
    
    440 440
             self.get_module('Bookmarks').request_bookmarks()
    
    441 441
             self.get_module('SoftwareVersion').set_enabled(True)
    
    442
    +        self.get_module('EntityTime').set_enabled(True)
    
    442 443
             self.get_module('LastActivity').set_enabled(True)
    
    443 444
             self.get_module('Annotations').request_annotations()
    
    444 445
             self.get_module('Blocking').get_blocking_list()
    

  • gajim/common/modules/entity_time.py
    ... ... @@ -14,102 +14,31 @@
    14 14
     
    
    15 15
     # XEP-0202: Entity Time
    
    16 16
     
    
    17
    -import time
    
    18
    -
    
    19
    -import nbxmpp
    
    20
    -from nbxmpp.namespaces import Namespace
    
    21
    -from nbxmpp.structs import StanzaHandler
    
    22
    -from nbxmpp.modules.date_and_time import parse_datetime
    
    23
    -from nbxmpp.modules.date_and_time import create_tzinfo
    
    24
    -
    
    25 17
     from gajim.common import app
    
    26
    -from gajim.common.nec import NetworkEvent
    
    27 18
     from gajim.common.modules.base import BaseModule
    
    28 19
     
    
    29 20
     
    
    30 21
     class EntityTime(BaseModule):
    
    22
    +
    
    23
    +    _nbxmpp_extends = 'EntityTime'
    
    24
    +    _nbxmpp_methods = [
    
    25
    +        'request_entity_time',
    
    26
    +        'enable',
    
    27
    +        'disable',
    
    28
    +    ]
    
    29
    +
    
    31 30
         def __init__(self, con):
    
    32 31
             BaseModule.__init__(self, con)
    
    33 32
     
    
    34
    -        self.handlers = [
    
    35
    -            StanzaHandler(name='iq',
    
    36
    -                          callback=self._answer_request,
    
    37
    -                          typ='get',
    
    38
    -                          ns=Namespace.TIME_REVISED),
    
    39
    -        ]
    
    33
    +        self.handlers = []
    
    40 34
     
    
    41
    -    def request_entity_time(self, jid, resource):
    
    42
    -        if not app.account_is_available(self._account):
    
    35
    +    def set_enabled(self, enabled):
    
    36
    +        if not enabled:
    
    37
    +            self._nbxmpp('EntityTime').disable()
    
    43 38
                 return
    
    44 39
     
    
    45
    -        if resource:
    
    46
    -            jid += '/' + resource
    
    47
    -        iq = nbxmpp.Iq(to=jid, typ='get')
    
    48
    -        iq.addChild('time', namespace=Namespace.TIME_REVISED)
    
    49
    -
    
    50
    -        self._log.info('Requested: %s', jid)
    
    51
    -
    
    52
    -        self._con.connection.SendAndCallForResponse(iq, self._result_received)
    
    53
    -
    
    54
    -    def _result_received(self, _nbxmpp_client, stanza):
    
    55
    -        time_info = None
    
    56
    -        if not nbxmpp.isResultNode(stanza):
    
    57
    -            self._log.info('Error: %s', stanza.getError())
    
    58
    -        else:
    
    59
    -            time_info = self._extract_info(stanza)
    
    60
    -
    
    61
    -        self._log.info('Received: %s %s', stanza.getFrom(), time_info)
    
    62
    -
    
    63
    -        app.nec.push_incoming_event(NetworkEvent('time-result-received',
    
    64
    -                                                 conn=self._con,
    
    65
    -                                                 jid=stanza.getFrom(),
    
    66
    -                                                 time_info=time_info))
    
    67
    -
    
    68
    -    def _extract_info(self, stanza):
    
    69
    -        time_ = stanza.getTag('time')
    
    70
    -        if not time_:
    
    71
    -            self._log.warning('No time node: %s', stanza)
    
    72
    -            return None
    
    73
    -
    
    74
    -        tzo = time_.getTag('tzo').getData()
    
    75
    -        if not tzo:
    
    76
    -            self._log.warning('Wrong tzo node: %s', stanza)
    
    77
    -            return None
    
    78
    -
    
    79
    -        remote_tz = create_tzinfo(tz_string=tzo)
    
    80
    -        if remote_tz is None:
    
    81
    -            self._log.warning('Wrong tzo node: %s', stanza)
    
    82
    -            return None
    
    83
    -
    
    84
    -        utc_time = time_.getTag('utc').getData()
    
    85
    -        date_time = parse_datetime(utc_time, check_utc=True)
    
    86
    -        if date_time is None:
    
    87
    -            self._log.warning('Wrong timezone definition: %s %s',
    
    88
    -                              utc_time, stanza.getFrom())
    
    89
    -            return None
    
    90
    -
    
    91
    -        date_time = date_time.astimezone(remote_tz)
    
    92
    -        return date_time.strftime('%c %Z')
    
    93
    -
    
    94
    -    def _answer_request(self, _con, stanza, _properties):
    
    95
    -        self._log.info('%s asked for the time', stanza.getFrom())
    
    96 40
             if app.settings.get_account_setting(self._account, 'send_time_info'):
    
    97
    -            iq = stanza.buildReply('result')
    
    98
    -            time_ = iq.setTag('time', namespace=Namespace.TIME_REVISED)
    
    99
    -            formated_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
    
    100
    -            time_.setTagData('utc', formated_time)
    
    101
    -            isdst = time.localtime().tm_isdst
    
    102
    -            zone = -(time.timezone, time.altzone)[isdst] / 60.0
    
    103
    -            tzo = (zone / 60, abs(zone % 60))
    
    104
    -            time_.setTagData('tzo', '%+03d:%02d' % (tzo))
    
    105
    -            self._log.info('Answer: %s %s', formated_time, '%+03d:%02d' % (tzo))
    
    106
    -        else:
    
    107
    -            iq = stanza.buildReply('error')
    
    108
    -            err = nbxmpp.ErrorNode(nbxmpp.ERR_SERVICE_UNAVAILABLE)
    
    109
    -            iq.addChild(node=err)
    
    110
    -            self._log.info('Send service-unavailable')
    
    111
    -        self._con.connection.send(iq)
    
    112
    -        raise nbxmpp.NodeProcessed
    
    41
    +            self._nbxmpp('EntityTime').enable()
    
    113 42
     
    
    114 43
     
    
    115 44
     def get_instance(*args, **kwargs):
    

  • gajim/data/gui/contact_info.ui
    ... ... @@ -490,16 +490,13 @@
    490 490
                                     <property name="model">groups_model</property>
    
    491 491
                                     <property name="headers-visible">False</property>
    
    492 492
                                     <child internal-child="selection">
    
    493
    -                                  <object class="GtkTreeSelection">
    
    494
    -                                    <signal name="changed" handler="_on_group_selection_changed" swapped="no"/>
    
    495
    -                                  </object>
    
    493
    +                                  <object class="GtkTreeSelection" id="tree_selection"/>
    
    496 494
                                     </child>
    
    497 495
                                     <child>
    
    498 496
                                       <object class="GtkTreeViewColumn">
    
    499 497
                                         <child>
    
    500
    -                                      <object class="GtkCellRendererToggle">
    
    498
    +                                      <object class="GtkCellRendererToggle" id="toggle_renderer">
    
    501 499
                                             <property name="xpad">12</property>
    
    502
    -                                        <signal name="toggled" handler="_on_group_toggled" swapped="no"/>
    
    503 500
                                           </object>
    
    504 501
                                           <attributes>
    
    505 502
                                             <attribute name="active">0</attribute>
    
    ... ... @@ -512,10 +509,9 @@
    512 509
                                         <property name="title" translatable="yes">column</property>
    
    513 510
                                         <property name="sort-column-id">1</property>
    
    514 511
                                         <child>
    
    515
    -                                      <object class="GtkCellRendererText">
    
    512
    +                                      <object class="GtkCellRendererText" id="text_renderer">
    
    516 513
                                             <property name="height">42</property>
    
    517 514
                                             <property name="editable">True</property>
    
    518
    -                                        <signal name="edited" handler="_on_group_name_edited" swapped="no"/>
    
    519 515
                                           </object>
    
    520 516
                                           <attributes>
    
    521 517
                                             <attribute name="text">1</attribute>
    

  • gajim/gtk/contact_info.py
    ... ... @@ -38,6 +38,7 @@
    38 38
     from .dialogs import DialogButton
    
    39 39
     from .sidebar_switcher import SideBarSwitcher
    
    40 40
     from .util import get_builder
    
    41
    +from .util import connect_destroy
    
    41 42
     from .vcard_grid import VCardGrid
    
    42 43
     
    
    43 44
     log = logging.getLogger('gajim.gui.contact_info')
    
    ... ... @@ -92,14 +93,17 @@ def __init__(self, account, contact, page=None, anonymous=False):
    92 93
                 self._fill_settings_page()
    
    93 94
                 self._fill_groups_page()
    
    94 95
     
    
    96
    +        self._tasks = []
    
    97
    +
    
    95 98
             # pylint: disable=line-too-long
    
    96 99
             self.register_events([
    
    97
    -            ('time-result-received', ged.GUI1, self._set_entity_time),
    
    98 100
                 ('subscribed-presence-received', ged.GUI1, self._on_subscribed_presence_received),
    
    99 101
                 ('unsubscribed-presence-received', ged.GUI1, self._on_unsubscribed_presence_received),
    
    100 102
             ])
    
    101 103
             # pylint: enable=line-too-long
    
    102 104
     
    
    105
    +        self._load_avatar()
    
    106
    +
    
    103 107
             self._ui.contact_name_label.set_text(contact.name)
    
    104 108
             if contact.is_pm_contact:
    
    105 109
                 self._ui.role_label.set_text(get_uf_role(contact.role))
    
    ... ... @@ -131,6 +135,16 @@ def __init__(self, account, contact, page=None, anonymous=False):
    131 135
             self.connect('key-press-event', self._on_key_press)
    
    132 136
             self.connect('destroy', self._on_destroy)
    
    133 137
     
    
    138
    +        connect_destroy(self._ui.tree_selection,
    
    139
    +                        'changed',
    
    140
    +                        self._on_group_selection_changed)
    
    141
    +        connect_destroy(self._ui.toggle_renderer,
    
    142
    +                        'toggled',
    
    143
    +                        self._on_group_toggled)
    
    144
    +        connect_destroy(self._ui.text_renderer,
    
    145
    +                        'edited',
    
    146
    +                        self._on_group_name_edited)
    
    147
    +
    
    134 148
             self.add(self._ui.main_grid)
    
    135 149
             self.show_all()
    
    136 150
     
    
    ... ... @@ -145,6 +159,10 @@ def _on_stack_child_changed(self, *args):
    145 159
                 self._ui.header_revealer.set_reveal_child(True)
    
    146 160
     
    
    147 161
         def _on_destroy(self, _widget):
    
    162
    +        for task in self._tasks:
    
    163
    +            task.cancel()
    
    164
    +        self._tasks.clear()
    
    165
    +
    
    148 166
             if not self.contact.is_pm_contact:
    
    149 167
                 self._save_annotation()
    
    150 168
     
    
    ... ... @@ -152,7 +170,7 @@ def _on_destroy(self, _widget):
    152 170
                 GLib.source_remove(self._update_timeout_id)
    
    153 171
     
    
    154 172
             self.unregister_events()
    
    155
    -        app.cancel_tasks(self)
    
    173
    +        app.check_finalize(self)
    
    156 174
     
    
    157 175
         def _save_annotation(self):
    
    158 176
             buffer_ = self._ui.textview_annotation.get_buffer()
    
    ... ... @@ -183,7 +201,6 @@ def _on_vcard_received(self, task):
    183 201
                 vcard = VCard()
    
    184 202
     
    
    185 203
             self._vcard_grid.set_vcard(vcard)
    
    186
    -        self._load_avatar()
    
    187 204
     
    
    188 205
         def _load_avatar(self):
    
    189 206
             scale = self.get_scale_factor()
    
    ... ... @@ -210,16 +227,21 @@ def _query_device(self, contact):
    210 227
             }
    
    211 228
             self._rebuild_devices_grid()
    
    212 229
     
    
    213
    -        self._client.get_module('SoftwareVersion').request_software_version(
    
    230
    +        task = self._client.get_module('SoftwareVersion').request_software_version(
    
    214 231
                 contact.jid, callback=self._set_os_info, user_data=contact)
    
    215
    -        self._client.get_module('EntityTime').request_entity_time(
    
    216
    -            str(contact.jid.bare), contact.jid.resource)
    
    232
    +        self._tasks.append(task)
    
    233
    +
    
    234
    +        task = self._client.get_module('EntityTime').request_entity_time(
    
    235
    +            contact.jid, callback=self._set_entity_time, user_data=contact)
    
    236
    +        self._tasks.append(task)
    
    217 237
     
    
    218 238
         def _set_os_info(self, task):
    
    239
    +        self._tasks.remove(task)
    
    240
    +
    
    219 241
             try:
    
    220 242
                 result = task.finish()
    
    221
    -        except StanzaError as err:
    
    222
    -            log.info('Could not retrieve software version: %s', err)
    
    243
    +        except Exception as err:
    
    244
    +            log.warning('Could not retrieve software version: %s', err)
    
    223 245
                 return
    
    224 246
     
    
    225 247
             contact = task.get_user_data()
    
    ... ... @@ -230,19 +252,19 @@ def _set_os_info(self, task):
    230 252
             self._received_devices.add(contact.jid.resource)
    
    231 253
             self._rebuild_devices_grid()
    
    232 254
     
    
    233
    -    def _set_entity_time(self, event):
    
    234
    -        if event.conn.name != self.account:
    
    255
    +    def _set_entity_time(self, task):
    
    256
    +        self._tasks.remove(task)
    
    257
    +
    
    258
    +        try:
    
    259
    +            entity_time = task.finish()
    
    260
    +        except Exception as err:
    
    261
    +            log.warning('Could not retrieve entity time: %s', err)
    
    235 262
                 return
    
    236 263
     
    
    237
    -        if self.contact.is_pm_contact:
    
    238
    -            if event.jid != self.contact.jid:
    
    239
    -                return
    
    240
    -        else:
    
    241
    -            if event.jid.bare != self.contact.jid:
    
    242
    -                return
    
    264
    +        contact = task.get_user_data()
    
    243 265
     
    
    244
    -        self._devices[event.jid.resource]['time'] = event.time_info
    
    245
    -        self._received_times.add(event.jid.resource)
    
    266
    +        self._devices[contact.jid.resource]['time'] = entity_time
    
    267
    +        self._received_times.add(contact.jid.resource)
    
    246 268
             self._rebuild_devices_grid()
    
    247 269
     
    
    248 270
         def _rebuild_devices_grid(self):