diff libervia/backend/core/main.py @ 4270:0d7bb4df2343

Reformatted code base using black.
author Goffi <goffi@goffi.org>
date Wed, 19 Jun 2024 18:44:57 +0200
parents 9fc3d28bc3f6
children 9e63e02318ec
line wrap: on
line diff
--- a/libervia/backend/core/main.py	Tue Jun 18 12:06:45 2024 +0200
+++ b/libervia/backend/core/main.py	Wed Jun 19 18:44:57 2024 +0200
@@ -29,6 +29,7 @@
 from libervia import backend
 from libervia.backend.core.i18n import _, D_, language_switch
 from libervia.backend.core import patches
+
 patches.apply()
 from twisted.application import service
 from twisted.internet import defer
@@ -57,6 +58,7 @@
 
 log = getLogger(__name__)
 
+
 class LiberviaBackend(service.Service):
 
     def _init(self):
@@ -67,7 +69,7 @@
         # dynamic menus. key: callback_id, value: menu data (dictionnary)
         self._menus = {}
         self._menus_paths = {}  # path to id. key: (menu_type, lower case tuple of path),
-                                # value: menu id
+        # value: menu id
 
         # like initialised, but launched before init script is done, mainly useful for CLI
         # frontend, so it can be used in init script, while other frontends are waiting.
@@ -75,7 +77,7 @@
         self.initialised = defer.Deferred()
         self.profiles = {}
         self.plugins = {}
