ForcePilot/backend/package/yuxi/channel/extensions/imessage/format.py
Kris 4d52f634fe feat(imessage): 新增iMessage渠道插件完整实现
该提交新增了基于BlueBubbles的iMessage渠道插件,支持单聊和群组消息,包含文本、图片、语音、文件和视频消息收发,支持消息编辑、撤回、回复、 reactions和输入状态提示,同时实现了账号配置、安全校验、配对授权、消息格式化与分片等完整功能。
2026-05-21 10:50:15 +08:00

78 lines
2.6 KiB
Python

from __future__ import annotations
import re
_RE_STRIP_MARKDOWN_LINK = re.compile(r"\[([^\]]*)\]\([^)]+\)")
_RE_STRIP_MARKDOWN_IMAGE = re.compile(r"!\[([^\]]*)\]\([^)]+\)")
def markdown_to_plaintext(md_text: str) -> str:
result = md_text
result = re.sub(r"\*\*(.+?)\*\*", lambda m: m.group(1).upper(), result)
result = re.sub(r"__([^_]+)__", lambda m: m.group(1).upper(), result)
result = re.sub(r"\*([^*]+)\*", r"_\1_", result)
result = re.sub(r"_([^_]+)_", r"_\1_", result)
result = re.sub(r"~~(.+?)~~", "", result)
result = _RE_STRIP_MARKDOWN_IMAGE.sub(r"[\1]", result)
result = _RE_STRIP_MARKDOWN_LINK.sub(lambda m: f"{m.group(1)} ({m.group(0).split('](')[1].rstrip(')')})", result)
result = re.sub(r"```(\w*)\n(.*?)```", r"[CODE]\n\2\n[/CODE]", result, flags=re.DOTALL)
result = result.replace(" & ", " & ")
result = result.replace(" < ", " < ")
result = result.replace(" > ", " > ")
return result.strip()
def convert_table_to_bullets(md_text: str) -> str:
lines = md_text.split("\n")
result: list[str] = []
in_table = False
headers: list[str] = []
for line in lines:
stripped = line.strip()
if stripped.startswith("|") and stripped.endswith("|"):
cells = [c.strip() for c in stripped[1:-1].split("|")]
if not in_table:
headers = cells
in_table = True
continue
if all(re.match(r"^[-:]+$", c) for c in cells):
continue
for i, header in enumerate(headers):
value = cells[i] if i < len(cells) else ""
result.append(f" {header}: {value}")
else:
if in_table:
in_table = False
result.append(line)
return "\n".join(result)
def split_plaintext_chunks(text: str, limit: int = 4000) -> list[str]:
if len(text) <= limit:
return [text]
chunks: list[str] = []
lines = text.split("\n")
current = ""
for line in lines:
if len(current) + len(line) + 1 > limit and current:
chunks.append(current.rstrip())
current = line
else:
current = current + "\n" + line if current else line
if current:
chunks.append(current.rstrip())
return chunks
class IMessageFormatAdapter:
def format_for_imessage(self, md_text: str) -> str:
text = convert_table_to_bullets(md_text)
return markdown_to_plaintext(text)
def chunk_text(self, text: str, limit: int = 4000) -> list[str]:
return split_plaintext_chunks(text, limit)