changeset 4035:9c76678a39e2

cli (info/disco): Add external services in results: rel 418
author Goffi <goffi@goffi.org>
date Fri, 07 Apr 2023 15:18:05 +0200
parents 9496f28dadff
children c4464d7ae97b
files sat_frontends/jp/cmd_info.py
diffstat 1 files changed, 130 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/sat_frontends/jp/cmd_info.py	Fri Apr 07 15:17:24 2023 +0200
+++ b/sat_frontends/jp/cmd_info.py	Fri Apr 07 15:18:05 2023 +0200
@@ -17,12 +17,15 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from . import base
+from pprint import pformat
+
 from sat.core.i18n import _
+from sat.tools.common import data_format, date_utils
 from sat.tools.common.ansi import ANSI as A
-from sat.tools.common import date_utils, data_format
+from sat_frontends.jp import common
 from sat_frontends.jp.constants import Const as C
-from sat_frontends.jp import common
+
+from . import base
 
 __commands__ = ["Info"]
 
@@ -44,8 +47,8 @@
             "-t",
             "--type",
             type=str,
-            choices=("infos", "items", "both"),
-            default="both",
+            choices=("infos", "items", "both", "external", "all"),
+            default="all",
             help=_("type of data to discover"),
         )
         self.parser.add_argument("-n", "--node", default="", help=_("node to use"))
@@ -62,6 +65,7 @@
         identities = data.get("identities", [])
         extensions = data.get("extensions", {})
         items = data.get("items", [])
+        external = data.get("external", [])
 
         identities_table = common.Table(
             self.host,
@@ -112,6 +116,7 @@
         )
 
         template = []
+        fmt_kwargs = {}
         if features:
             template.append(A.color(C.A_HEADER, _("Features")) + "\n\n{features}")
         if identities:
@@ -120,6 +125,81 @@
             template.append(A.color(C.A_HEADER, _("Extensions")) + "\n\n{extensions}")
         if items:
             template.append(A.color(C.A_HEADER, _("Items")) + "\n\n{items}")
+        if external:
+            fmt_lines = []
+            for e in external:
+                data = {k: e[k] for k in sorted(e)}
+                host = data.pop("host")
+                type_ = data.pop("type")
+                fmt_lines.append(A.color(
+                    "\t",
+                    C.A_SUBHEADER,
+                    host,
+                    " ",
+                    A.RESET,
+                    "[",
+                    C.A_LEVEL_COLORS[1],
+                    type_,
+                    A.RESET,
+                    "]",
+                ))
+                extended = data.pop("extended", None)
+                for key, value in data.items():
+                    fmt_lines.append(A.color(
+                        "\t\t",
+                        C.A_LEVEL_COLORS[2],
+                        f"{key}: ",
+                        C.A_LEVEL_COLORS[3],
+                        str(value)
+                    ))
+                if extended:
+                    fmt_lines.append(A.color(
+                        "\t\t",
+                        C.A_HEADER,
+                        "extended",
+                    ))
+                    nb_extended = len(extended)
+                    for idx, form_data in enumerate(extended):
+                        namespace = form_data.get("namespace")
+                        if namespace:
+                            fmt_lines.append(A.color(
+                                "\t\t",
+                                C.A_LEVEL_COLORS[2],
+                                "namespace: ",
+                                C.A_LEVEL_COLORS[3],
+                                A.BOLD,
+                                namespace
+                            ))
+                        for field_data in form_data["fields"]:
+                            name = field_data.get("name")
+                            if not name:
+                                continue
+                            field_type = field_data.get("type")
+                            if "multi" in field_type:
+                                value = ", ".join(field_data.get("values") or [])
+                            else:
+                                value = field_data.get("value")
+                                if value is None:
+                                    continue
+                                if field_type == "boolean":
+                                    value = C.bool(value)
+                            fmt_lines.append(A.color(
+                                "\t\t",
+                                C.A_LEVEL_COLORS[2],
+                                f"{name}: ",
+                                C.A_LEVEL_COLORS[3],
+                                A.BOLD,
+                                str(value)
+                            ))
+                        if nb_extended>1 and idx < nb_extended-1:
+                            fmt_lines.append("\n")
+
+                fmt_lines.append("\n")
+
+            template.append(
+                A.color(C.A_HEADER, _("External")) + "\n\n{external_formatted}"
+            )
+            fmt_kwargs["external_formatted"] = "\n".join(fmt_lines)
 
         print(
             "\n\n".join(template).format(
@@ -127,19 +207,28 @@
                 identities=identities_table.display().string,
                 extensions="\n".join(extensions_tpl),
                 items=items_table.display().string,
+                **fmt_kwargs,
             )
         )
 
     async def start(self):
-        infos_requested = self.args.type in ("infos", "both")
-        items_requested = self.args.type in ("items", "both")
+        infos_requested = self.args.type in ("infos", "both", "all")
+        items_requested = self.args.type in ("items", "both", "all")
+        exter_requested = self.args.type in ("external", "all")
+        if self.args.node:
+            if self.args.type == "external":
+                self.parser.error(
+                    '--node can\'t be used with discovery of external services '
+                    '(--type="external")'
+                )
+            else:
+                exter_requested = False
         jids = await self.host.check_jids([self.args.jid])
         jid = jids[0]
+        data = {}
 
         # infos
-        if not infos_requested:
-            infos = None
-        else:
+        if infos_requested:
             try:
                 infos = await self.host.bridge.discoInfos(
                     jid,
@@ -151,10 +240,16 @@
                 self.disp(_("error while doing discovery: {e}").format(e=e), error=True)
                 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
 
-                # items
-        if not items_requested:
-            items = None
-        else:
+            else:
+                features, identities, extensions = infos
+                features.sort()
+                identities.sort(key=lambda identity: identity[2])
+                data.update(
+                    {"features": features, "identities": identities, "extensions": extensions}
+                )
+
+        # items
+        if items_requested:
             try:
                 items = await self.host.bridge.discoItems(
                     jid,
@@ -165,22 +260,29 @@
             except Exception as e:
                 self.disp(_("error while doing discovery: {e}").format(e=e), error=True)
                 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
-
-                # output
-        data = {}
+            else:
+                items.sort(key=lambda item: item[2])
+                data["items"] = items
 
-        if infos_requested:
-            features, identities, extensions = infos
-            features.sort()
-            identities.sort(key=lambda identity: identity[2])
-            data.update(
-                {"features": features, "identities": identities, "extensions": extensions}
-            )
+        # external
+        if exter_requested:
+            try:
+                ext_services_s = await self.host.bridge.external_disco_get(
+                    jid,
+                    self.host.profile,
+                )
+            except Exception as e:
+                self.disp(
+                    _("error while doing external service discovery: {e}").format(e=e),
+                    error=True
+                )
+                self.host.quit(C.EXIT_BRIDGE_ERRBACK)
+            else:
+                data["external"] = data_format.deserialise(
+                    ext_services_s, type_check=list
+                )
 
-        if items_requested:
-            items.sort(key=lambda item: item[2])
-            data["items"] = items
-
+        # output
         await self.output(data)
         self.host.quit()