-        # map for short name to whole namespace,
+        # map for short name to whole namespace,
         # extended by plugins with register_namespace
         self.ns_map = {
             "x-data": xmpp.NS_X_DATA,
@@ -85,13 +87,10 @@
         self.memory = memory.Memory(self)
 
         # trigger are used to change Libervia behaviour
-        self.trigger = (
-            trigger.TriggerManager()
-        )
+        self.trigger = trigger.TriggerManager()
 
-        bridge_name = (
-            os.getenv("LIBERVIA_BRIDGE_NAME")
-            or self.memory.config_get("", "bridge", "dbus")
+        bridge_name = os.getenv("LIBERVIA_BRIDGE_NAME") or self.memory.config_get(
+            "", "bridge", "dbus"
         )
 
         bridge_module = dynamic_import.bridge(bridge_name)
@@ -120,7 +119,6 @@
         else:
             self.local_shared_path = None
 
-
         defer.ensureDeferred(self._post_init())
 
     @property
@@ -174,40 +172,58 @@
         self.bridge.register_method("entity_data_get", self.memory._get_entity_data)
         self.bridge.register_method("entities_data_get", self.memory._get_entities_data)
         self.bridge.register_method("profile_create", self.memory.create_profile)
-        self.bridge.register_method("profile_delete_async", self.memory.profile_delete_async)
+        self.bridge.register_method(
+            "profile_delete_async", self.memory.profile_delete_async
+        )
         self.bridge.register_method("profile_start_session", self.memory.start_session)
         self.bridge.register_method(
             "profile_is_session_started", self.memory._is_session_started
         )
-        self.bridge.register_method("profile_set_default", self.memory.profile_set_default)
+        self.bridge.register_method(
+            "profile_set_default", self.memory.profile_set_default
+        )
         self.bridge.register_method("connect", self._connect)
         self.bridge.register_method("disconnect", self.disconnect)
         self.bridge.register_method("contact_get", self._contact_get)
         self.bridge.register_method("contacts_get", self.contacts_get)
-        self.bridge.register_method("contacts_get_from_group", self.contacts_get_from_group)
+        self.bridge.register_method(
+            "contacts_get_from_group", self.contacts_get_from_group
+        )
         self.bridge.register_method("main_resource_get", self.memory._get_main_resource)
         self.bridge.register_method(
             "presence_statuses_get", self.memory._get_presence_statuses
         )
         self.bridge.register_method("sub_waiting_get", self.memory.sub_waiting_get)
         self.bridge.register_method("message_send", self._message_send)
-        self.bridge.register_method("message_encryption_start",
-                                    self._message_encryption_start)
-        self.bridge.register_method("message_encryption_stop",
-                                    self._message_encryption_stop)
-        self.bridge.register_method("message_encryption_get",
-                                    self._message_encryption_get)
-        self.bridge.register_method("encryption_namespace_get",
-                                    self._encryption_namespace_get)
-        self.bridge.register_method("encryption_plugins_get", self._encryption_plugins_get)
-        self.bridge.register_method("encryption_trust_ui_get", self._encryption_trust_ui_get)
+        self.bridge.register_method(
+            "message_encryption_start", self._message_encryption_start
+        )
+        self.bridge.register_method(
+            "message_encryption_stop", self._message_encryption_stop
+        )
+        self.bridge.register_method(
+            "message_encryption_get", self._message_encryption_get
+        )
+        self.bridge.register_method(
+            "encryption_namespace_get", self._encryption_namespace_get
+        )
+        self.bridge.register_method(
+            "encryption_plugins_get", self._encryption_plugins_get
+        )
+        self.bridge.register_method(
+            "encryption_trust_ui_get", self._encryption_trust_ui_get
+        )
         self.bridge.register_method("config_get", self._get_config)
         self.bridge.register_method("param_set", self.param_set)
         self.bridge.register_method("param_get_a", self.memory.get_string_param_a)
         self.bridge.register_method("private_data_get", self.memory._private_data_get)
         self.bridge.register_method("private_data_set", self.memory._private_data_set)
-        self.bridge.register_method("private_data_delete", self.memory._private_data_delete)
-        self.bridge.register_method("param_get_a_async", self.memory.async_get_string_param_a)
+        self.bridge.register_method(
+            "private_data_delete", self.memory._private_data_delete
+        )
+        self.bridge.register_method(
+            "param_get_a_async", self.memory.async_get_string_param_a
+        )
         self.bridge.register_method(
             "params_values_from_category_get_async",
             self.memory._get_params_values_from_category,
@@ -216,7 +232,9 @@
         self.bridge.register_method(
             "params_categories_get", self.memory.params_categories_get
         )
-        self.bridge.register_method("params_register_app", self.memory.params_register_app)
+        self.bridge.register_method(
+            "params_register_app", self.memory.params_register_app
+        )
         self.bridge.register_method("history_get", self.memory._history_get)
         self.bridge.register_method("presence_set", self._set_presence)
         self.bridge.register_method("subscription", self.subscription)
@@ -242,13 +260,18 @@
         self.bridge.register_method("namespaces_get", self.get_namespaces)
         self.bridge.register_method("image_check", self._image_check)
         self.bridge.register_method("image_resize", self._image_resize)
-        self.bridge.register_method("image_generate_preview", self._image_generate_preview)
+        self.bridge.register_method(
+            "image_generate_preview", self._image_generate_preview
+        )
         self.bridge.register_method("image_convert", self._image_convert)
         self.bridge.register_method("notification_add", self.memory._add_notification)
         self.bridge.register_method("notifications_get", self.memory._get_notifications)
-        self.bridge.register_method("notification_delete", self.memory._delete_notification)
-        self.bridge.register_method("notifications_expired_clean", self.memory._notifications_expired_clean)
-
+        self.bridge.register_method(
+            "notification_delete", self.memory._delete_notification
+        )
+        self.bridge.register_method(
+            "notifications_expired_clean", self.memory._notifications_expired_clean
+        )
 
         await self.memory.initialise()
         self.common_cache = cache.Cache(self, None)
@@ -277,10 +300,7 @@
             else:
                 log.info(f"Running init script {init_script!r}.")
                 try:
-                    await async_process.run(
-                        str(init_script),
-                        verbose=True
-                    )
+                    await async_process.run(str(init_script), verbose=True)
                 except RuntimeError as e:
                     log.error(f"Init script failed: {e}")
                     self.stopService()
@@ -292,15 +312,18 @@
         # profile autoconnection must be done after self.initialised is called because
         # start_session waits for it.
         autoconnect_dict = await self.memory.storage.get_ind_param_values(
-            category='Connection', name='autoconnect_backend',
+            category="Connection",
+            name="autoconnect_backend",
         )
         profiles_autoconnect = [p for p, v in autoconnect_dict.items() if C.bool(v)]
         if not self.trigger.point("profilesAutoconnect", profiles_autoconnect):
             return
         if profiles_autoconnect:
-            log.info(D_(
-                "Following profiles will be connected automatically: {profiles}"
-                ).format(profiles= ', '.join(profiles_autoconnect)))
+            log.info(
+                D_(
+                    "Following profiles will be connected automatically: {profiles}"
+                ).format(profiles=", ".join(profiles_autoconnect))
+            )
         connect_d_list = []
         for profile in profiles_autoconnect:
             connect_d_list.append(defer.ensureDeferred(self.connect(profile)))
@@ -312,8 +335,8 @@
                     profile = profiles_autoconnect[0]
                     log.warning(
                         _("Can't autoconnect profile {profile}: {reason}").format(
-                            profile = profile,
-                            reason = result)
+                            profile=profile, reason=result
+                        )
                     )
 
     def _add_base_menus(self):
@@ -342,7 +365,8 @@
                 init_path = plug_path / f"__init__.{C.PLUGIN_EXT}"
                 if not init_path.exists():
                     log.warning(
-                        f"{plug_path} doesn't appear to be a package, can't load it")
+                        f"{plug_path} doesn't appear to be a package, can't load it"
+                    )
                     continue
                 plug_name = plug_path.name
             elif plug_path.is_file():
@@ -350,12 +374,12 @@
                     continue
                 plug_name = plug_path.stem
             else:
-                log.warning(
-                    f"{plug_path} is not a file or a dir, ignoring it")
+                log.warning(f"{plug_path} is not a file or a dir, ignoring it")
                 continue
             if not plug_name.isidentifier():
                 log.warning(
-                    f"{plug_name!r} is not a valid name for a plugin, ignoring it")
+                    f"{plug_name!r} is not a valid name for a plugin, ignoring it"
+                )
                 continue
             plugin_path = f"libervia.backend.plugins.{plug_name}"
             try:
@@ -364,9 +388,7 @@
                 self._unimport_plugin(plugin_path)
                 log.warning(
                     "Can't import plugin [{path}] because of an unavailale third party "
-                    "module:\n{msg}".format(
-                        path=plugin_path, msg=e
-                    )
+                    "module:\n{msg}".format(path=plugin_path, msg=e)
                 )
                 continue
             except exceptions.CancelError as e:
@@ -450,9 +472,7 @@
         else:
             if not import_name in plugins_to_import:
                 if optional:
-                    log.warning(
-                        _("Recommended plugin not found: {}").format(import_name)
-                    )
+                    log.warning(_("Recommended plugin not found: {}").format(import_name))
                     return
                 msg = "Dependency not found: {}".format(import_name)
                 log.error(msg)
@@ -521,7 +541,8 @@
         return defer.ensureDeferred(self.connect(profile, password, options))
 
     async def connect(
-        self, profile, password="", options=None, max_retries=C.XMPP_MAX_RETRIES):
+        self, profile, password="", options=None, max_retries=C.XMPP_MAX_RETRIES
+    ):
         """Connect a profile (i.e. connect client.component to XMPP server)
 
         Retrieve the individual parameters, authenticate the profile
@@ -761,16 +782,14 @@
         try:
             return self.ns_map[short_name]
         except KeyError:
-            raise exceptions.NotFound("namespace {short_name} is not registered"
-                                      .format(short_name=short_name))
+            raise exceptions.NotFound(
+                "namespace {short_name} is not registered".format(short_name=short_name)
+            )
 
     def get_session_infos(self, profile_key):
         """compile interesting data on current profile session"""
         client = self.get_client(profile_key)
-        data = {
-            "jid": client.jid.full(),
-            "started": str(int(client.started))
-            }
+        data = {"jid": client.jid.full(), "started": str(int(client.started))}
         return defer.succeed(data)
 
     def _get_devices_infos(self, bare_jid, profile_key):
@@ -808,11 +827,11 @@
                 "resource": resource,
             }
             try:
-                presence = cache_data['presence']
+                presence = cache_data["presence"]
             except KeyError:
                 pass
             else:
-                res_data['presence'] = {
+                res_data["presence"] = {
                     "show": presence.show,
                     "priority": presence.priority,
                     "statuses": presence.statuses,
@@ -821,12 +840,14 @@
             disco = await self.get_disco_infos(client, res_jid)
 
             for (category, type_), name in disco.identities.items():
-                identities = res_data.setdefault('identities', [])
-                identities.append({
-                    "name": name,
-                    "category": category,
-                    "type": type_,
-                })
+                identities = res_data.setdefault("identities", [])
+                identities.append(
+                    {
+                        "name": name,
+                        "category": category,
+                        "type": type_,
+                    }
+                )
 
             ret_data.append(res_data)
 
@@ -857,7 +878,7 @@
         """
         report = image.check(self, path, max_size=(300, 300))
 
-        if not report['too_large']:
+        if not report["too_large"]:
             # in the unlikely case that image is already smaller than a preview
             preview_path = path
         else:
@@ -867,17 +888,14 @@
             filename = f"{uid}{path.suffix.lower()}"
             metadata = client.cache.get_metadata(uid=uid)
             if metadata is not None:
-                preview_path = metadata['path']
+                preview_path = metadata["path"]
             else:
                 with client.cache.cache_data(
-                    source='HOST_PREVIEW',
-                    uid=uid,
-                    filename=filename) as cache_f:
+                    source="HOST_PREVIEW", uid=uid, filename=filename
+                ) as cache_f:
 
                     preview_path = await image.resize(
-                        path,
-                        new_size=report['recommended_size'],
-                        dest=cache_f
+                        path, new_size=report["recommended_size"], dest=cache_f
                     )
 
         return preview_path
@@ -922,23 +940,19 @@
             metadata = cache.get_metadata(uid=uid)
             if metadata is not None:
                 # there is already a conversion for this image in cache
-                return metadata['path']
+                return metadata["path"]
             else:
                 with cache.cache_data(
-                    source='HOST_IMAGE_CONVERT',
-                    uid=uid,
-                    filename=filename) as cache_f:
+                    source="HOST_IMAGE_CONVERT", uid=uid, filename=filename
+                ) as cache_f:
 
                     converted_path = await image.convert(
-                        source,
-                        dest=cache_f,
-                        extra=extra
+                        source, dest=cache_f, extra=extra
                     )
                 return converted_path
         else:
             return await image.convert(source, dest, extra)
 
-
     # local dirs
 
     def get_local_path(
@@ -998,18 +1012,19 @@
     def register_encryption_plugin(self, *args, **kwargs):
         return encryption.EncryptionHandler.register_plugin(*args, **kwargs)
 
-    def _message_encryption_start(self, to_jid_s, namespace, replace=False,
-                                profile_key=C.PROF_KEY_NONE):
+    def _message_encryption_start(
+        self, to_jid_s, namespace, replace=False, profile_key=C.PROF_KEY_NONE
+    ):
         client = self.get_client(profile_key)
         to_jid = jid.JID(to_jid_s)
         return defer.ensureDeferred(
-            client.encryption.start(to_jid, namespace or None, replace))
+            client.encryption.start(to_jid, namespace or None, replace)
+        )
 
     def _message_encryption_stop(self, to_jid_s, profile_key=C.PROF_KEY_NONE):
         client = self.get_client(profile_key)
         to_jid = jid.JID(to_jid_s)
-        return defer.ensureDeferred(
-            client.encryption.stop(to_jid))
+        return defer.ensureDeferred(client.encryption.stop(to_jid))
 
     def _message_encryption_get(self, to_jid_s, profile_key=C.PROF_KEY_NONE):
         client = self.get_client(profile_key)
@@ -1024,42 +1039,48 @@
         plugins = encryption.EncryptionHandler.getPlugins()
         ret = []
         for p in plugins:
