Mercurial > libervia-web
view libervia/web/pages/_browser/cache.py @ 1582:f52b89365002
browser: new `popup` module to create dynamic popups
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 28 Nov 2023 17:53:56 +0100 |
parents | 9b451115e726 |
children |
line wrap: on
line source
from browser import window, console as log from browser.local_storage import storage from dialog import notification from bridge import Bridge, AsyncBridge import json log.warning = log.warn session_uuid = window.session_uuid bridge = Bridge() async_bridge = AsyncBridge() # XXX: we don't use browser.object_storage because it is affected by # https://github.com/brython-dev/brython/issues/1467 and mixing local_storage.storage # and object_storage was resulting in weird behaviour (keys found in one not in the # other) class Cache: def __init__(self): try: cache = storage['libervia_cache'] except KeyError: self.request_data_from_backend() else: cache = json.loads(cache) if cache['metadata']['session_uuid'] != session_uuid: log.debug("data in cache are not valid for this session, resetting") del storage['libervia_cache'] self.request_data_from_backend() else: self._cache = cache log.debug("storage cache is used") @property def roster(self): return self._cache['roster'] @property def identities(self): return self._cache['identities'] def update(self): log.debug(f"updating: {self._cache}") storage['libervia_cache'] = json.dumps(self._cache) log.debug("cache stored") def _store_if_complete(self): self._completed_count -= 1 if self._completed_count == 0: del self._completed_count self.update() def get_contacts_cb(self, contacts): log.debug("roster received") roster = self._cache['roster'] for contact_jid, attributes, groups in contacts: roster[contact_jid] = { 'attributes': attributes, 'groups': groups, } self._store_if_complete() def identities_base_get_cb(self, identities_raw): log.debug("base identities received") identities = json.loads(identities_raw) self._cache['identities'].update(identities) self._store_if_complete() def request_failed(self, exc, message): notification.show(message.format(exc=exc), "error") self._store_if_complete() def request_data_from_backend(self): self._cache = { 'metadata': { "session_uuid": session_uuid, }, 'roster': {}, 'identities': {}, } self._completed_count = 2 log.debug("requesting roster to backend") bridge.contacts_get( callback=self.get_contacts_cb, errback=lambda e: self.request_failed(e, "Can't get contacts: {exc}") ) log.debug("requesting base identities to backend") bridge.identities_base_get( callback=self.identities_base_get_cb, errback=lambda e: self.request_failed(e, "Can't get base identities: {exc}") ) async def fill_identities(self, entities) -> None: """Check that identities for entities exist, request them otherwise""" to_get = {e for e in entities if e not in self._cache['identities']} if to_get: log.debug(f"we don't have all identities in cache, getting {to_get}") try: new_identities_raw = await async_bridge.identities_get( list(to_get), ['avatar', 'nicknames'], ) except Exception as e: notification.show( f"Can't get identities: {e}", "error" ) else: new_identities = json.loads(new_identities_raw) log.debug(f"new identities: {new_identities.keys()}") self._cache['identities'].update(new_identities) self.update() else: # we already have all identities log.debug("no missing identity") def match_identity(self, entity_jid, text, identity=None): """Returns True if a text match an entity identity identity will be matching if its jid or any of its name contain text @param entity_jid: jid of the entity to check @param text: text to use for filtering. Must be in lowercase and stripped @param identity: identity data if None, it will be retrieved if jid is not matching @return: True if entity is matching """ if text in entity_jid: return True if identity is None: try: identity = self.identities[entity_jid] except KeyError: log.debug(f"missing identity: {entity_jid}") return False return any(text in n.lower() for n in identity['nicknames']) def matching_identities(self, text): """Return identities corresponding to a text """ text = text.lower().strip() for entity_jid, identity in self._cache['identities'].items(): if ((text in entity_jid or any(text in n.lower() for n in identity['nicknames']) )): yield entity_jid cache = Cache() roster = cache.roster identities = cache.identities