新增IRC协议相关的全套工具模块,包括: - 核心协议解析与CTCP处理 - 消息发送缓存与文本 sanitize - 账号配置管理与运行时状态 - 命令处理与权限控制 - 服务发现与诊断工具 - 多账号网关与配置加载
85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
_IRC_PROTOCOL_PREFIX = "irc:"
|
|
|
|
|
|
def resolve_chat_id(target: str, sender_nick: str) -> str:
|
|
is_channel = target.startswith("#") or target.startswith("&")
|
|
return target if is_channel else f"dm_{sender_nick}"
|
|
|
|
|
|
def resolve_channel_user_id(nick: str) -> str:
|
|
return nick
|
|
|
|
|
|
def resolve_thread_id(agent_id: str, chat_id: str) -> str:
|
|
is_channel = chat_id.startswith("#") or chat_id.startswith("&")
|
|
if is_channel:
|
|
channel_name = chat_id.lstrip("#&")
|
|
return f"agent:{agent_id}:irc:channel:{channel_name}"
|
|
dm_nick = chat_id.removeprefix("dm_")
|
|
return f"agent:{agent_id}:irc:dm:{dm_nick}"
|
|
|
|
|
|
def is_channel(target: str) -> bool:
|
|
return target.startswith("#") or target.startswith("&")
|
|
|
|
|
|
def normalize_irc_messaging_target(target: str) -> dict[str, str] | None:
|
|
"""Parse IRC messaging target with optional protocol prefix.
|
|
|
|
Handles:
|
|
- raw channel: ``#channel``, ``&channel``
|
|
- protocol prefix: ``irc:channel:#channel``, ``irc:user:nick``
|
|
- DM target: plain nick (no prefix)
|
|
|
|
Returns ``{"kind": "group"|"user", "target": "..."}`` or None.
|
|
"""
|
|
clean = target.strip()
|
|
if not clean:
|
|
return None
|
|
|
|
if clean.startswith(_IRC_PROTOCOL_PREFIX):
|
|
clean = clean.removeprefix(_IRC_PROTOCOL_PREFIX)
|
|
if clean.startswith("channel:"):
|
|
ch = clean.removeprefix("channel:")
|
|
if ch:
|
|
return {"kind": "group", "target": ch}
|
|
return None
|
|
if clean.startswith("user:"):
|
|
u = clean.removeprefix("user:")
|
|
if u:
|
|
return {"kind": "user", "target": u}
|
|
return None
|
|
return None
|
|
|
|
if clean.startswith("#") or clean.startswith("&"):
|
|
return {"kind": "group", "target": clean}
|
|
|
|
return {"kind": "user", "target": clean}
|
|
|
|
|
|
def resolve_targets(kind: str, target: str) -> dict[str, str] | None:
|
|
"""Resolve a target string based on its kind.
|
|
|
|
- ``kind="group"``: auto-prepend ``#`` if missing, reject bare nick.
|
|
- ``kind="user"``: reject channel targets (``#``/``&``).
|
|
|
|
Returns ``{"kind": "...", "target": "..."}`` or None on error.
|
|
"""
|
|
t = target.strip()
|
|
if not t:
|
|
return None
|
|
|
|
if kind == "group":
|
|
if not t.startswith("#") and not t.startswith("&"):
|
|
t = f"#{t}"
|
|
return {"kind": "group", "target": t}
|
|
|
|
if kind == "user":
|
|
if t.startswith("#") or t.startswith("&"):
|
|
return None
|
|
return {"kind": "user", "target": t}
|
|
|
|
return None
|