core (disco), plugins identidy, XEP-0115:
- Fix data types, and use quotes data type to avoid immediate evaluation on Python < 3.14 - Better error catching folling change in `get_infos` in `memory.disco`. - Some code modernisation (async coroutine).
This commit is contained in:
parent
7c8fae5703
commit
8d42a09208
3 changed files with 57 additions and 32 deletions
|
|
@ -21,6 +21,7 @@ from collections.abc import Iterable
|
|||
from typing import cast
|
||||
|
||||
from twisted.internet.interfaces import IReactorCore
|
||||
from libervia.backend import G
|
||||
from libervia.backend.core.i18n import _
|
||||
from libervia.backend.core import exceptions
|
||||
from libervia.backend.core.log import getLogger
|
||||
|
|
@ -37,6 +38,8 @@ from libervia.backend.memory import persistent
|
|||
from tx_xmpp import disco
|
||||
import time
|
||||
|
||||
from libervia.backend.tools.utils import ensure_deferred
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
|
||||
|
|
@ -130,7 +133,10 @@ class Discovery:
|
|||
@param node: optional node to use for disco request
|
||||
@return: a Deferred which fire a boolean (True if feature is available)
|
||||
"""
|
||||
disco_infos = await self.get_infos(client, jid_, node)
|
||||
try:
|
||||
disco_infos = await self.get_infos(client, jid_, node)
|
||||
except (exceptions.ExternalRequestError, exceptions.TimeOutError):
|
||||
return False
|
||||
return feature in disco_infos.features
|
||||
|
||||
async def check_feature(
|
||||
|
|
@ -235,10 +241,12 @@ class Discovery:
|
|||
f"Cached disco failure for {jid_.full()}, retry in "
|
||||
f"{DISCO_RETRY_DELAY - int(elapsed)} seconds"
|
||||
)
|
||||
return defer.fail(exceptions.ExternalRequestError(
|
||||
f"Disco query failed for {jid_.full()}, retrying in "
|
||||
f"{DISCO_RETRY_DELAY} seconds"
|
||||
))
|
||||
return defer.fail(
|
||||
exceptions.ExternalRequestError(
|
||||
f"Disco query failed for {jid_.full()}, retrying in "
|
||||
f"{DISCO_RETRY_DELAY} seconds"
|
||||
)
|
||||
)
|
||||
# Retry delay expired, remove from cache and retry
|
||||
log.debug(f"Disco retry delay expired for {jid_.full()}, retrying")
|
||||
del self._jid_disco_cache[jid_]
|
||||
|
|
@ -286,14 +294,20 @@ class Discovery:
|
|||
disco_infos = self.hashes[cap_hash]
|
||||
return defer.succeed(disco_infos)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def get_items(self, client, jid_=None, node="", use_cache=True):
|
||||
"""get disco items from jid_, cache them for our own server
|
||||
async def get_items(
|
||||
self,
|
||||
client: SatXMPPEntity,
|
||||
jid_: jid.JID | None = None,
|
||||
node: str = "",
|
||||
use_cache: bool = True,
|
||||
) -> disco.DiscoItems:
|
||||
"""get disco items from jid_, cache them for our own server.
|
||||
|
||||
@param jid_(jid.JID): jid of the target, or None for profile's server
|
||||
@param node(unicode): optional node to use for disco request
|
||||
@param use_cache(bool): if True, use cached data if available
|
||||
@return: a Deferred which fire disco.DiscoItems
|
||||
@param client: client session
|
||||
@param jid_: jid of the target, or None for profile's server
|
||||
@param node: optional node to use for disco request
|
||||
@param use_cache: if True, use cached data if available
|
||||
@return: disco.DiscoItems
|
||||
"""
|
||||
# FIXME: RSM is not managed here
|
||||
if jid_ is None:
|
||||
|
|
@ -302,20 +316,20 @@ class Discovery:
|
|||
if jid_ == client.server_jid and not node:
|
||||
# we cache items only for our own server and if node is not set
|
||||
try:
|
||||
items = self.host.memory.entity_data_get(client, jid_, ["DISCO_ITEMS"])[
|
||||
"DISCO_ITEMS"
|
||||
]
|
||||
items = await self.host.memory.entity_data_get(
|
||||
client, jid_, ["DISCO_ITEMS"]
|
||||
)["DISCO_ITEMS"]
|
||||
log.debug("[%s] disco items are in cache" % jid_.full())
|
||||
if not use_cache:
|
||||
# we ignore cache, so we pretend we haven't found it
|
||||
raise KeyError
|
||||
except (KeyError, exceptions.UnknownEntityError):
|
||||
log.debug("Caching [%s] disco items" % jid_.full())
|
||||
items = yield client.disco.requestItems(jid_, nodeIdentifier=node)
|
||||
self.host.memory.update_entity_data(client, jid_, "DISCO_ITEMS", items)
|
||||
log.debug(f"Caching {jid_} disco items")
|
||||
items = await client.disco.requestItems(jid_, nodeIdentifier=node)
|
||||
G.host.memory.update_entity_data(client, jid_, "DISCO_ITEMS", items)
|
||||
else:
|
||||
try:
|
||||
items = yield client.disco.requestItems(jid_, nodeIdentifier=node)
|
||||
items = await client.disco.requestItems(jid_, nodeIdentifier=node)
|
||||
except StanzaError as e:
|
||||
log.warning(
|
||||
"Error while requesting items for {jid}: {reason}".format(
|
||||
|
|
@ -379,7 +393,6 @@ class Discovery:
|
|||
for item in items:
|
||||
info_d = self.get_infos(client, item.entity)
|
||||
|
||||
|
||||
info_d.addCallbacks(
|
||||
infos_cb, self._infos_eb, [item.entity], None, [item.entity]
|
||||
)
|
||||
|
|
@ -484,17 +497,22 @@ class Discovery:
|
|||
continue
|
||||
yield (item.entity.full(), item.nodeIdentifier or "", item.name or "")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _disco_items(
|
||||
self, entity_jid_s, node="", use_cache=True, profile_key=C.PROF_KEY_NONE
|
||||
):
|
||||
"""Discovery method for the bridge
|
||||
@ensure_deferred
|
||||
async def _disco_items(
|
||||
self,
|
||||
entity_jid_s: str,
|
||||
node: str = "",
|
||||
use_cache: bool = True,
|
||||
profile_key: str = C.PROF_KEY_NONE,
|
||||
) -> list[tuple[str, str, str]]:
|
||||
"""Discovery method for the bridge.
|
||||
|
||||
@param entity_jid_s: entity we want to discover
|
||||
@param node(unicode): optional node to use
|
||||
@param use_cache(bool): if True, use cached data if available
|
||||
@return: list of tuples"""
|
||||
@param node: optional node to use
|
||||
@param use_cache: if True, use cached data if available
|
||||
@return: list of (jid, node, name) tuples
|
||||
"""
|
||||
client = self.host.get_client(profile_key)
|
||||
entity = jid.JID(entity_jid_s)
|
||||
disco_items = yield self.get_items(client, entity, node, use_cache)
|
||||
disco_items = await self.get_items(client, entity, node, use_cache)
|
||||
return list(self.items2tuples(disco_items))
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ from typing import Any, Coroutine, Dict, List, Optional, Union, cast
|
|||
from twisted.internet import defer, reactor, threads
|
||||
from twisted.internet.interfaces import IReactorCore
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.words.protocols.jabber.error import StanzaError
|
||||
|
||||
from libervia.backend.core import exceptions
|
||||
from libervia.backend.core.constants import Const as C
|
||||
|
|
@ -750,6 +751,12 @@ class Identity:
|
|||
if entity is not None:
|
||||
try:
|
||||
disco_infos = await self.host.memory.disco.get_infos(client, entity)
|
||||
except (
|
||||
exceptions.TimeOutError,
|
||||
exceptions.ExternalRequestError,
|
||||
StanzaError,
|
||||
) as e:
|
||||
log.warning(f"Can't retrieve disco info for {entity}: {e}")
|
||||
except Exception as e:
|
||||
log.exception(f"Can't get disco infos for {entity}.")
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ from twisted.internet import defer, error
|
|||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.words.protocols.jabber.xmlstream import XMPPHandler
|
||||
from twisted.words.xish import domish
|
||||
from tx_xmpp import disco, itx_xmpp
|
||||
from tx_xmpp import data_form, disco, itx_xmpp
|
||||
from zope.interface import implementer
|
||||
|
||||
from libervia.backend import G
|
||||
|
|
@ -98,7 +98,7 @@ class XEP_0115:
|
|||
log.info(_("Plugin XEP_0115 initialization"))
|
||||
host.trigger.add("Presence send", self._presence_trigger)
|
||||
|
||||
def get_handler(self, client: SatXMPPEntity) -> XEP_0115_handler:
|
||||
def get_handler(self, client: SatXMPPEntity) -> "XEP_0115_handler":
|
||||
return XEP_0115_handler(self)
|
||||
|
||||
async def _prepare_caps(self, client: SatXMPPEntity) -> None:
|
||||
|
|
@ -426,7 +426,7 @@ class XEP_0115_handler(XMPPHandler):
|
|||
requestor: SatXMPPEntity,
|
||||
target: SatXMPPEntity,
|
||||
nodeIdentifier: str = "",
|
||||
) -> list[disco.DiscoFeature | disco.DiscoIdentity | disco.DiscoExtension]:
|
||||
) -> list[disco.DiscoFeature | disco.DiscoIdentity | data_form.Form]:
|
||||
"""
|
||||
Handle disco#info requests, including caps node queries.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue