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

Commits:

3 changed files:

Changes:

  • gajim/common/modules/contacts.py
    ... ... @@ -129,7 +129,7 @@ def add_chat_contact(self, jid: Union[str, JID]) -> BareContact:
    129 129
             contact = self._contacts.get(jid)
    
    130 130
             if contact is not None:
    
    131 131
                 if not isinstance(contact, BareContact):
    
    132
    -                raise ValueError(f'Trying to add GroupchatContact {jid}, '
    
    132
    +                raise ValueError(f'Trying to add BareContact {jid}, '
    
    133 133
                                      f'but contact exists already as {contact}')
    
    134 134
                 return contact
    
    135 135
     
    
    ... ... @@ -162,14 +162,14 @@ def add_private_contact(self, jid: Union[str, JID]) -> GroupchatParticipant:
    162 162
                 raise ValueError(f'Trying to add a bare JID as private {jid}')
    
    163 163
     
    
    164 164
             contact = self._contacts.get(jid.bare)
    
    165
    -        if not isinstance(contact, GroupchatContact):
    
    166
    -            raise ValueError(f'Trying to add GroupchatParticipant {jid}, '
    
    167
    -                             f'to BareContact {contact}')
    
    168
    -
    
    169 165
             if contact is None:
    
    170 166
                 group_chat_contact = self.add_group_chat_contact(jid.bare)
    
    171 167
                 return group_chat_contact.add_resource(jid.resource)
    
    172 168
     
    
    169
    +        if not isinstance(contact, GroupchatContact):
    
    170
    +            raise ValueError(f'Trying to add GroupchatParticipant {jid}, '
    
    171
    +                             f'to BareContact {contact}')
    
    172
    +
    
    173 173
             return contact.add_resource(jid.resource)
    
    174 174
     
    
    175 175
         def add_contact(self,
    

  • gajim/common/modules/vcard_avatars.py
    ... ... @@ -16,9 +16,13 @@
    16 16
     
    
    17 17
     from __future__ import annotations
    
    18 18
     
    
    19
    +from typing import Any
    
    20
    +from typing import Callable
    
    19 21
     from typing import Generator
    
    20 22
     from typing import Optional
    
    21 23
     
    
    24
    +import weakref
    
    25
    +
    
    22 26
     from nbxmpp.const import AvatarState
    
    23 27
     from nbxmpp.modules.util import is_error
    
    24 28
     from nbxmpp.modules.vcard_temp import VCard
    
    ... ... @@ -31,8 +35,12 @@
    31 35
     
    
    32 36
     from gajim.common import app
    
    33 37
     from gajim.common import types
    
    38
    +from gajim.common.task_manager import Task
    
    34 39
     from gajim.common.modules.base import BaseModule
    
    35 40
     from gajim.common.modules.util import as_task
    
    41
    +from gajim.common.modules.contacts import GroupchatContact
    
    42
    +from gajim.common.modules.contacts import GroupchatParticipant
    
    43
    +from gajim.common.modules.contacts import BareContact
    
    36 44
     
    
    37 45
     
    
    38 46
     class VCardAvatars(BaseModule):
    
    ... ... @@ -62,13 +70,13 @@ def get_avatar_sha(self, jid: JID) -> Optional[str]:
    62 70
     
    
    63 71
         @as_task
    
    64 72
         def _request_vcard(self,
    
    65
    -                       jid: JID,
    
    66
    -                       expected_sha: str,
    
    67
    -                       type_: str
    
    73
    +                       contact: types.ChatContactT,
    
    74
    +                       expected_sha: str
    
    68 75
                            ) -> Generator[VCard, None, None]:
    
    69 76
             _task = yield  # noqa: F841
    
    70 77
     
    
    71
    -        vcard = yield self._con.get_module('VCardTemp').request_vcard(jid=jid)
    
    78
    +        vcard = yield self._con.get_module('VCardTemp').request_vcard(
    
    79
    +            jid=contact.jid)
    
    72 80
     
    
    73 81
             if is_error(vcard):
    
    74 82
                 self._log.warning(vcard)
    
    ... ... @@ -76,29 +84,27 @@ def _request_vcard(self,
    76 84
     
    
    77 85
             avatar, avatar_sha = vcard.get_avatar()
    
    78 86
             if avatar is None:
    
    79
    -            self._log.info('Avatar missing: %s %s', jid, expected_sha)
    
    87
    +            self._log.info('Avatar missing: %s %s', contact.jid, expected_sha)
    
    80 88
                 return
    
    81 89
     
    
    82 90
             if expected_sha != avatar_sha:
    
    83 91
                 self._log.warning('Avatar mismatch: %s %s != %s',
    
    84
    -                              jid,
    
    92
    +                              contact.jid,
    
    85 93
                                   expected_sha,
    
    86 94
                                   avatar_sha)
    
    87 95
                 return
    
    88 96
     
    
    89
    -        self._log.info('Received: %s %s', jid, avatar_sha)
    
    97
    +        self._log.info('Received: %s %s', contact.jid, avatar_sha)
    
    90 98
             app.interface.save_avatar(avatar)
    
    91 99
     
    
    92
    -        contact = self._con.get_module('Contacts').get_contact(jid)
    
    93
    -
    
    94
    -        if type_ == 'contact':
    
    95
    -            app.storage.cache.set_contact(jid, 'avatar', avatar_sha)
    
    100
    +        if isinstance(contact, BareContact):
    
    101
    +            app.storage.cache.set_contact(contact.jid, 'avatar', avatar_sha)
    
    96 102
     
    
    97
    -        elif type_ == 'muc':
    
    98
    -            app.storage.cache.set_muc(jid, 'avatar', avatar_sha)
    
    103
    +        elif isinstance(contact, GroupchatContact):
    
    104
    +            app.storage.cache.set_muc(contact.jid, 'avatar', avatar_sha)
    
    99 105
     
    
    100
    -        elif type_ == 'muc-user':
    
    101
    -            self._muc_avatar_cache[jid] = avatar_sha
    
    106
    +        else:
    
    107
    +            self._muc_avatar_cache[contact.jid] = avatar_sha
    
    102 108
     
    
    103 109
             contact.update_avatar(avatar_sha)
    
    104 110
     
    
    ... ... @@ -180,10 +186,11 @@ def _process_update(self,
    180 186
     
    
    181 187
                 if avatar_sha not in self._requested_shas:
    
    182 188
                     self._requested_shas.append(avatar_sha)
    
    183
    -                if groupchat:
    
    184
    -                    self._request_vcard(jid, avatar_sha, 'muc')
    
    185
    -                else:
    
    186
    -                    self._request_vcard(jid, avatar_sha, 'contact')
    
    189
    +
    
    190
    +                task = VCardAvatarsTask(contact,
    
    191
    +                                        avatar_sha,
    
    192
    +                                        self._request_vcard)
    
    193
    +                app.task_manager.add_task(task)
    
    187 194
     
    
    188 195
         def _muc_update_received(self, properties: PresenceProperties) -> None:
    
    189 196
             contact = self._con.get_module('Contacts').get_contact(properties.jid,
    
    ... ... @@ -202,9 +209,11 @@ def _muc_update_received(self, properties: PresenceProperties) -> None:
    202 209
                     if properties.avatar_sha not in self._requested_shas:
    
    203 210
                         app.log('avatar').info('Request: %s', nick)
    
    204 211
                         self._requested_shas.append(properties.avatar_sha)
    
    205
    -                    self._request_vcard(properties.jid,
    
    206
    -                                        properties.avatar_sha,
    
    207
    -                                        'muc-user')
    
    212
    +
    
    213
    +                    task = VCardAvatarsTask(contact,
    
    214
    +                                            properties.avatar_sha,
    
    215
    +                                            self._request_vcard)
    
    216
    +                    app.task_manager.add_task(task)
    
    208 217
                     return
    
    209 218
     
    
    210 219
                 current_avatar_sha = self._muc_avatar_cache.get(properties.jid)
    
    ... ... @@ -216,3 +225,48 @@ def _muc_update_received(self, properties: PresenceProperties) -> None:
    216 225
     
    
    217 226
                 else:
    
    218 227
                     self._log.info('Avatar already known: %s', nick)
    
    228
    +
    
    229
    +
    
    230
    +class VCardAvatarsTask(Task):
    
    231
    +    def __init__(self,
    
    232
    +                 contact: Any,
    
    233
    +                 sha: str,
    
    234
    +                 callback: Callable[..., Any]
    
    235
    +                 ) -> None:
    
    236
    +
    
    237
    +        Task.__init__(self)
    
    238
    +        self._contact = contact
    
    239
    +        self._sha = sha
    
    240
    +        self._callback = weakref.WeakMethod(callback)
    
    241
    +
    
    242
    +    def execute(self) -> None:
    
    243
    +        callback = self._callback()
    
    244
    +        if callback is not None:
    
    245
    +            callback(self._contact, self._sha)
    
    246
    +
    
    247
    +    def preconditions_met(self) -> bool:
    
    248
    +        try:
    
    249
    +            client = app.get_client(self._contact.account)
    
    250
    +        except Exception:
    
    251
    +            return False
    
    252
    +
    
    253
    +        if not client.state.is_available:
    
    254
    +            return False
    
    255
    +
    
    256
    +        if isinstance(self._contact, GroupchatContact):
    
    257
    +            if not self._contact.is_joined:
    
    258
    +                self.set_obsolete()
    
    259
    +                return False
    
    260
    +
    
    261
    +        elif isinstance(self._contact, GroupchatParticipant):
    
    262
    +            if not self._contact.room.is_joined:
    
    263
    +                self.set_obsolete()
    
    264
    +                return False
    
    265
    +
    
    266
    +        return True
    
    267
    +
    
    268
    +    def __repr__(self) -> str:
    
    269
    +        return f'VCardAvatars ({self._contact.jid} {self._sha})'
    
    270
    +
    
    271
    +    def __hash__(self) -> int:
    
    272
    +        return hash((self._contact, self._sha))

  • gajim/common/task_manager.py
    ... ... @@ -43,6 +43,8 @@ def _process_queue(self) -> bool:
    43 43
                     continue
    
    44 44
     
    
    45 45
                 if not task.preconditions_met():
    
    46
    +                # precondition_met() can change the obsolete flag, so we need
    
    47
    +                # to check again here
    
    46 48
                     if task.is_obsolete():
    
    47 49
                         log.info('Task obsolete: %r', task)
    
    48 50
                     else: