From 60ee621221826f725a87d23c83748a18282b5029 Mon Sep 17 00:00:00 2001 From: Guillaume De Saint Martin Date: Sat, 4 Jul 2026 10:17:54 +0200 Subject: [PATCH] [Node] improve node distribution UI --- .../node_web_interface/metadata.json | 2 +- .../distributions/node/__init__.py | 2 + .../distributions/node/dashboard.py | 8 ++- .../web_interface/models/__init__.py | 4 ++ .../models/distributions/__init__.py | 7 ++ .../models/distributions/node/__init__.py | 27 +++++++ .../distributions/node/configuration.py | 42 +++++++++++ .../distributions/node/dashboard.html | 32 ++++++++- .../templates/distributions/node/navbar.html | 7 +- .../tests/distributions/test_node.py | 50 +++++++++++++ .../tests/test_node_configuration_models.py | 72 +++++++++++++++++++ 11 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/__init__.py create mode 100644 packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/configuration.py create mode 100644 packages/tentacles/Services/Interfaces/web_interface/tests/distributions/test_node.py create mode 100644 packages/tentacles/Services/Interfaces/web_interface/tests/test_node_configuration_models.py diff --git a/packages/tentacles/Services/Interfaces/node_web_interface/metadata.json b/packages/tentacles/Services/Interfaces/node_web_interface/metadata.json index 2a7aa6b460..534e567eda 100644 --- a/packages/tentacles/Services/Interfaces/node_web_interface/metadata.json +++ b/packages/tentacles/Services/Interfaces/node_web_interface/metadata.json @@ -3,6 +3,6 @@ "origin_package": "OctoBot-Default-Tentacles", "tentacles": ["NodeWebInterface"], "tentacles-requirements": ["node_api_interface"], - "build": ["npm install", "npm run generate-client", "npm run build"], + "build": ["npm install", "npm run generate-client"], "include": ["dist/**/*", "node_web_interface.py"] } diff --git a/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/__init__.py b/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/__init__.py index 5cedd2b1ac..1860603e69 100644 --- a/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/__init__.py +++ b/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/__init__.py @@ -13,10 +13,12 @@ # # You should have received a copy of the GNU Lesser General Public # License along with this library. +import tentacles.Services.Interfaces.web_interface.controllers.logs import tentacles.Services.Interfaces.web_interface.controllers.distributions.node.dashboard def register(blueprint): + tentacles.Services.Interfaces.web_interface.controllers.logs.register(blueprint) tentacles.Services.Interfaces.web_interface.controllers.distributions.node.dashboard.register(blueprint) diff --git a/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/dashboard.py b/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/dashboard.py index 52b791b326..97dbd5e024 100644 --- a/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/dashboard.py +++ b/packages/tentacles/Services/Interfaces/web_interface/controllers/distributions/node/dashboard.py @@ -25,7 +25,13 @@ def register(blueprint): @login.login_required_when_activated def home(): if models.accepted_terms(): - return flask.render_template("distributions/node/dashboard.html") + node_local_ip, node_local_port = models.get_node_local_endpoint() + return flask.render_template( + "distributions/node/dashboard.html", + node_web_ui_url=models.get_node_web_ui_url(), + node_local_ip=node_local_ip, + node_local_port=node_local_port, + ) return flask.redirect(flask.url_for("terms")) @blueprint.route("/welcome") diff --git a/packages/tentacles/Services/Interfaces/web_interface/models/__init__.py b/packages/tentacles/Services/Interfaces/web_interface/models/__init__.py index 72a2354d48..05f620be02 100644 --- a/packages/tentacles/Services/Interfaces/web_interface/models/__init__.py +++ b/packages/tentacles/Services/Interfaces/web_interface/models/__init__.py @@ -291,6 +291,8 @@ from tentacles.Services.Interfaces.web_interface.models.distributions import ( save_market_making_configuration, get_market_making_services, + get_node_local_endpoint, + get_node_web_ui_url, ) @@ -513,5 +515,7 @@ "WebInterfaceTab", "save_market_making_configuration", "get_market_making_services", + "get_node_local_endpoint", + "get_node_web_ui_url", "get_dsl_keywords_docs", ] diff --git a/packages/tentacles/Services/Interfaces/web_interface/models/distributions/__init__.py b/packages/tentacles/Services/Interfaces/web_interface/models/distributions/__init__.py index e0b4f6a83f..9720d459b2 100644 --- a/packages/tentacles/Services/Interfaces/web_interface/models/distributions/__init__.py +++ b/packages/tentacles/Services/Interfaces/web_interface/models/distributions/__init__.py @@ -15,12 +15,17 @@ # License along with this library. from tentacles.Services.Interfaces.web_interface.models.distributions import market_making +from tentacles.Services.Interfaces.web_interface.models.distributions import node from tentacles.Services.Interfaces.web_interface.models.distributions import prediction_market from tentacles.Services.Interfaces.web_interface.models.distributions.market_making import ( save_market_making_configuration, get_market_making_services, ) +from tentacles.Services.Interfaces.web_interface.models.distributions.node import ( + get_node_local_endpoint, + get_node_web_ui_url, +) from tentacles.Services.Interfaces.web_interface.models.distributions.prediction_market import ( save_prediction_market_configuration, get_prediction_market_services, @@ -29,6 +34,8 @@ __all__ = [ "save_market_making_configuration", "get_market_making_services", + "get_node_local_endpoint", + "get_node_web_ui_url", "save_prediction_market_configuration", "get_prediction_market_services", ] diff --git a/packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/__init__.py b/packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/__init__.py new file mode 100644 index 0000000000..55db848de0 --- /dev/null +++ b/packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/__init__.py @@ -0,0 +1,27 @@ +# Drakkar-Software OctoBot-Interfaces +# Copyright (c) Drakkar-Software, All rights reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3.0 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. + +import tentacles.Services.Interfaces.web_interface.models.distributions.node.configuration + +from tentacles.Services.Interfaces.web_interface.models.distributions.node.configuration import ( + get_node_local_endpoint, + get_node_web_ui_url, +) + +__all__ = [ + "get_node_local_endpoint", + "get_node_web_ui_url", +] diff --git a/packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/configuration.py b/packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/configuration.py new file mode 100644 index 0000000000..2049219e0e --- /dev/null +++ b/packages/tentacles/Services/Interfaces/web_interface/models/distributions/node/configuration.py @@ -0,0 +1,42 @@ +# Drakkar-Software OctoBot-Interfaces +# Copyright (c) Drakkar-Software, All rights reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3.0 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. +import os +import socket +import typing + +import octobot_services.constants as services_constants +import tentacles.Services.Services_bases as Service_bases + + +def get_node_web_ui_url() -> typing.Optional[str]: + node_api_service = Service_bases.NodeApiService.instance() + if not Service_bases.NodeApiService.get_is_enabled(node_api_service.config): + return None + return f"{node_api_service.get_node_api_url().rstrip('/')}/app" + + +def get_node_local_endpoint() -> tuple[str, int]: + node_api_service = Service_bases.NodeApiService.instance() + port = node_api_service.get_bind_port() + bind_address = os.getenv(services_constants.ENV_NODE_API_ADDRESS) + if bind_address and bind_address not in ("0.0.0.0", "127.0.0.1"): + local_ip = bind_address + else: + try: + local_ip = socket.gethostbyname(socket.gethostname()) + except OSError: + local_ip = "127.0.0.1" + return local_ip, port diff --git a/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/dashboard.html b/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/dashboard.html index a610ca15b4..10022e5c90 100644 --- a/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/dashboard.html +++ b/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/dashboard.html @@ -8,8 +8,36 @@

OctoBot Node

-

Node is running.

- +

OctoBot Node is running.

+ +

+ In node mode, OctoBot should be configured and used from the + OctoBot Cloud UI. +

+ + Open OctoBot Cloud UI + + +
+ +
Node connection
+

Use this local endpoint when registering your node:

+

IP: {{ node_local_ip }}

+

Port: {{ node_local_port }}

+

+ If your node is reachable from the internet, use your public IP and port instead when registering it in the OctoBot Cloud UI. +

+ +
+ +
Local Node Admin
+ {% if node_web_ui_url %} + + Open Node Admin + + {% else %} +

Enable the Node API service to access the Node UI.

+ {% endif %}
{% endblock %} diff --git a/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/navbar.html b/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/navbar.html index 7aced756aa..36a7369eb5 100644 --- a/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/navbar.html +++ b/packages/tentacles/Services/Interfaces/web_interface/templates/distributions/node/navbar.html @@ -21,7 +21,12 @@