diff libervia/web/server/resources.py @ 1609:f3305832f3f6

server (resources): handle external Libervia apps by adding them to menu without using a Proxy: When an external Libervia app is used, a link is added to the menu, and clicking on it will open the app in an blank page instead of embedding it with a Proxy.
author Goffi <goffi@goffi.org>
date Fri, 31 May 2024 11:10:04 +0200
parents eb00d593801d
children 5d9889f14012
line wrap: on
line diff
--- a/libervia/web/server/resources.py	Fri May 31 11:10:02 2024 +0200
+++ b/libervia/web/server/resources.py	Fri May 31 11:10:04 2024 +0200
@@ -27,6 +27,7 @@
 from twisted.web import server
 from twisted.web import static
 from twisted.web import resource as web_resource
+from twisted.web.util import Redirect
 
 from libervia.web.server.constants import Const as C
 from libervia.web.server.utils import quote
@@ -210,7 +211,13 @@
         exposed_data = self.libervia_apps[app_name] = data_format.deserialise(
             await self.host.bridge_call("application_exposed_get", app_name, "", "")
         )
-
+        external = exposed_data.get("web_external", False)
+        if external:
+            log.info(
+                f"App {app_name!r} (instance {instance_id!r}) has been started."
+            )
+            # we don't add any resource of proxy for external apps.
+            return
         try:
             web_port = int(exposed_data['ports']['web'].split(':')[1])
         except (KeyError, ValueError):
@@ -237,8 +244,9 @@
             url_prefix.encode()
         )
         self.add_resource_to_path(url_prefix, res)
+
         log.info(
-            f"Resource for app {app_name!r} (instance {instance_id!r}) has been added"
+            f"Resource for app {app_name!r} (instance {instance_id!r}) has been added."
         )
 
     async def _init_redirections(self, options):
@@ -485,20 +493,33 @@
                 app_name = menu[13:].strip().lower()
                 app_data = await self._start_app(app_name)
                 exposed_data = app_data["expose"]
-                front_url = exposed_data['front_url']
-                options = self.host.options
-                url_redirections = options["url_redirections_dict"].setdefault(
-                    self.site_name, {}
-                )
-                if front_url in url_redirections:
-                    raise exceptions.ConflictError(
-                        f"There is already a redirection from {front_url!r}, can't add "
-                        f"{app_name!r}")
+                external = exposed_data.get("web_external", False)
+                if external:
+                    # The app is opened separately and not embedded into the Web frontend.
+                    try:
+                        front_url = exposed_data["front_url"]
+                    except KeyError:
+                        raise exceptions.DataError(
+                            'Missing "front_url" in app data for external app '
+                            f'{app_name!r}, it is mandatory when "external" is set. This '
+                            f'must be set in {app_name!r} app configuration file.'
 
-                url_redirections[front_url] = {
-                    "page": 'embed_app',
-                    "path_args": [app_name]
-                }
+                        )
+                else:
+                    front_url = exposed_data['web_url_path']
+                    options = self.host.options
+                    url_redirections = options["url_redirections_dict"].setdefault(
+                        self.site_name, {}
+                    )
+                    if front_url in url_redirections:
+                        raise exceptions.ConflictError(
+                            f"There is already a redirection from {front_url!r}, can't add "
+                            f"{app_name!r}")
+
+                    url_redirections[front_url] = {
+                        "page": 'embed_app',
+                        "path_args": [app_name]
+                    }
 
                 page_name = exposed_data.get('web_label', app_name).title()
                 url = front_url