ForcePilot/backend/package/yuxi/channels/adapters/irc/normalize.py
Kris 2dd1a075f2 feat(irc): 实现完整的IRC适配器基础功能模块
新增IRC协议相关的全套工具模块,包括:
- 核心协议解析与CTCP处理
- 消息发送缓存与文本 sanitize
- 账号配置管理与运行时状态
- 命令处理与权限控制
- 服务发现与诊断工具
- 多账号网关与配置加载
2026-05-12 00:45:10 +08:00

77 lines
2.2 KiB
Python

from __future__ import annotations
from fnmatch import fnmatchcase
def build_allowlist_candidates(
sender_nick: str,
sender_user: str | None = None,
sender_host: str | None = None,
) -> list[str]:
candidates = [sender_nick]
if sender_user:
candidates.append(f"{sender_nick}!{sender_user}")
if sender_host:
candidates.append(f"{sender_nick}@{sender_host}")
if sender_user and sender_host:
candidates.append(f"{sender_nick}!{sender_user}@{sender_host}")
return candidates
def resolve_allowlist_match(
candidates: list[str],
allowlist: list[str],
) -> str | None:
for candidate in candidates:
if candidate in allowlist:
return candidate
for candidate in candidates:
for entry in allowlist:
if fnmatchcase(candidate, entry) or fnmatchcase(entry, candidate):
return entry
if "*" in allowlist:
return "*"
return None
def normalize_allow_entry(entry: str) -> str:
for prefix in ("irc:", "irc:user:", "user:"):
if entry.startswith(prefix):
entry = entry[len(prefix) :]
return entry
def looks_like_irc_target_id(target: str) -> bool:
if target.startswith("irc:channel:") or target.startswith("irc:user:"):
return True
if "!" in target and "@" in target:
return True
return False
def normalize_irc_messaging_target(target: str) -> tuple[str, str]:
if target.startswith("irc:channel:"):
return "group", target.removeprefix("irc:channel:")
if target.startswith("irc:user:"):
return "direct", target.removeprefix("irc:user:")
if target.startswith("#") or target.startswith("&"):
return "group", target
return "direct", normalize_allow_entry(target)
def resolve_targets(target: str) -> dict:
kind, resolved = normalize_irc_messaging_target(target)
return {"kind": kind, "id": resolved, "display_name": resolved}
def format_irc_sender_id(nick: str, user: str | None = None, host: str | None = None) -> str:
if user and host:
return f"{nick}!{user}@{host}"
if user:
return f"{nick}!{user}"
if host:
return f"{nick}@{host}"
return nick