Philipp Hörist pushed to branch master at gajim / gajim
Commits: 3ae324ed by lovetox at 2022-08-13T19:22:31+02:00 cq: ChatList: Help type checker narrowing the type
- - - - - 8c1722e1 by lovetox at 2022-08-13T21:14:28+02:00 refactor: Storage: Allow CacheStorage to be created in memory
This is useful for tests
- - - - - 83f9ed16 by lovetox at 2022-08-13T21:15:33+02:00 refactor: Contacts: Make contacts a hashable object
- - - - - f1e8841f by lovetox at 2022-08-13T21:44:36+02:00 refactor: ChatBanner: Preserve phone indicator state on contact switch
- - - - - d8dfff44 by lovetox at 2022-08-13T21:53:02+02:00 other: Tests: Add contact object tests
- - - - -
6 changed files:
- gajim/common/modules/contacts.py - gajim/common/storage/base.py - gajim/common/storage/cache.py - gajim/gtk/chat_banner.py - gajim/gtk/chat_list.py - + test/no_gui/test_contacts.py
Changes:
===================================== gajim/common/modules/contacts.py ===================================== @@ -265,6 +265,16 @@ def __init__(self, self._jid = jid self._account = account
+ def __hash__(self) -> int: + return hash(f'{self._account}-{self._jid}') + + def __eq__(self, obj: object) -> bool: + if not isinstance(obj, CommonContact): + return NotImplemented + + return (self._account == obj.account and + obj._jid == self._jid) + def _module(self, name: str) -> BaseModule: return app.get_client(self._account).get_module(name)
===================================== gajim/common/storage/base.py ===================================== @@ -16,6 +16,7 @@
from typing import Any from typing import Callable +from typing import Optional from typing import TypeVar from typing import cast
@@ -36,6 +37,7 @@ from nbxmpp.structs import CommonError from nbxmpp.modules.discovery import parse_disco_info
+ _T = TypeVar('_T')
@@ -135,9 +137,10 @@ class SqliteStorage:
def __init__(self, log: logging.Logger, - path: Path, + path: Optional[Path], create_statement: str, - commit_delay: int = 500) -> None: + commit_delay: int = 500 + ) -> None:
self._log = log self._path = path @@ -147,14 +150,14 @@ def __init__(self, self._commit_source_id = None
def init(self, **kwargs: Any) -> None: - if self._path.exists(): + if self._path is None or not self._path.exists(): + self._con = self._create_storage(**kwargs) + + else: if not self._path.is_file(): sys.exit('%s must be a file' % self._path) self._con = self._connect(**kwargs)
- else: - self._con = self._create_storage(**kwargs) - self._migrate_storage()
def _set_journal_mode(self, mode: str) -> None: @@ -171,19 +174,24 @@ def user_version(self) -> int: return self._con.execute('PRAGMA user_version').fetchone()[0]
def _connect(self, **kwargs: Any) -> sqlite3.Connection: - return sqlite3.connect(self._path, **kwargs) + self._log.info('Connect to %s', self._path) + return sqlite3.connect(self._path or ':memory:', **kwargs)
def _create_storage(self, **kwargs: Any) -> sqlite3.Connection: - self._log.info('Creating %s', self._path) + self._log.info('Creating %s', self._path or 'in memory') + con = self._connect(**kwargs) - self._path.chmod(0o600) + + if self._path is not None: + self._path.chmod(0o600)
try: con.executescript(self._create_statement) except Exception: self._log.exception('Error') con.close() - self._path.unlink() + if self._path is not None: + self._path.unlink() sys.exit('Failed creating storage')
con.commit() @@ -192,7 +200,9 @@ def _create_storage(self, **kwargs: Any) -> sqlite3.Connection: def _reinit_storage(self) -> None: if self._con is not None: self._con.close() - self._path.unlink() + + if self._path is not None: + self._path.unlink() self.init()
def _migrate_storage(self) -> None:
===================================== gajim/common/storage/cache.py ===================================== @@ -93,10 +93,11 @@ class UnreadTableRow(NamedTuple):
class CacheStorage(SqliteStorage): - def __init__(self): + def __init__(self, in_memory: bool = False): + path = None if in_memory else configpaths.get('CACHE_DB') SqliteStorage.__init__(self, log, - configpaths.get('CACHE_DB'), + path, CACHE_SQL_STATEMENT)
self._entity_caps_cache: dict[tuple[str, str], DiscoInfo] = {}
===================================== gajim/gtk/chat_banner.py ===================================== @@ -51,6 +51,8 @@ def __init__(self) -> None: self._client: Optional[types.Client] = None self._contact: Optional[types.ChatContactT] = None
+ self._last_message_from_phone: set[BareContact] = set() + self._ui = get_builder('chat_banner.ui') self.add(self._ui.banner_box) self._ui.connect_signals(self) @@ -128,7 +130,8 @@ def switch_contact(self, contact: types.ChatContactT) -> None: ('account-disabled', ged.GUI2, self._on_account_changed) ])
- self._ui.phone_image.set_visible(False) + self._ui.phone_image.set_visible( + self._contact in self._last_message_from_phone)
if hide_banner: self.set_no_show_all(True) @@ -225,6 +228,11 @@ def _on_message_received(self, event: MessageReceived) -> None: return
resource_contact = self._contact.get_resource(event.resource) + if resource_contact.is_phone: + self._last_message_from_phone.add(self._contact) + else: + self._last_message_from_phone.discard(self._contact) + self._ui.phone_image.set_visible(resource_contact.is_phone)
def _update_avatar(self) -> None:
===================================== gajim/gtk/chat_list.py ===================================== @@ -607,7 +607,8 @@ def __init__(self, workspace_id: str, account: str, jid: JID, type_: str, self.update_name() self.update_account_identifier()
- if self.contact.is_groupchat and not self.contact.can_notify(): + if (isinstance(self.contact, GroupchatContact) and + not self.contact.can_notify()): self._ui.unread_label.get_style_context().add_class( 'unread-counter-silent')
===================================== test/no_gui/test_contacts.py ===================================== @@ -0,0 +1,30 @@ + +import unittest +from unittest.mock import MagicMock + +from nbxmpp.protocol import JID + +from gajim.common import app +from gajim.common.modules.contacts import Contacts +from gajim.common.modules.contacts import BareContact +from gajim.common.storage.cache import CacheStorage + + +class ContactTest(unittest.TestCase): + def test_contact_object(self): + account = 'testacc' + jid = JID.from_string('user@example.org') + module = Contacts(MagicMock()) + + app.storage.cache = CacheStorage(in_memory=True) + app.storage.cache.init() + + contact = BareContact(module._log, jid, account) + contact2 = BareContact(module._log, jid, account) + + self.assertEqual(contact, contact2) + self.assertEqual(hash(contact), hash(contact2)) + + +if __name__ == '__main__': + unittest.main()
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/c30369acb0fccb0d64cecd6e13749be3...