-
Notifications
You must be signed in to change notification settings - Fork 30
入群欢迎词支持@和图片的cq码 #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
入群欢迎词支持@和图片的cq码 #98
Changes from all commits
969a020
a5d60e5
ad5e2cc
803071f
a44535b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| import re | ||
| import os | ||
| from astrbot.core.message.components import Plain, At, Image | ||
|
|
||
| def parse_cq_to_chain(text: str) -> list: | ||
| """增强版 CQ 码解析,支持本地绝对路径图片""" | ||
| chain = [] | ||
| # 更加健壮的正则,支持参数中带有路径、空格等 | ||
| pattern = r'\[CQ:([a-z]+),([^\]]+)\]' | ||
| last_pos = 0 | ||
|
|
||
| for match in re.finditer(pattern, text): | ||
| # 处理之前的纯文本 | ||
| plain_text = text[last_pos:match.start()] | ||
| if plain_text: | ||
| chain.append(Plain(plain_text)) | ||
|
|
||
| cq_type = match.group(1) | ||
| params_str = match.group(2) | ||
|
|
||
| # 解析参数:file=D:\xxx... | ||
| params = {} | ||
| for item in params_str.split(','): | ||
| if '=' in item: | ||
| k, v = item.split('=', 1) | ||
| params[k.strip()] = v.strip() | ||
|
|
||
| # 根据类型构造组件 | ||
| if cq_type == "at": | ||
| chain.append(At(qq=params.get("qq", ""), name="")) | ||
|
Comment on lines
+29
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: 当缺少 当 Suggested implementation: # 根据类型构造组件
if cq_type == "at":
qq = (params.get("qq") or "").strip()
# qq 缺失或格式异常时,不创建空的 At,而是退回为原始文本,便于发现配置问题
if qq and qq.isdigit():
chain.append(At(qq=qq, name=""))
else:
chain.append(Plain(match.group(0)))
elif cq_type == "image":This change assumes that Original comment in Englishsuggestion: Creating an When Suggested implementation: # 根据类型构造组件
if cq_type == "at":
qq = (params.get("qq") or "").strip()
# qq 缺失或格式异常时,不创建空的 At,而是退回为原始文本,便于发现配置问题
if qq and qq.isdigit():
chain.append(At(qq=qq, name=""))
else:
chain.append(Plain(match.group(0)))
elif cq_type == "image":This change assumes that |
||
| elif cq_type == "image": | ||
| file_path = params.get("file") or params.get("url") | ||
| if file_path: | ||
| # 判断是 URL 还是本地路径 | ||
| if file_path.startswith("http"): | ||
| chain.append(Image.fromURL(file_path)) | ||
| else: | ||
| # 确保路径存在 | ||
| if os.path.exists(file_path): | ||
| chain.append(Image.fromFileSystem(file_path)) | ||
| else: | ||
| # 如果路径不存在,回退为文本提示,方便调试 | ||
| chain.append(Plain(f"[图片读取失败: {file_path}]")) | ||
|
|
||
| last_pos = match.end() | ||
|
|
||
| # 处理剩余文本 | ||
| rest_text = text[last_pos:] | ||
| if rest_text: | ||
| chain.append(Plain(rest_text)) | ||
|
|
||
| return chain | ||
|
|
||
| # --- 以下仅用于本地脱离 AstrBot 环境测试 --- | ||
| # if __name__ == "__main__": | ||
| # class MockComponent: | ||
| # def __repr__(self): | ||
| # # 这样打印出来能看到具体的属性 | ||
| # return f"{self.__class__.__name__}({self.__dict__})" | ||
|
|
||
| # class Plain(MockComponent): | ||
| # def __init__(self, text): self.text = text | ||
|
|
||
| # class At(MockComponent): | ||
| # def __init__(self, qq, name=""): | ||
| # self.qq = qq | ||
| # self.name = name | ||
|
|
||
| # class Image(MockComponent): | ||
| # def __init__(self, file=None, url=None): | ||
| # self.file = file | ||
| # self.url = url | ||
| # @staticmethod | ||
| # def fromURL(url): return Image(url=url) | ||
| # @staticmethod | ||
| # def fromFileSystem(path): return Image(file=path) | ||
|
|
||
| # # 测试文本(建议使用 r"" 原始字符串防止路径转义) | ||
| # test_text = r"你好 {nickname}。欢迎![CQ:at,qq=123456][CQ:image,file=./入群欢迎.jpg]" | ||
|
|
||
| # # 假设你脚本里的函数名是 parse_cq_to_chain | ||
| # result = parse_cq_to_chain(test_text) | ||
|
|
||
| # print("\n" + "="*30) | ||
| # print("--- 🔍 解析结果验证 ---") | ||
| # for i, item in enumerate(result): | ||
| # print(f"组件 {i}: {item}") | ||
| # print("="*30) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): 未识别的 CQ 类型会被静默丢弃,而不是保留为文本。
当
cq_type不是at或image时,这个分支只会向前移动last_pos,而不会追加任何内容,因此该 CQ 段会丢失。为避免丢弃未知或未来可能出现的 CQ 类型,建议在类型未被识别时,将原始片段text[match.start():match.end()]作为一个Plain段追加到链中。Original comment in English
issue (bug_risk): Unrecognized CQ types are silently dropped instead of being preserved as text.
When
cq_typeis notatorimage, this branch only moveslast_posforward and never appends anything, so that CQ segment is lost. To avoid dropping unknown or future CQ types, consider appending the raw slicetext[match.start():match.end()]as aPlainsegment when the type isn’t recognized.