core (xmpp, core_type): SatXMPPEntity can now handle plugin data:

2 new methods `get_plugin_data` and `set_plugin_data` let plugin register data for a given
profile session (i.e. client instance). This is the clean way to handle plugin data
(instead of the former way of adding custom attribute to `client` instance), and it uses
generics so type hints are working correctly with linters.
This commit is contained in:
Goffi 2026-02-23 13:07:53 +01:00
commit ad409de6a5
2 changed files with 35 additions and 1 deletions

View file

@ -18,7 +18,8 @@
from abc import ABC, abstractmethod
from collections import namedtuple
from typing import TYPE_CHECKING, Any
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Type, TypeVar
from twisted.internet import defer
from twisted.python import failure
from typing_extensions import TypedDict
@ -38,6 +39,9 @@ if TYPE_CHECKING:
from txtorcon import Tor
D = TypeVar("D")
EncryptionPlugin = namedtuple(
"EncryptionPlugin", ("instance", "name", "namespace", "priority", "directed")
)
@ -87,11 +91,40 @@ class SatXMPPEntity(ABC):
xmlstream: xmlstream.XmlStream
tor: "Tor | None" = None
def __init__(self) -> None:
self.plugin_data: dict[str, Any] = {}
@property
def tor_mode(self) -> "TorMode":
"""Return Tor mode for this profile."""
raise NotImplementedError
def get_plugin_data(self, import_name: str, plugin_data_model: Type[D]) -> D:
"""Retrieve data for a plugin.
Those data are per profile session (i.e. client instance).
If there is no data for this plugin in this instance, it will be created with not
arguments, which means that the model must have default value for every field.
If it's not the case, use "set_plugin_data" before the first call of
"get_plugin_data".
"""
try:
data = self.plugin_data[import_name]
except KeyError:
data = self.plugin_data[import_name] = plugin_data_model()
return data
def set_plugin_data(self, import_name: str, plugin_data: object) -> None:
"""Set plugin data.
This will store plugin data in current client instance.
"""
if import_name in self.plugin_data:
raise exceptions.ConfigError("Plugin data already stored in {import_name!r}")
self.plugin_data[import_name] = plugin_data
@property
@abstractmethod
def treq(self) -> "HTTPClient":

View file

@ -113,6 +113,7 @@ class SatXMPPEntity(core_types.SatXMPPEntity):
profiles_connecting = set()
def __init__(self, host_app, profile, max_retries):
core_types.SatXMPPEntity.__init__(self)
factory = self.factory
# we monkey patch clientConnectionLost to handle network_enabled/network_disabled