Mercurial > libervia-backend
changeset 4393:49aa73c8fc30
component email gateway: implement pubsub relationships and pubsub extended discovery:
- Pubsub relationships are used to set node hierarchy (comments nodes are set as children of
corresponding pubsub nodes).
- XEP-0499 Extended Pubsub Discovery is used to return hierarchy of pubsub nodes and
items.
rel 463
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 31 Aug 2025 12:34:37 +0200 |
parents | dcda916f16f6 |
children | e28cd3454c60 |
files | libervia/backend/plugins/plugin_comp_email_gateway/__init__.py libervia/backend/plugins/plugin_comp_email_gateway/pubsub_service.py |
diffstat | 2 files changed, 48 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libervia/backend/plugins/plugin_comp_email_gateway/__init__.py Sun Aug 31 12:34:30 2025 +0200 +++ b/libervia/backend/plugins/plugin_comp_email_gateway/__init__.py Sun Aug 31 12:34:37 2025 +0200 @@ -72,6 +72,7 @@ from libervia.backend.plugins.plugin_xep_0277 import Comment, MbData, XEP_0277 from libervia.backend.plugins.plugin_xep_0373 import binary_to_ascii_armor from libervia.backend.plugins.plugin_xep_0498 import XEP_0498 +from libervia.backend.plugins.plugin_xep_0499 import XEP_0499, ExtDiscoOptions from libervia.backend.tools.common import date_utils, regex, uri from libervia.backend.tools.utils import aio @@ -94,7 +95,7 @@ C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT, C.PI_PROTOCOLS: [], C.PI_DEPENDENCIES: [ - "XEP-0033", "XEP-0077", "XEP-0106", "XEP-0277", "XEP-0498", "GRE", "GRE-MIME", + "XEP-0033", "XEP-0077", "XEP-0106", "XEP-0277", "XEP-0498", "XEP-0499", "GRE", "GRE-MIME", "GRE-OpenPGP", "PUBSUB_CACHE", "TEXT_SYNTAXES" ], C.PI_RECOMMENDATIONS: [], @@ -146,6 +147,7 @@ self._shim = cast(XEP_0131, host.plugins["XEP-0131"]) self._mb = cast(XEP_0277, host.plugins["XEP-0277"]) self._pfs = cast(XEP_0498, host.plugins["XEP-0498"]) + self._ext_disco = cast(XEP_0499, host.plugins["XEP-0499"]) self._gre = cast(GRE, host.plugins["GRE"]) self._syntax = cast(TextSyntaxes, host.plugins["TEXT_SYNTAXES"]) # TODO: For the moment, all credentials are kept in cache; we should only keep the @@ -1284,6 +1286,7 @@ entity = user_jid, affiliation = Affiliation.owner )], + "parent_node": root_node }, ) else:
--- a/libervia/backend/plugins/plugin_comp_email_gateway/pubsub_service.py Sun Aug 31 12:34:30 2025 +0200 +++ b/libervia/backend/plugins/plugin_comp_email_gateway/pubsub_service.py Sun Aug 31 12:34:37 2025 +0200 @@ -31,6 +31,7 @@ from libervia.backend.memory.sqla_mapping import AccessModel, Affiliation from libervia.backend.plugins.plugin_pubsub_cache import PubsubCache from libervia.backend.plugins.plugin_xep_0498 import NodeData +from libervia.backend.plugins.plugin_xep_0499 import ExtDiscoOptions, ExtDiscoResult, DiscoPubsubItem, DiscoPubsubNode from libervia.backend.tools.utils import ensure_deferred if TYPE_CHECKING: from . import EmailGatewayComponent @@ -220,6 +221,7 @@ def __init__(self, gateway: "EmailGatewayComponent"): self.gateway = gateway self._pfs = gateway._pfs + gateway._ext_disco.register_handler(self.on_extended_disco) resource = EmailGWPubsubResource(self) super().__init__(resource) self.host = gateway.host @@ -229,6 +231,48 @@ "name": "Libervia Email Gateway", } + @property + def client(self) -> SatXMPPComponent: + client = self.gateway.client + assert client is not None + return client + + async def on_extended_disco( + self, + client: SatXMPPComponent, + iq_elt: domish.Element, + ext_disco_options: ExtDiscoOptions + ) -> ExtDiscoResult: + """Handle pubsub extended disco""" + query_elt = iq_elt.query + assert query_elt is not None + node = query_elt.getAttribute("node") + if not "nodes" in ext_disco_options.type: + raise NotImplementedError("Returning items only is not yet supported.") + depth = ext_disco_options.depth + nodes = await G.storage.get_pubsub_nodes( + client, + service=client.jid, + node_name = node, + linked_node=ext_disco_options.linked_nodes, + depth=depth, + with_items="items" in ext_disco_options.type + ) + + if depth == 0: + # If depth == 0, we don't want to use `from_sqlalchemy_full_hierarchy` to + # avoid returning children, and because children `parent` and `child_nodes` + # fields are not loaded. + return ExtDiscoResult([ + DiscoPubsubNode.from_sqlalchemy(node, self.client.jid) + for node in nodes + ]) + else: + return ExtDiscoResult([ + DiscoPubsubNode.from_sqlalchemy_full_hierarchy(node, self.client.jid) + for node in nodes + ]) + @ensure_deferred async def getDiscoInfo( self, requestor: jid.JID, target: jid.JID, nodeIdentifier: str = ""