Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
8392372a
by Philipp Hörist at 2023-05-23T00:34:23+02:00
6 changed files:
- gajim/common/modules/contacts.py
- gajim/common/modules/discovery.py
- gajim/common/modules/user_nickname.py
- gajim/common/modules/vcard_avatars.py
- gajim/common/storage/cache.py
- gajim/gtk/avatar.py
Changes:
| ... | ... | @@ -360,7 +360,8 @@ def __init__(self, logger: LogAdapter, jid: JID, account: str) -> None: |
| 360 | 360 | self.settings = ContactSettings(account, jid)
|
| 361 | 361 | self._resources: dict[str, ResourceContact] = {}
|
| 362 | 362 | |
| 363 | - self._avatar_sha = app.storage.cache.get_contact(jid, 'avatar')
|
|
| 363 | + self._avatar_sha = app.storage.cache.get_contact(
|
|
| 364 | + account, jid, 'avatar')
|
|
| 364 | 365 | |
| 365 | 366 | @property
|
| 366 | 367 | def is_self(self):
|
| ... | ... | @@ -448,7 +449,8 @@ def name(self) -> str: |
| 448 | 449 | if item is not None and item.name:
|
| 449 | 450 | return item.name
|
| 450 | 451 | |
| 451 | - nickname = app.storage.cache.get_contact(self._jid, 'nickname')
|
|
| 452 | + nickname = app.storage.cache.get_contact(
|
|
| 453 | + self._account, self._jid, 'nickname')
|
|
| 452 | 454 | if nickname:
|
| 453 | 455 | return nickname
|
| 454 | 456 | if self._jid.is_domain:
|
| ... | ... | @@ -466,7 +468,11 @@ def get_location(self) -> Optional[LocationData]: |
| 466 | 468 | |
| 467 | 469 | @property
|
| 468 | 470 | def avatar_sha(self) -> Optional[str]:
|
| 469 | - return app.storage.cache.get_contact(self._jid, 'avatar')
|
|
| 471 | + return app.storage.cache.get_contact(
|
|
| 472 | + self._account, self._jid, 'avatar')
|
|
| 473 | + |
|
| 474 | + def set_avatar_sha(self, sha: str) -> None:
|
|
| 475 | + app.storage.cache.set_contact(self._account, self._jid, 'avatar', sha)
|
|
| 470 | 476 | |
| 471 | 477 | def get_avatar(self,
|
| 472 | 478 | size: int,
|
| ... | ... | @@ -514,7 +520,7 @@ def update_avatar(self, sha: str) -> None: |
| 514 | 520 | |
| 515 | 521 | self._avatar_sha = sha
|
| 516 | 522 | |
| 517 | - app.storage.cache.set_contact(self._jid, 'avatar', sha)
|
|
| 523 | + app.storage.cache.set_contact(self._account, self._jid, 'avatar', sha)
|
|
| 518 | 524 | app.app.avatar_storage.invalidate_cache(self._jid)
|
| 519 | 525 | self.notify('avatar-update')
|
| 520 | 526 | |
| ... | ... | @@ -743,7 +749,10 @@ def name(self) -> str: |
| 743 | 749 | |
| 744 | 750 | @property
|
| 745 | 751 | def avatar_sha(self) -> Optional[str]:
|
| 746 | - return app.storage.cache.get_muc(self._jid, 'avatar')
|
|
| 752 | + return app.storage.cache.get_muc(self._account, self._jid, 'avatar')
|
|
| 753 | + |
|
| 754 | + def set_avatar_sha(self, sha: str) -> None:
|
|
| 755 | + app.storage.cache.set_muc(self._account, self._jid, 'avatar', sha)
|
|
| 747 | 756 | |
| 748 | 757 | def get_avatar(self, size: int, scale: int) -> Optional[cairo.ImageSurface]:
|
| 749 | 758 | transport_icon = None
|
| ... | ... | @@ -235,7 +235,8 @@ def disco_muc(self, |
| 235 | 235 | if not app.app.avatar_storage.avatar_exists(avatar_sha):
|
| 236 | 236 | app.app.avatar_storage.save_avatar(avatar)
|
| 237 | 237 | |
| 238 | - app.storage.cache.set_muc(result.info.jid, 'avatar', avatar_sha)
|
|
| 238 | + app.storage.cache.set_muc(
|
|
| 239 | + self._account, result.info.jid, 'avatar', avatar_sha)
|
|
| 239 | 240 | app.app.avatar_storage.invalidate_cache(result.info.jid)
|
| 240 | 241 | |
| 241 | 242 | self._con.get_module('VCardAvatars').muc_disco_info_update(result.info)
|
| ... | ... | @@ -55,7 +55,8 @@ def _nickname_received(self, |
| 55 | 55 | app.nicks[self._account] = nick
|
| 56 | 56 | return
|
| 57 | 57 | |
| 58 | - app.storage.cache.set_contact(properties.jid, 'nickname', nick)
|
|
| 58 | + app.storage.cache.set_contact(
|
|
| 59 | + self._account, properties.jid, 'nickname', nick)
|
|
| 59 | 60 | |
| 60 | 61 | self._log.info('Nickname for %s: %s', properties.jid, nick)
|
| 61 | 62 |
| ... | ... | @@ -97,11 +97,8 @@ def _request_vcard(self, |
| 97 | 97 | self._log.info('Received: %s %s', contact.jid, avatar_sha)
|
| 98 | 98 | app.app.avatar_storage.save_avatar(avatar)
|
| 99 | 99 | |
| 100 | - if isinstance(contact, BareContact):
|
|
| 101 | - app.storage.cache.set_contact(contact.jid, 'avatar', avatar_sha)
|
|
| 102 | - |
|
| 103 | - elif isinstance(contact, GroupchatContact):
|
|
| 104 | - app.storage.cache.set_muc(contact.jid, 'avatar', avatar_sha)
|
|
| 100 | + if isinstance(contact, (BareContact, GroupchatContact)):
|
|
| 101 | + contact.set_avatar_sha(avatar_sha)
|
|
| 105 | 102 | |
| 106 | 103 | else:
|
| 107 | 104 | self._muc_avatar_cache[contact.jid] = avatar_sha
|
| ... | ... | @@ -159,11 +156,7 @@ def _process_update(self, |
| 159 | 156 | if state == AvatarState.EMPTY:
|
| 160 | 157 | # Empty <photo/> tag, means no avatar is advertised
|
| 161 | 158 | self._log.info('%s has no avatar published', jid)
|
| 162 | - if groupchat:
|
|
| 163 | - app.storage.cache.set_muc(jid, 'avatar', None)
|
|
| 164 | - else:
|
|
| 165 | - app.storage.cache.set_contact(jid, 'avatar', None)
|
|
| 166 | - |
|
| 159 | + contact.set_avatar_sha(None)
|
|
| 167 | 160 | contact.update_avatar(avatar_sha)
|
| 168 | 161 | |
| 169 | 162 | else:
|
| ... | ... | @@ -176,11 +169,7 @@ def _process_update(self, |
| 176 | 169 | if app.app.avatar_storage.avatar_exists(avatar_sha):
|
| 177 | 170 | # Check if the avatar is already in storage
|
| 178 | 171 | self._log.info('Found avatar in storage')
|
| 179 | - if groupchat:
|
|
| 180 | - app.storage.cache.set_muc(jid, 'avatar', avatar_sha)
|
|
| 181 | - else:
|
|
| 182 | - app.storage.cache.set_contact(jid, 'avatar', avatar_sha)
|
|
| 183 | - |
|
| 172 | + contact.set_avatar_sha(avatar_sha)
|
|
| 184 | 173 | contact.update_avatar(avatar_sha)
|
| 185 | 174 | return
|
| 186 | 175 |
| ... | ... | @@ -35,7 +35,9 @@ |
| 35 | 35 | from gajim.common.storage.base import SqliteStorage
|
| 36 | 36 | from gajim.common.storage.base import timeit
|
| 37 | 37 | |
| 38 | -CURRENT_USER_VERSION = 9
|
|
| 38 | +ContactCacheDictT = dict[tuple[str, JID], dict[str, Any]]
|
|
| 39 | + |
|
| 40 | +CURRENT_USER_VERSION = 10
|
|
| 39 | 41 | |
| 40 | 42 | CACHE_SQL_STATEMENT = '''
|
| 41 | 43 | CREATE TABLE caps_cache (
|
| ... | ... | @@ -54,15 +56,19 @@ |
| 54 | 56 | roster TEXT
|
| 55 | 57 | );
|
| 56 | 58 | CREATE TABLE muc(
|
| 57 | - jid TEXT PRIMARY KEY UNIQUE,
|
|
| 58 | - avatar TEXT
|
|
| 59 | + account TEXT,
|
|
| 60 | + jid TEXT,
|
|
| 61 | + avatar TEXT,
|
|
| 62 | + PRIMARY KEY (account, jid)
|
|
| 59 | 63 | );
|
| 60 | 64 | CREATE TABLE contact(
|
| 61 | - jid TEXT PRIMARY KEY UNIQUE,
|
|
| 65 | + account TEXT,
|
|
| 66 | + jid TEXT,
|
|
| 62 | 67 | avatar TEXT,
|
| 63 | 68 | avatar_ts INTEGER,
|
| 64 | 69 | nickname TEXT,
|
| 65 | - nickname_ts INTEGER
|
|
| 70 | + nickname_ts INTEGER,
|
|
| 71 | + PRIMARY KEY (account, jid)
|
|
| 66 | 72 | );
|
| 67 | 73 | CREATE TABLE unread(
|
| 68 | 74 | account TEXT,
|
| ... | ... | @@ -101,8 +107,8 @@ def __init__(self, in_memory: bool = False): |
| 101 | 107 | |
| 102 | 108 | self._entity_caps_cache: dict[tuple[str, str], DiscoInfo] = {}
|
| 103 | 109 | self._disco_info_cache: dict[JID, DiscoInfo] = {}
|
| 104 | - self._muc_cache: dict[JID, dict[str, Any]] = defaultdict(dict)
|
|
| 105 | - self._contact_cache: dict[JID, dict[str, Any]] = defaultdict(dict)
|
|
| 110 | + self._muc_cache: ContactCacheDictT = defaultdict(dict)
|
|
| 111 | + self._contact_cache: ContactCacheDictT = defaultdict(dict)
|
|
| 106 | 112 | |
| 107 | 113 | def init(self, **kwargs: Any) -> None:
|
| 108 | 114 | SqliteStorage.init(self,
|
| ... | ... | @@ -136,7 +142,7 @@ def _migrate(self) -> None: |
| 136 | 142 | self._reinit_storage()
|
| 137 | 143 | return
|
| 138 | 144 | |
| 139 | - if user_version < 9:
|
|
| 145 | + if user_version < 10:
|
|
| 140 | 146 | self._reinit_storage()
|
| 141 | 147 | return
|
| 142 | 148 | |
| ... | ... | @@ -287,60 +293,74 @@ def remove_roster(self, account: str) -> None: |
| 287 | 293 | self._commit()
|
| 288 | 294 | |
| 289 | 295 | @timeit
|
| 290 | - def set_muc(self, jid: JID, prop: str, value: Any) -> None:
|
|
| 291 | - sql = f'''INSERT INTO muc (jid, {prop}) VALUES (?, ?)'''
|
|
| 296 | + def set_muc(self,
|
|
| 297 | + account: str,
|
|
| 298 | + jid: JID,
|
|
| 299 | + prop: str,
|
|
| 300 | + value: Any
|
|
| 301 | + ) -> None:
|
|
| 302 | + |
|
| 303 | + sql = f'''INSERT INTO muc (account, jid, {prop}) VALUES (?, ?, ?)'''
|
|
| 292 | 304 | |
| 293 | 305 | try:
|
| 294 | - self._con.execute(sql, (jid, value))
|
|
| 306 | + self._con.execute(sql, (account, jid, value))
|
|
| 295 | 307 | except sqlite3.IntegrityError:
|
| 296 | - sql = f'UPDATE muc SET {prop} = ? WHERE jid = ?'
|
|
| 297 | - self._con.execute(sql, (value, jid))
|
|
| 308 | + sql = f'UPDATE muc SET {prop} = ? WHERE account = ? AND jid = ?'
|
|
| 309 | + self._con.execute(sql, (value, account, jid))
|
|
| 298 | 310 | |
| 299 | - self._muc_cache[jid][prop] = value
|
|
| 311 | + self._muc_cache[(account, jid)][prop] = value
|
|
| 300 | 312 | |
| 301 | 313 | self._delayed_commit()
|
| 302 | 314 | |
| 303 | 315 | @timeit
|
| 304 | - def get_muc(self, jid: JID, prop: str) -> Any:
|
|
| 316 | + def get_muc(self, account: str, jid: JID, prop: str) -> Any:
|
|
| 305 | 317 | try:
|
| 306 | - return self._muc_cache[jid][prop]
|
|
| 318 | + return self._muc_cache[(account, jid)][prop]
|
|
| 307 | 319 | except KeyError:
|
| 308 | 320 | sql = f'''SELECT jid as "jid [jid]", {prop}
|
| 309 | - FROM muc WHERE jid = ?'''
|
|
| 310 | - row = self._con.execute(sql, (jid,)).fetchone()
|
|
| 321 | + FROM muc WHERE account = ? AND jid = ?'''
|
|
| 322 | + row = self._con.execute(sql, (account, jid)).fetchone()
|
|
| 311 | 323 | value = None if row is None else getattr(row, prop)
|
| 312 | 324 | |
| 313 | - self._muc_cache[jid][prop] = value
|
|
| 325 | + self._muc_cache[(account, jid)][prop] = value
|
|
| 314 | 326 | return value
|
| 315 | 327 | |
| 316 | 328 | @timeit
|
| 317 | - def set_contact(self, jid: JID, prop: str, value: Any) -> None:
|
|
| 318 | - sql = f'INSERT INTO contact (jid, {prop}, {prop}_ts) VALUES (?, ?, ?)'
|
|
| 329 | + def set_contact(self,
|
|
| 330 | + account: str,
|
|
| 331 | + jid: JID,
|
|
| 332 | + prop: str,
|
|
| 333 | + value: Any
|
|
| 334 | + ) -> None:
|
|
| 335 | + |
|
| 336 | + sql = f'''INSERT INTO contact (account, jid, {prop}, {prop}_ts)
|
|
| 337 | + VALUES (?, ?, ?, ?)'''
|
|
| 319 | 338 | |
| 320 | 339 | prop_ts = time.time()
|
| 321 | 340 | |
| 322 | 341 | try:
|
| 323 | - self._con.execute(sql, (jid, value, prop_ts))
|
|
| 342 | + self._con.execute(sql, (account, jid, value, prop_ts))
|
|
| 324 | 343 | except sqlite3.IntegrityError:
|
| 325 | - sql = f'UPDATE contact SET {prop} = ?, {prop}_ts = ? WHERE jid = ?'
|
|
| 326 | - self._con.execute(sql, (value, prop_ts, jid))
|
|
| 344 | + sql = f'''UPDATE contact SET {prop} = ?, {prop}_ts = ?
|
|
| 345 | + WHERE account = ? AND jid = ?'''
|
|
| 346 | + self._con.execute(sql, (value, prop_ts, account, jid))
|
|
| 327 | 347 | |
| 328 | - self._contact_cache[jid][prop] = (value, prop_ts)
|
|
| 348 | + self._contact_cache[(account, jid)][prop] = (value, prop_ts)
|
|
| 329 | 349 | |
| 330 | 350 | self._delayed_commit()
|
| 331 | 351 | |
| 332 | 352 | @timeit
|
| 333 | - def get_contact(self, jid: JID, prop: str) -> Any:
|
|
| 353 | + def get_contact(self, account: str, jid: JID, prop: str) -> Any:
|
|
| 334 | 354 | try:
|
| 335 | - value, prop_ts = self._contact_cache[jid][prop]
|
|
| 355 | + value, prop_ts = self._contact_cache[(account, jid)][prop]
|
|
| 336 | 356 | except KeyError:
|
| 337 | 357 | sql = f'''SELECT jid as "jid [jid]", {prop}, {prop}_ts
|
| 338 | - FROM contact WHERE jid = ?'''
|
|
| 339 | - row = self._con.execute(sql, (jid,)).fetchone()
|
|
| 358 | + FROM contact WHERE account = ? AND jid = ?'''
|
|
| 359 | + row = self._con.execute(sql, (account, jid)).fetchone()
|
|
| 340 | 360 | value = None if row is None else getattr(row, prop)
|
| 341 | 361 | prop_ts = 0 if row is None else getattr(row, f'{prop}_ts')
|
| 342 | 362 | |
| 343 | - self._contact_cache[jid][prop] = (value, prop_ts)
|
|
| 363 | + self._contact_cache[(account, jid)][prop] = (value, prop_ts)
|
|
| 344 | 364 | return value
|
| 345 | 365 | |
| 346 | 366 | else:
|
| ... | ... | @@ -432,7 +432,7 @@ def get_muc_surface(self, |
| 432 | 432 | if surface is not None:
|
| 433 | 433 | return surface
|
| 434 | 434 | |
| 435 | - avatar_sha = app.storage.cache.get_muc(jid, 'avatar')
|
|
| 435 | + avatar_sha = app.storage.cache.get_muc(account, jid, 'avatar')
|
|
| 436 | 436 | if avatar_sha is not None:
|
| 437 | 437 | surface = self.surface_from_filename(avatar_sha, size, scale)
|
| 438 | 438 | if surface is not None:
|
| ... | ... | @@ -442,7 +442,7 @@ def get_muc_surface(self, |
| 442 | 442 | |
| 443 | 443 | # avatar_sha set, but image is missing
|
| 444 | 444 | # (e.g. avatar cache deleted)
|
| 445 | - app.storage.cache.set_muc(jid, 'avatar', None)
|
|
| 445 | + app.storage.cache.set_muc(account, jid, 'avatar', None)
|
|
| 446 | 446 | |
| 447 | 447 | client = app.get_client(account)
|
| 448 | 448 | contact = client.get_module('Contacts').get_bare_contact(jid)
|