component pubsub: Integrate XEP-0499 extended discovery:
- Added `on_extended_disco()` handler. - Added `with_parent=True` to all `get_pubsub_node()` calls to prevent lazy load errors in access checks. rel 476 Registered XEP-0499 handler in `profile_connecting()` and added it to plugin dependencies.
This commit is contained in:
parent
f1ceb7db8e
commit
c89b91c2e9
3 changed files with 116 additions and 11 deletions
|
|
@ -0,0 +1,26 @@
|
|||
"""add "max_items" to PubsubNode
|
||||
|
||||
Revision ID: f9ce59cfc13f
|
||||
Revises: ece2a6d7e4bb
|
||||
Create Date: 2026-04-11 12:29:56.062028
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'f9ce59cfc13f'
|
||||
down_revision = 'ece2a6d7e4bb'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
with op.batch_alter_table('pubsub_nodes', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('max_items', sa.Integer(), server_default=sa.text('0'), nullable=False))
|
||||
|
||||
|
||||
def downgrade():
|
||||
with op.batch_alter_table('pubsub_nodes', schema=None) as batch_op:
|
||||
batch_op.drop_column('max_items')
|
||||
|
|
@ -47,6 +47,13 @@ from libervia.backend.memory.sqla_mapping import (
|
|||
from libervia.backend.plugins.plugin_xep_0167 import NS_AV_CONFERENCES
|
||||
from libervia.backend.plugins.plugin_xep_0060 import NodeMetadata, XEP_0060
|
||||
from libervia.backend.plugins.plugin_xep_0496 import LINK_VAR, PARENT_VAR, XEP_0496
|
||||
from libervia.backend.plugins.plugin_xep_0499 import (
|
||||
DiscoPubsubItem,
|
||||
ExtDiscoOptions,
|
||||
ExtDiscoResult,
|
||||
DiscoPubsubNode,
|
||||
XEP_0499,
|
||||
)
|
||||
from libervia.backend.tools.config import ComponentSettings
|
||||
from libervia.backend.tools.xml_tools import element_copy
|
||||
from tx_xmpp.pubsub import NS_PUBSUB_EVENT
|
||||
|
|
@ -62,7 +69,7 @@ PLUGIN_INFO = {
|
|||
C.PI_MODES: [C.PLUG_MODE_COMPONENT],
|
||||
C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT,
|
||||
C.PI_PROTOCOLS: [],
|
||||
C.PI_DEPENDENCIES: ["XEP-0060", "XEP-0496"],
|
||||
C.PI_DEPENDENCIES: ["XEP-0060", "XEP-0496", "XEP-0499"],
|
||||
C.PI_RECOMMENDATIONS: [],
|
||||
C.PI_MAIN: "PubsubComponent",
|
||||
C.PI_HANDLER: C.BOOL_TRUE,
|
||||
|
|
@ -174,7 +181,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
def __init__(self, service: "PubsubService") -> None:
|
||||
super().__init__()
|
||||
self.service = service
|
||||
self.xep_0496 = cast(XEP_0496, service.client.host.plugins.get("XEP-0496"))
|
||||
self.xep_0496 = cast(XEP_0496, G.host.plugins["XEP-0496"])
|
||||
|
||||
@property
|
||||
def client(self) -> SatXMPPComponent:
|
||||
|
|
@ -285,7 +292,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
client,
|
||||
client.jid,
|
||||
request.nodeIdentifier,
|
||||
with_affiliations=True,
|
||||
with_affiliations=True, with_parent=True,
|
||||
with_subscriptions=True,
|
||||
)
|
||||
|
||||
|
|
@ -673,8 +680,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
client,
|
||||
client.jid,
|
||||
request.nodeIdentifier,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
with_affiliations=True, with_parent=True,
|
||||
with_link=True,
|
||||
)
|
||||
|
||||
|
|
@ -744,8 +750,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
client,
|
||||
client.jid,
|
||||
request.nodeIdentifier,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
with_affiliations=True, with_parent=True,
|
||||
with_link=True,
|
||||
)
|
||||
|
||||
|
|
@ -904,7 +909,11 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
assert request.nodeIdentifier is not None
|
||||
|
||||
node = await G.storage.get_pubsub_node(
|
||||
client, client.jid, request.nodeIdentifier, with_affiliations=True
|
||||
client,
|
||||
client.jid,
|
||||
request.nodeIdentifier,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
)
|
||||
|
||||
if node is None:
|
||||
|
|
@ -959,6 +968,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
client.jid,
|
||||
request.nodeIdentifier,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
with_subscriptions=True,
|
||||
)
|
||||
|
||||
|
|
@ -1030,6 +1040,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
client.jid,
|
||||
request.nodeIdentifier,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
with_subscriptions=True,
|
||||
)
|
||||
|
||||
|
|
@ -1073,6 +1084,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
client.jid,
|
||||
request.nodeIdentifier,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
with_subscriptions=True,
|
||||
)
|
||||
|
||||
|
|
@ -1126,6 +1138,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
client.jid,
|
||||
node_name,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
with_subscriptions=True,
|
||||
)
|
||||
if fetched_node:
|
||||
|
|
@ -1297,6 +1310,7 @@ class PubsubResource(pubsub.PubSubResource):
|
|||
request.nodeIdentifier,
|
||||
with_subscriptions=True,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
)
|
||||
|
||||
if node is None:
|
||||
|
|
@ -1561,6 +1575,71 @@ class PubsubService(rsm.PubSubService):
|
|||
def client(self) -> SatXMPPComponent:
|
||||
return self.component.client
|
||||
|
||||
async def on_extended_disco(
|
||||
self,
|
||||
client: SatXMPPComponent,
|
||||
iq_elt: domish.Element,
|
||||
ext_disco_options: ExtDiscoOptions,
|
||||
) -> ExtDiscoResult:
|
||||
"""Handle pubsub extended disco requests."""
|
||||
query_elt = iq_elt.query
|
||||
assert query_elt is not None
|
||||
node_name = query_elt.getAttribute("node")
|
||||
|
||||
requestor_jid = client.jid
|
||||
|
||||
nodes = await G.storage.get_pubsub_nodes(
|
||||
client,
|
||||
service=client.jid,
|
||||
node_name=node_name,
|
||||
linked_node=ext_disco_options.linked_nodes,
|
||||
depth=ext_disco_options.depth,
|
||||
with_items="items" in ext_disco_options.type,
|
||||
with_affiliations=True,
|
||||
with_parent=True,
|
||||
with_link=True,
|
||||
)
|
||||
|
||||
result_items: list[DiscoPubsubNode | DiscoPubsubItem] = []
|
||||
|
||||
for node in nodes:
|
||||
if ext_disco_options.depth == 0:
|
||||
disco_node = DiscoPubsubNode.from_sqlalchemy(node, client.jid)
|
||||
if "items" in ext_disco_options.type:
|
||||
try:
|
||||
disco_node.items = [
|
||||
DiscoPubsubItem.from_sqlalchemy(item, node.name, client.jid)
|
||||
for item in node.items
|
||||
]
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
disco_node = DiscoPubsubNode.from_sqlalchemy_full_hierarchy(
|
||||
node, client.jid
|
||||
)
|
||||
|
||||
filtered_node = (
|
||||
await self.component.ext_disco.filter_node_hierarchy_by_access(
|
||||
client,
|
||||
client.jid,
|
||||
disco_node,
|
||||
requestor_jid,
|
||||
depth=ext_disco_options.depth,
|
||||
linked_nodes=ext_disco_options.linked_nodes,
|
||||
)
|
||||
)
|
||||
if filtered_node is None:
|
||||
continue
|
||||
|
||||
if "nodes" in ext_disco_options.type:
|
||||
result_items.append(filtered_node)
|
||||
|
||||
if "items" in ext_disco_options.type and filtered_node.items:
|
||||
result_items.extend(filtered_node.items)
|
||||
filtered_node.items = None
|
||||
|
||||
return ExtDiscoResult(result_items)
|
||||
|
||||
|
||||
class PubsubComponent:
|
||||
IMPORT_NAME = IMPORT_NAME
|
||||
|
|
@ -1569,6 +1648,7 @@ class PubsubComponent:
|
|||
def __init__(self, host):
|
||||
self._clientt: SatXMPPComponent | None = None
|
||||
self.pubsub_service = PubsubService(self)
|
||||
self.ext_disco = cast(XEP_0499, host.plugins.get("XEP-0499"))
|
||||
|
||||
@property
|
||||
def client(self) -> SatXMPPComponent:
|
||||
|
|
@ -1580,6 +1660,7 @@ class PubsubComponent:
|
|||
|
||||
def profile_connecting(self, client: SatXMPPEntity) -> None:
|
||||
self._client = cast(SatXMPPComponent, client)
|
||||
self.ext_disco.register_handler(self.pubsub_service.on_extended_disco)
|
||||
|
||||
|
||||
@implementer(itx_xmpp.IDisco)
|
||||
|
|
|
|||
|
|
@ -53,9 +53,7 @@ PLUGIN_INFO = {
|
|||
C.PI_TYPE: "XEP",
|
||||
C.PI_MODES: C.PLUG_MODE_BOTH,
|
||||
C.PI_PROTOCOLS: ["XEP-0499"],
|
||||
C.PI_DEPENDENCIES: [
|
||||
"XEP-0060", "XEP-0496"
|
||||
],
|
||||
C.PI_DEPENDENCIES: ["XEP-0060", "XEP-0496"],
|
||||
C.PI_RECOMMENDATIONS: [],
|
||||
C.PI_MAIN: "XEP_0499",
|
||||
C.PI_HANDLER: "yes",
|
||||
|
|
|
|||
Loading…
Reference in a new issue