ForcePilot/backend/package/yuxi/channels/adapters/matrix/config_patch.py
Kris 2063145ce1 feat(matrix): 新增完整的Matrix适配器工具集
新增了20+个Matrix相关工具模块,包含线程处理、自动加入、消息去重、配置管理、安全策略、媒体处理、命令解析等功能,完善Matrix适配器基础能力
2026-05-12 00:45:54 +08:00

113 lines
3.3 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
@dataclass
class MatrixAccountPatch:
user_id: str | None = None
display_name: str | None = None
avatar_url: str | None = None
homeserver: str | None = None
access_token: str | None = None
device_id: str | None = None
dm_policy: str | None = None
group_policy: str | None = None
allow_bots: bool | None = None
auto_join: str | None = None
sync_timeout_ms: int | None = None
loop_sleep_ms: int | None = None
probe_timeout_s: float | None = None
response_prefix: str | None = None
require_mention: bool | None = None
chunk_mode: str | None = None
media_max_mb: int | None = None
crypto_store_dir: str | None = None
rooms: dict[str, Any] | None = None
dm_allow_from: list[str] | None = None
group_allow_from: list[str] | None = None
extra: dict[str, Any] = field(default_factory=dict)
_KNOWN_FIELDS = frozenset(
{
"user_id",
"display_name",
"avatar_url",
"homeserver",
"access_token",
"device_id",
"dm_policy",
"group_policy",
"allow_bots",
"auto_join",
"sync_timeout_ms",
"loop_sleep_ms",
"probe_timeout_s",
"response_prefix",
"require_mention",
"chunk_mode",
"media_max_mb",
"crypto_store_dir",
"rooms",
"dm_allow_from",
"group_allow_from",
}
)
def to_dict(self) -> dict[str, Any]:
result: dict[str, Any] = {}
for name in self._KNOWN_FIELDS:
value = getattr(self, name)
if value is not None:
result[name] = value
result.update(self.extra)
return result
@classmethod
def from_dict(cls, data: dict[str, Any]) -> MatrixAccountPatch:
known: dict[str, Any] = {}
extra: dict[str, Any] = {}
for k, v in data.items():
if k in cls._KNOWN_FIELDS:
known[k] = v
else:
extra[k] = v
return cls(**known, extra=extra)
@property
def has_changes(self) -> bool:
return any(getattr(self, name) is not None for name in self._KNOWN_FIELDS) or bool(self.extra)
def apply_patch(config: dict[str, Any], patch: MatrixAccountPatch) -> dict[str, Any]:
result = dict(config)
fields = patch.to_dict()
for key, value in fields.items():
if key in ("rooms", "dm_allow_from", "group_allow_from"):
if isinstance(value, (list, dict)):
result[key] = value
else:
result[key] = value
return result
def merge_patches(base: MatrixAccountPatch, overlay: MatrixAccountPatch) -> MatrixAccountPatch:
base_dict = base.to_dict()
overlay_dict = overlay.to_dict()
base_dict.update(overlay_dict)
return MatrixAccountPatch.from_dict(base_dict)
def diff_config(old: dict[str, Any], new: dict[str, Any]) -> dict[str, tuple[Any, Any]]:
all_keys = set(old.keys()) | set(new.keys())
diff: dict[str, tuple[Any, Any]] = {}
for key in all_keys:
old_val = old.get(key)
new_val = new.get(key)
if old_val != new_val:
diff[key] = (old_val, new_val)
return diff