-            ret.append({
-                "name": p.name,
-                "namespace": p.namespace,
-                "priority": p.priority,
-                "directed": p.directed,
-                })
+            ret.append(
+                {
+                    "name": p.name,
+                    "namespace": p.namespace,
+                    "priority": p.priority,
+                    "directed": p.directed,
+                }
+            )
         return data_format.serialise(ret)
 
     def _encryption_trust_ui_get(self, to_jid_s, namespace, profile_key):
         client = self.get_client(profile_key)
         to_jid = jid.JID(to_jid_s)
         d = defer.ensureDeferred(
-            client.encryption.get_trust_ui(to_jid, namespace=namespace or None))
+            client.encryption.get_trust_ui(to_jid, namespace=namespace or None)
+        )
         d.addCallback(lambda xmlui: xmlui.toXml())
         return d
 
     ## XMPP methods ##
 
     def _message_send(
-            self, to_jid_s, message, subject=None, mess_type="auto", extra_s="",
-            profile_key=C.PROF_KEY_NONE):
+        self,
+        to_jid_s,
+        message,
+        subject=None,
+        mess_type="auto",
+        extra_s="",
+        profile_key=C.PROF_KEY_NONE,
+    ):
         client = self.get_client(profile_key)
         to_jid = jid.JID(to_jid_s)
         return client.sendMessage(
-            to_jid,
-            message,
-            subject,
-            mess_type,
-            data_format.deserialise(extra_s)
+            to_jid, message, subject, mess_type, data_format.deserialise(extra_s)
         )
 
     def _set_presence(self, to="", show="", statuses=None, profile_key=C.PROF_KEY_NONE):
         return self.presence_set(jid.JID(to) if to else None, show, statuses, profile_key)
 
-    def presence_set(self, to_jid=None, show="", statuses=None,
-                    profile_key=C.PROF_KEY_NONE):
+    def presence_set(
+        self, to_jid=None, show="", statuses=None, profile_key=C.PROF_KEY_NONE
+    ):
         """Send our presence information"""
         if statuses is None:
             statuses = {}
@@ -1116,7 +1137,7 @@
     def contact_update(self, client, to_jid, name, groups):
         """update a contact in roster list"""
         roster_item = RosterItem(to_jid)
-        roster_item.name = name or u''
+        roster_item.name = name or ""
         roster_item.groups = set(groups)
         if not self.trigger.point("roster_update", client, roster_item):
             return
@@ -1167,28 +1188,46 @@
     def find_features_set(self, *args, **kwargs):
         return self.memory.disco.find_features_set(*args, **kwargs)
 
-    def _find_by_features(self, namespaces, identities, bare_jids, service, roster, own_jid,
-                        local_device, profile_key):
+    def _find_by_features(
+        self,
+        namespaces,
+        identities,
+        bare_jids,
+        service,
+        roster,
+        own_jid,
+        local_device,
+        profile_key,
+    ):
         client = self.get_client(profile_key)
         identities = [tuple(i) for i in identities] if identities else None
-        return defer.ensureDeferred(self.find_by_features(
-            client, namespaces, identities, bare_jids, service, roster, own_jid,
-            local_device))
+        return defer.ensureDeferred(
+            self.find_by_features(
+                client,
+                namespaces,
+                identities,
+                bare_jids,
+                service,
+                roster,
+                own_jid,
+                local_device,
+            )
+        )
 
     async def find_by_features(
         self,
         client: SatXMPPEntity,
         namespaces: List[str],
-        identities: Optional[List[Tuple[str, str]]]=None,
-        bare_jids: bool=False,
-        service: bool=True,
-        roster: bool=True,
-        own_jid: bool=True,
-        local_device: bool=False
+        identities: Optional[List[Tuple[str, str]]] = None,
+        bare_jids: bool = False,
+        service: bool = True,
+        roster: bool = True,
+        own_jid: bool = True,
+        local_device: bool = False,
     ) -> Tuple[
         Dict[jid.JID, Tuple[str, str, str]],
         Dict[jid.JID, Tuple[str, str, str]],
-        Dict[jid.JID, Tuple[str, str, str]]
+        Dict[jid.JID, Tuple[str, str, str]],
     ]:
         """Retrieve all services or contacts managing a set a features
 
@@ -1224,19 +1263,25 @@
         if service:
             services_jids = await self.find_features_set(client, namespaces)
             services_jids = list(services_jids)  # we need a list to map results below
-            services_infos  = await defer.DeferredList(
-                [self.get_disco_infos(client, service_jid) for service_jid in services_jids]
+            services_infos = await defer.DeferredList(
+                [
+                    self.get_disco_infos(client, service_jid)
+                    for service_jid in services_jids
+                ]
             )
 
             for idx, (success, infos) in enumerate(services_infos):
                 service_jid = services_jids[idx]
                 if not success:
                     log.warning(
-                        _("Can't find features for service {service_jid}, ignoring")
-                        .format(service_jid=service_jid.full()))
+                        _(
+                            "Can't find features for service {service_jid}, ignoring"
+                        ).format(service_jid=service_jid.full())
+                    )
                     continue
-                if (identities is not None
-                    and not set(infos.identities.keys()).issuperset(identities)):
+                if identities is not None and not set(infos.identities.keys()).issuperset(
+                    identities
+                ):
                     continue
                 found_identities = [
                     (cat, type_, name or "")
@@ -1291,8 +1336,10 @@
                 full_jid = full_jids[idx]
                 if not success:
                     log.warning(
-                        _("Can't retrieve {full_jid} infos, ignoring")
-                        .format(full_jid=full_jid.full()))
+                        _("Can't retrieve {full_jid} infos, ignoring").format(
+                            full_jid=full_jid.full()
+                        )
+                    )
                     continue
                 if infos.features.issuperset(namespaces):
                     if identities is not None and not set(
@@ -1476,21 +1523,16 @@
         return callback_id
 
     def remove_callback(self, callback_id):
-        """ Remove a previously registered callback
-        @param callback_id: id returned by [register_callback] """
+        """Remove a previously registered callback
+        @param callback_id: id returned by [register_callback]"""
         log.debug("Removing callback [%s]" % callback_id)
         del self._cb_map[callback_id]
 
     def _action_launch(
-        self,
-        callback_id: str,
-        data_s: str,
-        profile_key: str
+        self, callback_id: str, data_s: str, profile_key: str
     ) -> defer.Deferred:
         d = self.launch_callback(
-            callback_id,
-            data_format.deserialise(data_s),
-            profile_key
+            callback_id, data_format.deserialise(data_s), profile_key
         )
         d.addCallback(data_format.serialise)
         return d
@@ -1499,7 +1541,7 @@
         self,
         callback_id: str,
         data: Optional[dict] = None,
-        profile_key: str = C.PROF_KEY_NONE
+        profile_key: str = C.PROF_KEY_NONE,
     ) -> defer.Deferred:
         """Launch a specific callback
 
@@ -1568,8 +1610,14 @@
         """
         return tuple((p.lower().strip() for p in path))
 
-    def import_menu(self, path, callback, security_limit=C.NO_SECURITY_LIMIT,
-                   help_string="", type_=C.MENU_GLOBAL):
+    def import_menu(
+        self,
+        path,
+        callback,
+        security_limit=C.NO_SECURITY_LIMIT,
+        help_string="",
+        type_=C.MENU_GLOBAL,
+    ):
         r"""register a new menu for frontends
 
         @param path(iterable[unicode]): path to go to the menu
@@ -1677,13 +1725,20 @@
 
         return ret
 
-    def _launch_menu(self, menu_type, path, data=None, security_limit=C.NO_SECURITY_LIMIT,
-                    profile_key=C.PROF_KEY_NONE):
+    def _launch_menu(
+        self,
+        menu_type,
+        path,
+        data=None,
+        security_limit=C.NO_SECURITY_LIMIT,
+        profile_key=C.PROF_KEY_NONE,
+    ):
         client = self.get_client(profile_key)
         return self.launch_menu(client, menu_type, path, data, security_limit)
 
-    def launch_menu(self, client, menu_type, path, data=None,
-        security_limit=C.NO_SECURITY_LIMIT):
+    def launch_menu(
+        self, client, menu_type, path, data=None, security_limit=C.NO_SECURITY_LIMIT
+    ):
         """launch action a menu action
 
         @param menu_type(unicode): type of menu to launch