103 lines
4.0 KiB
Python
103 lines
4.0 KiB
Python
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from dataclasses import dataclass, field
|
|||
|
|
from typing import Any
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class IMessageAccount:
|
|||
|
|
account_id: str
|
|||
|
|
name: str = ""
|
|||
|
|
server_url: str = "http://localhost:1234"
|
|||
|
|
password: str = ""
|
|||
|
|
dm_policy: str = "pairing"
|
|||
|
|
group_policy: str = "allowlist"
|
|||
|
|
allow_from: list[str] = field(default_factory=list)
|
|||
|
|
group_allow_from: list[str] = field(default_factory=list)
|
|||
|
|
require_mention: bool = False
|
|||
|
|
default_to: str = ""
|
|||
|
|
enabled: bool = True
|
|||
|
|
|
|||
|
|
|
|||
|
|
def resolve_accounts(config: dict[str, Any]) -> list[IMessageAccount]:
|
|||
|
|
"""解析多账户配置。
|
|||
|
|
|
|||
|
|
支持两种配置模式:
|
|||
|
|
1. 顶层单账户:config 直接包含 server_url / password
|
|||
|
|
2. accounts 块:config["accounts"] 为 {accountId: {...}, ...}
|
|||
|
|
|
|||
|
|
返回扁平化的 IMessageAccount 列表。
|
|||
|
|
"""
|
|||
|
|
accounts_raw = config.get("accounts")
|
|||
|
|
|
|||
|
|
if not accounts_raw:
|
|||
|
|
account = _account_from_top_level(config)
|
|||
|
|
return [account] if account.server_url else []
|
|||
|
|
|
|||
|
|
result: list[IMessageAccount] = []
|
|||
|
|
default_account_id = config.get("defaultAccount", config.get("default_account", ""))
|
|||
|
|
|
|||
|
|
for account_id, acct_config in accounts_raw.items():
|
|||
|
|
if not isinstance(acct_config, dict):
|
|||
|
|
continue
|
|||
|
|
merged = _merge_account_config(config, account_id, acct_config)
|
|||
|
|
result.append(merged)
|
|||
|
|
|
|||
|
|
if default_account_id:
|
|||
|
|
result.sort(key=lambda a: 0 if a.account_id == default_account_id else 1)
|
|||
|
|
|
|||
|
|
return result
|
|||
|
|
|
|||
|
|
|
|||
|
|
def list_enabled_accounts(config: dict[str, Any]) -> list[IMessageAccount]:
|
|||
|
|
accounts = resolve_accounts(config)
|
|||
|
|
return [a for a in accounts if a.enabled]
|
|||
|
|
|
|||
|
|
|
|||
|
|
def resolve_default_account(config: dict[str, Any]) -> IMessageAccount | None:
|
|||
|
|
accounts = list_enabled_accounts(config)
|
|||
|
|
if not accounts:
|
|||
|
|
return None
|
|||
|
|
default_id = config.get("defaultAccount", config.get("default_account", ""))
|
|||
|
|
for acct in accounts:
|
|||
|
|
if acct.account_id == default_id:
|
|||
|
|
return acct
|
|||
|
|
return accounts[0]
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _account_from_top_level(config: dict[str, Any]) -> IMessageAccount:
|
|||
|
|
return IMessageAccount(
|
|||
|
|
account_id="default",
|
|||
|
|
name=config.get("name", "iMessage"),
|
|||
|
|
server_url=config.get("server_url", "http://localhost:1234"),
|
|||
|
|
password=config.get("password", ""),
|
|||
|
|
dm_policy=config.get("dmPolicy", config.get("dm_policy", "pairing")),
|
|||
|
|
group_policy=config.get("groupPolicy", config.get("group_policy", "allowlist")),
|
|||
|
|
allow_from=config.get("allowFrom", config.get("allow_from", [])),
|
|||
|
|
group_allow_from=config.get("groupAllowFrom", config.get("group_allow_from", [])),
|
|||
|
|
require_mention=config.get("requireMention", config.get("require_mention", False)),
|
|||
|
|
default_to=config.get("defaultTo", config.get("default_to", "")),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _merge_account_config(top: dict[str, Any], account_id: str, acct: dict[str, Any]) -> IMessageAccount:
|
|||
|
|
return IMessageAccount(
|
|||
|
|
account_id=account_id,
|
|||
|
|
name=acct.get("name", account_id),
|
|||
|
|
server_url=acct.get("server_url", top.get("server_url", "http://localhost:1234")),
|
|||
|
|
password=acct.get("password", top.get("password", "")),
|
|||
|
|
dm_policy=acct.get("dmPolicy", acct.get("dm_policy", top.get("dmPolicy", top.get("dm_policy", "pairing")))),
|
|||
|
|
group_policy=acct.get(
|
|||
|
|
"groupPolicy", acct.get("group_policy", top.get("groupPolicy", top.get("group_policy", "allowlist")))
|
|||
|
|
),
|
|||
|
|
allow_from=acct.get("allowFrom", acct.get("allow_from", top.get("allowFrom", top.get("allow_from", [])))),
|
|||
|
|
group_allow_from=acct.get(
|
|||
|
|
"groupAllowFrom", acct.get("group_allow_from", top.get("groupAllowFrom", top.get("group_allow_from", [])))
|
|||
|
|
),
|
|||
|
|
require_mention=acct.get(
|
|||
|
|
"requireMention", acct.get("require_mention", top.get("requireMention", top.get("require_mention", False)))
|
|||
|
|
),
|
|||
|
|
default_to=acct.get("defaultTo", acct.get("default_to", top.get("defaultTo", top.get("default_to", "")))),
|
|||
|
|
enabled=acct.get("enabled", True),
|
|||
|
|
)
|