changeset 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 b338c31d5251
children 106945841fbc
files libervia/web/pages/_browser/cache.py libervia/web/pages/_browser/invitation.py libervia/web/pages/lists/view/_browser/__init__.py libervia/web/pages/photos/album/_browser/__init__.py
diffstat 4 files changed, 34 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/libervia/web/pages/_browser/cache.py	Thu Jun 08 23:32:47 2023 +0200
+++ b/libervia/web/pages/_browser/cache.py	Thu Jun 22 16:35:34 2023 +0200
@@ -1,11 +1,13 @@
-from browser import window
+from browser import window, console as log
 from browser.local_storage import storage
-from javascript import JSON
 from dialog import notification
-from bridge import Bridge
+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
@@ -21,7 +23,7 @@
         except KeyError:
             self.request_data_from_backend()
         else:
-            cache = JSON.parse(cache)
+            cache = json.loads(cache)
             if cache['metadata']['session_uuid'] != session_uuid:
                 print("data in cache are not valid for this session, resetting")
                 del storage['libervia_cache']
@@ -39,10 +41,8 @@
         return self._cache['identities']
 
     def update(self):
-        # FIXME: we use window.JSON as a workaround to
-        #   https://github.com/brython-dev/brython/issues/1467
         print(f"updating: {self._cache}")
-        storage['libervia_cache'] = window.JSON.stringify(self._cache)
+        storage['libervia_cache'] = json.dumps(self._cache)
         print("cache stored")
 
     def _store_if_complete(self):
@@ -63,7 +63,7 @@
 
     def identities_base_get_cb(self, identities_raw):
         print("base identities received")
-        identities = JSON.parse(identities_raw)
+        identities = json.loads(identities_raw)
         self._cache['identities'].update(identities)
         self._store_if_complete()
 
@@ -91,33 +91,28 @@
             errback=lambda e: self.request_failed(e, "Can't get base identities: {exc}")
         )
 
-    def _fill_identities_cb(self, new_identities_raw, callback):
-        new_identities = JSON.parse(new_identities_raw)
-        print(f"new identities: {new_identities.keys()}")
-        self._cache['identities'].update(new_identities)
-        self.update()
-        if callback:
-            callback()
-
-    def fill_identities(self, entities, callback=None):
+    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:
-            bridge.identities_get(
-                list(to_get),
-                ['avatar', 'nicknames'],
-                callback=lambda identities: self._fill_identities_cb(
-                    identities, callback),
-                errback=lambda failure_: notification.show(
-                    f"Can't get identities: {failure_}",
+            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)
+                print(f"new identities: {new_identities.keys()}")
+                self._cache['identities'].update(new_identities)
+                self.update()
         else:
             # we already have all identities
-            print("no missing identity")
-            if callback:
-                callback()
+            log.debug("no missing identity")
 
     def match_identity(self, entity_jid, text, identity=None):
         """Returns True if a text match an entity identity
--- a/libervia/web/pages/_browser/invitation.py	Thu Jun 08 23:32:47 2023 +0200
+++ b/libervia/web/pages/_browser/invitation.py	Thu Jun 22 16:35:34 2023 +0200
@@ -1,9 +1,9 @@
-from browser import document, window, timer
 from bridge import Bridge
+from browser import document, timer, window
+from cache import cache
+import dialog
+import javascript
 from template import Template
-import dialog
-from cache import cache
-import javascript
 
 bridge = Bridge()
 # we use JS RegExp because Python's re is really long to import in Brython
@@ -26,7 +26,7 @@
         self._active_new_item = None
         self._idx = 0
 
-    def attach(self, affiliations=None):
+    async def attach(self, affiliations=None):
         if affiliations is None:
             affiliations = {}
         self.affiliations = affiliations
@@ -37,7 +37,9 @@
             close_elt.bind("click", self.on_manager_close)
         self.side_panel.bind("click", lambda evt: evt.stopPropagation())
 
-        cache.fill_identities(affiliations.keys(), callback=self._set_affiliations)
+        await cache.fill_identities(affiliations.keys())
+        for entity_jid, affiliation in self.affiliations.items():
+            self.set_affiliation(entity_jid, affiliation)
 
         contact_elt = self.manager_panel_elt.select_one('input[name="contact"]')
         contact_elt.bind("input", self.on_contact_input)
@@ -46,10 +48,6 @@
         contact_elt.bind("blur", self.on_contact_blur)
         document['invite_email'].bind('click', self.on_invite_email_click)
 
-    def _set_affiliations(self):
-        for entity_jid, affiliation in self.affiliations.items():
-            self.set_affiliation(entity_jid, affiliation)
-
     def open(self):
         """Re-attach and show a closed panel"""
         self._body_ori_style = document.body.style.height, document.body.style.overflow
--- a/libervia/web/pages/lists/view/_browser/__init__.py	Thu Jun 08 23:32:47 2023 +0200
+++ b/libervia/web/pages/lists/view/_browser/__init__.py	Thu Jun 22 16:35:34 2023 +0200
@@ -1,4 +1,4 @@
-from browser import window, document, aio, bind
+from browser import aio, window, document, aio, bind
 from invitation import InvitationManager
 from javascript import JSON
 from bridge import Async as Bridge, BridgeException
@@ -33,7 +33,7 @@
         if name:
             pubsub_data['name'] = name
     manager = InvitationManager("pubsub", pubsub_data)
-    manager.attach(affiliations=affiliations)
+    aio.run(manager.attach(affiliations=affiliations))
 
 
 async def on_delete(evt):
--- a/libervia/web/pages/photos/album/_browser/__init__.py	Thu Jun 08 23:32:47 2023 +0200
+++ b/libervia/web/pages/photos/album/_browser/__init__.py	Thu Jun 22 16:35:34 2023 +0200
@@ -293,7 +293,7 @@
     evt.stopPropagation()
     evt.preventDefault()
     manager = InvitationManager("photos", {"service": files_service, "path": files_path})
-    manager.attach(affiliations=affiliations)
+    aio.run(manager.attach(affiliations=affiliations))
 
 
 # hint