from __future__ import annotations import logging import os logger = logging.getLogger(__name__) class ZulipConfigAdapter: def __init__(self): self._config: dict = {} def list_account_ids(self, config: dict) -> list[str]: self._config = config accounts = config.get("channels", {}).get("zulip", {}).get("accounts", []) if not accounts: return ["default"] if self._env_configured("default") else [] return [a.get("account_id", "default") for a in accounts] async def resolve_account(self, account_id: str) -> dict: raw = self._load_config(account_id) return self._build_account(account_id, raw) def _load_config(self, account_id: str) -> dict: accounts = self._config.get("channels", {}).get("zulip", {}).get("accounts", []) for acct in accounts: if acct.get("account_id", "default") == account_id: return acct return {} def _build_account(self, account_id: str, raw: dict) -> dict: env_realm = os.environ.get("ZULIP_REALM_URL", "") env_email = os.environ.get("ZULIP_BOT_EMAIL", "") env_key = os.environ.get("ZULIP_BOT_API_KEY", "") return { "account_id": account_id, "enabled": raw.get("enabled", True), "realm_url": env_realm or raw.get("realm_url", ""), "bot_email": env_email or raw.get("bot_email", ""), "bot_api_key": env_key or raw.get("bot_api_key", ""), "dm_policy": raw.get("dm_policy", "pairing"), "allow_from": raw.get("allow_from", []), "stream_allowlist": raw.get("stream_allowlist", []), "streaming_mode": raw.get("streaming_mode", "block"), } def is_configured(self, account: dict) -> bool: return bool(account.get("realm_url") and account.get("bot_email") and account.get("bot_api_key")) def is_enabled(self, account: dict, config: dict | None = None) -> bool: return account.get("enabled", True) def describe_account(self, account: dict) -> dict: return { "account_id": account.get("account_id", ""), "realm_url": account.get("realm_url", ""), "bot_email": account.get("bot_email", ""), "dm_policy": account.get("dm_policy", "pairing"), "configured": self.is_configured(account), "enabled": self.is_enabled(account), } def config_schema(self) -> dict: return { "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "title": "Zulip 渠道配置", "properties": { "realmUrl": { "type": "string", "title": "Zulip 服务器地址", "format": "uri", }, "botEmail": { "type": "string", "title": "Bot Email", "format": "email", }, "botApiKey": { "type": "string", "title": "Bot API Key", "x-ui-password": True, }, "dmPolicy": { "type": "string", "enum": ["pairing", "allowlist", "open", "disabled"], "default": "pairing", }, "streamAllowlist": { "type": "array", "items": {"type": "string"}, "default": [], }, "streamingMode": { "type": "string", "enum": ["off", "block"], "default": "block", }, }, "required": ["realmUrl", "botEmail", "botApiKey"], } @staticmethod def _env_configured(account_id: str) -> bool: return bool( os.environ.get("ZULIP_REALM_URL", "") and os.environ.get("ZULIP_BOT_EMAIL", "") and os.environ.get("ZULIP_BOT_API_KEY", "") )