Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions astrbot/core/message/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,13 +720,20 @@ async def get_file(self, allow_return_url: bool = False) -> str:
if allow_return_url and self.url:
return self.url

if self.file_ and os.path.exists(self.file_):
return os.path.abspath(self.file_)
if self.file_:
path = self.file_
if path.startswith("file:///"):
path = path[8:]
if os.path.exists(path):
return os.path.abspath(path)

if self.url:
await self._download_file()
if self.file_:
return os.path.abspath(self.file_)
path = self.file_
if path.startswith("file:///"):
path = path[8:]
return os.path.abspath(path)

return ""

Expand Down
11 changes: 11 additions & 0 deletions astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import os
import re
from collections.abc import AsyncGenerator

Expand Down Expand Up @@ -45,6 +46,16 @@ async def _from_segment_to_dict(segment: BaseMessageComponent) -> dict:
if isinstance(segment, File):
# For File segments, we need to handle the file differently
d = await segment.to_dict()
file_val = d.get("data", {}).get("file", "")
if (
file_val
and os.path.isabs(file_val)
and not file_val.startswith(("http", "base64", "file://"))
):
if file_val.startswith("/"):
d["data"]["file"] = f"file://{file_val}"
else:
d["data"]["file"] = f"file:///{file_val}"
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

aiocqhttp_message_event.py 中为绝对路径添加 file:// 前缀的逻辑需要修正,以完全符合 OneBot 11 标准。OneBot 11 标准要求本地文件路径使用 file:/// 协议头,其中路径部分应为绝对路径。

当前的实现中:

  • 如果 file_val 是 Unix-like 绝对路径(例如 /home/user/file.txt),if file_val.startswith("/") 分支会将其转换为 file:////home/user/file.txt(四个斜杠)。这与 file:/// 标准不符。
  • 如果 file_val 是 Windows 绝对路径(例如 C:\Users\user\file.txt),else 分支会将其转换为 file:///C:\Users\user\file.txt(三个斜杠),这符合标准。

为了确保所有绝对本地路径都以 file:/// 格式正确生成,无论操作系统如何,都应该先移除路径中可能存在的起始斜杠,然后再统一添加 file:/// 前缀。

例如:

  • /home/user/file.txt 应变为 file:///home/user/file.txt
  • C:\Users\user\file.txt 应变为 file:///C:\Users\user\file.txt
                normalized_path = file_val.lstrip("/")
                d["data"]["file"] = f"file:///{normalized_path}"

return d
if isinstance(segment, Video):
d = await segment.to_dict()
Expand Down