comparison libervia/web/pages/_browser/cache.py @ 1531:d7c78722e4f8

browser (cache): make `fill_identities` async + use `json` module: - `json` module has been greatly improved in Brython, the former workaround is not needed anymore. - `fill_identities` is now async so an async method can wait for it to complete
author Goffi <goffi@goffi.org>
date Thu, 22 Jun 2023 16:35:34 +0200
parents eb00d593801d
children 9b451115e726
comparison
equal deleted inserted replaced
1530:b338c31d5251 1531:d7c78722e4f8
1 from browser import window 1 from browser import window, console as log
2 from browser.local_storage import storage 2 from browser.local_storage import storage
3 from javascript import JSON
4 from dialog import notification 3 from dialog import notification
5 from bridge import Bridge 4 from bridge import Bridge, AsyncBridge
5 import json
6 6
7 log.warning = log.warn
7 session_uuid = window.session_uuid 8 session_uuid = window.session_uuid
8 bridge = Bridge() 9 bridge = Bridge()
10 async_bridge = AsyncBridge()
9 11
10 # XXX: we don't use browser.object_storage because it is affected by 12 # XXX: we don't use browser.object_storage because it is affected by
11 # https://github.com/brython-dev/brython/issues/1467 and mixing local_storage.storage 13 # https://github.com/brython-dev/brython/issues/1467 and mixing local_storage.storage
12 # and object_storage was resulting in weird behaviour (keys found in one not in the 14 # and object_storage was resulting in weird behaviour (keys found in one not in the
13 # other) 15 # other)
19 try: 21 try:
20 cache = storage['libervia_cache'] 22 cache = storage['libervia_cache']
21 except KeyError: 23 except KeyError:
22 self.request_data_from_backend() 24 self.request_data_from_backend()
23 else: 25 else:
24 cache = JSON.parse(cache) 26 cache = json.loads(cache)
25 if cache['metadata']['session_uuid'] != session_uuid: 27 if cache['metadata']['session_uuid'] != session_uuid:
26 print("data in cache are not valid for this session, resetting") 28 print("data in cache are not valid for this session, resetting")
27 del storage['libervia_cache'] 29 del storage['libervia_cache']
28 self.request_data_from_backend() 30 self.request_data_from_backend()
29 else: 31 else:
37 @property 39 @property
38 def identities(self): 40 def identities(self):
39 return self._cache['identities'] 41 return self._cache['identities']
40 42
41 def update(self): 43 def update(self):
42 # FIXME: we use window.JSON as a workaround to
43 # https://github.com/brython-dev/brython/issues/1467
44 print(f"updating: {self._cache}") 44 print(f"updating: {self._cache}")
45 storage['libervia_cache'] = window.JSON.stringify(self._cache) 45 storage['libervia_cache'] = json.dumps(self._cache)
46 print("cache stored") 46 print("cache stored")
47 47
48 def _store_if_complete(self): 48 def _store_if_complete(self):
49 self._completed_count -= 1 49 self._completed_count -= 1
50 if self._completed_count == 0: 50 if self._completed_count == 0:
61 } 61 }
62 self._store_if_complete() 62 self._store_if_complete()
63 63
64 def identities_base_get_cb(self, identities_raw): 64 def identities_base_get_cb(self, identities_raw):
65 print("base identities received") 65 print("base identities received")
66 identities = JSON.parse(identities_raw) 66 identities = json.loads(identities_raw)
67 self._cache['identities'].update(identities) 67 self._cache['identities'].update(identities)
68 self._store_if_complete() 68 self._store_if_complete()
69 69
70 def request_failed(self, exc, message): 70 def request_failed(self, exc, message):
71 notification.show(message.format(exc=exc), "error") 71 notification.show(message.format(exc=exc), "error")
89 bridge.identities_base_get( 89 bridge.identities_base_get(
90 callback=self.identities_base_get_cb, 90 callback=self.identities_base_get_cb,
91 errback=lambda e: self.request_failed(e, "Can't get base identities: {exc}") 91 errback=lambda e: self.request_failed(e, "Can't get base identities: {exc}")
92 ) 92 )
93 93
94 def _fill_identities_cb(self, new_identities_raw, callback): 94 async def fill_identities(self, entities) -> None:
95 new_identities = JSON.parse(new_identities_raw)
96 print(f"new identities: {new_identities.keys()}")
97 self._cache['identities'].update(new_identities)
98 self.update()
99 if callback:
100 callback()
101
102 def fill_identities(self, entities, callback=None):
103 """Check that identities for entities exist, request them otherwise""" 95 """Check that identities for entities exist, request them otherwise"""
104 to_get = {e for e in entities if e not in self._cache['identities']} 96 to_get = {e for e in entities if e not in self._cache['identities']}
105 if to_get: 97 if to_get:
106 bridge.identities_get( 98 try:
107 list(to_get), 99 new_identities_raw = await async_bridge.identities_get(
108 ['avatar', 'nicknames'], 100 list(to_get),
109 callback=lambda identities: self._fill_identities_cb( 101 ['avatar', 'nicknames'],
110 identities, callback), 102 )
111 errback=lambda failure_: notification.show( 103 except Exception as e:
112 f"Can't get identities: {failure_}", 104 notification.show(
105 f"Can't get identities: {e}",
113 "error" 106 "error"
114 ) 107 )
115 ) 108 else:
109 new_identities = json.loads(new_identities_raw)
110 print(f"new identities: {new_identities.keys()}")
111 self._cache['identities'].update(new_identities)
112 self.update()
116 else: 113 else:
117 # we already have all identities 114 # we already have all identities
118 print("no missing identity") 115 log.debug("no missing identity")
119 if callback:
120 callback()
121 116
122 def match_identity(self, entity_jid, text, identity=None): 117 def match_identity(self, entity_jid, text, identity=None):
123 """Returns True if a text match an entity identity 118 """Returns True if a text match an entity identity
124 119
125 identity will be matching if its jid or any of its name contain text 120 identity will be matching if its jid or any of its name contain text