mirror of
https://github.com/AstrBotDevs/AstrBot.git
synced 2026-09-24 16:39:52 +08:00
fix: resolve ruff check issues
This commit is contained in:
@@ -16,6 +16,7 @@ from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import anyio
|
||||
from sqlalchemy import delete
|
||||
|
||||
from astrbot.core import logger
|
||||
@@ -364,7 +365,7 @@ class AstrBotImporter:
|
||||
"""
|
||||
result = ImportResult()
|
||||
|
||||
if not os.path.exists(zip_path):
|
||||
if not await anyio.Path(zip_path).exists():
|
||||
result.add_error(f"备份文件不存在: {zip_path}")
|
||||
return result
|
||||
|
||||
@@ -446,12 +447,12 @@ class AstrBotImporter:
|
||||
try:
|
||||
config_content = zf.read("config/cmd_config.json")
|
||||
# 备份现有配置
|
||||
if os.path.exists(self.config_path):
|
||||
if await anyio.Path(self.config_path).exists():
|
||||
backup_path = f"{self.config_path}.bak"
|
||||
shutil.copy2(self.config_path, backup_path)
|
||||
|
||||
with open(self.config_path, "wb") as f:
|
||||
f.write(config_content)
|
||||
async with await anyio.open_file(self.config_path, "wb") as f:
|
||||
await f.write(config_content)
|
||||
result.imported_files["config"] = 1
|
||||
except Exception as e:
|
||||
result.add_warning(f"导入配置文件失败: {e}")
|
||||
@@ -753,8 +754,10 @@ class AstrBotImporter:
|
||||
if faiss_path in zf.namelist():
|
||||
try:
|
||||
target_path = kb_dir / "index.faiss"
|
||||
with zf.open(faiss_path) as src, open(target_path, "wb") as dst:
|
||||
dst.write(src.read())
|
||||
with zf.open(faiss_path) as src:
|
||||
content = src.read()
|
||||
async with await anyio.open_file(target_path, "wb") as dst:
|
||||
await dst.write(content)
|
||||
except Exception as e:
|
||||
result.add_warning(f"导入知识库 {kb_id} 的 FAISS 索引失败: {e}")
|
||||
|
||||
@@ -765,9 +768,13 @@ class AstrBotImporter:
|
||||
try:
|
||||
rel_path = name[len(media_prefix) :]
|
||||
target_path = kb_dir / rel_path
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with zf.open(name) as src, open(target_path, "wb") as dst:
|
||||
dst.write(src.read())
|
||||
await anyio.Path(target_path.parent).mkdir(
|
||||
parents=True, exist_ok=True
|
||||
)
|
||||
with zf.open(name) as src:
|
||||
content = src.read()
|
||||
async with await anyio.open_file(target_path, "wb") as dst:
|
||||
await dst.write(content)
|
||||
except Exception as e:
|
||||
result.add_warning(f"导入媒体文件 {name} 失败: {e}")
|
||||
|
||||
@@ -827,9 +834,13 @@ class AstrBotImporter:
|
||||
else:
|
||||
target_path = attachments_dir / os.path.basename(name)
|
||||
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with zf.open(name) as src, open(target_path, "wb") as dst:
|
||||
dst.write(src.read())
|
||||
await anyio.Path(target_path.parent).mkdir(
|
||||
parents=True, exist_ok=True
|
||||
)
|
||||
with zf.open(name) as src:
|
||||
content = src.read()
|
||||
async with await anyio.open_file(target_path, "wb") as dst:
|
||||
await dst.write(content)
|
||||
count += 1
|
||||
except Exception as e:
|
||||
logger.warning(f"导入附件 {name} 失败: {e}")
|
||||
@@ -885,15 +896,15 @@ class AstrBotImporter:
|
||||
continue
|
||||
|
||||
# 备份现有目录(如果存在)
|
||||
if target_dir.exists():
|
||||
if await anyio.Path(target_dir).exists():
|
||||
backup_path = Path(f"{target_dir}.bak")
|
||||
if backup_path.exists():
|
||||
if await anyio.Path(backup_path).exists():
|
||||
shutil.rmtree(backup_path)
|
||||
shutil.move(str(target_dir), str(backup_path))
|
||||
logger.debug(f"已备份现有目录 {target_dir} 到 {backup_path}")
|
||||
|
||||
# 创建目标目录
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
await anyio.Path(target_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 解压文件
|
||||
for name in dir_files:
|
||||
@@ -904,10 +915,14 @@ class AstrBotImporter:
|
||||
continue
|
||||
|
||||
target_path = target_dir / rel_path
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
await anyio.Path(target_path.parent).mkdir(
|
||||
parents=True, exist_ok=True
|
||||
)
|
||||
|
||||
with zf.open(name) as src, open(target_path, "wb") as dst:
|
||||
dst.write(src.read())
|
||||
with zf.open(name) as src:
|
||||
content = src.read()
|
||||
async with await anyio.open_file(target_path, "wb") as dst:
|
||||
await dst.write(content)
|
||||
file_count += 1
|
||||
except Exception as e:
|
||||
result.add_warning(f"导入文件 {name} 失败: {e}")
|
||||
|
||||
@@ -6,6 +6,7 @@ import random
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import aiohttp
|
||||
import anyio
|
||||
import boxlite
|
||||
from shipyard.filesystem import FileSystemComponent as ShipyardFileSystemComponent
|
||||
from shipyard.python import PythonComponent as ShipyardPythonComponent
|
||||
@@ -52,8 +53,8 @@ class MockShipyardSandboxClient:
|
||||
|
||||
try:
|
||||
# Read file content
|
||||
with open(path, "rb") as f:
|
||||
file_content = f.read()
|
||||
async with await anyio.open_file(path, "rb") as f:
|
||||
file_content = await f.read()
|
||||
|
||||
# Create multipart form data
|
||||
data = aiohttp.FormData()
|
||||
|
||||
@@ -5,6 +5,8 @@ import os
|
||||
import shlex
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
import anyio
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -37,7 +39,7 @@ class NeoPythonComponent(PythonComponent):
|
||||
self,
|
||||
code: str,
|
||||
kernel_id: str | None = None,
|
||||
timeout: int = 30,
|
||||
timeout: int = 30, # noqa: ASYNC109
|
||||
silent: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
_ = kernel_id # Bay runtime does not expose kernel_id in current SDK.
|
||||
@@ -79,7 +81,7 @@ class NeoShellComponent(ShellComponent):
|
||||
command: str,
|
||||
cwd: str | None = None,
|
||||
env: dict[str, str] | None = None,
|
||||
timeout: int | None = 30,
|
||||
timeout: int | None = 30, # noqa: ASYNC109
|
||||
shell: bool = True,
|
||||
background: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
@@ -196,7 +198,7 @@ class NeoBrowserComponent(BrowserComponent):
|
||||
async def exec(
|
||||
self,
|
||||
cmd: str,
|
||||
timeout: int = 30,
|
||||
timeout: int = 30, # noqa: ASYNC109
|
||||
description: str | None = None,
|
||||
tags: str | None = None,
|
||||
learn: bool = False,
|
||||
@@ -215,7 +217,7 @@ class NeoBrowserComponent(BrowserComponent):
|
||||
async def exec_batch(
|
||||
self,
|
||||
commands: list[str],
|
||||
timeout: int = 60,
|
||||
timeout: int = 60, # noqa: ASYNC109
|
||||
stop_on_error: bool = True,
|
||||
description: str | None = None,
|
||||
tags: str | None = None,
|
||||
@@ -236,7 +238,7 @@ class NeoBrowserComponent(BrowserComponent):
|
||||
async def run_skill(
|
||||
self,
|
||||
skill_key: str,
|
||||
timeout: int = 60,
|
||||
timeout: int = 60, # noqa: ASYNC109
|
||||
stop_on_error: bool = True,
|
||||
include_trace: bool = False,
|
||||
description: str | None = None,
|
||||
@@ -480,8 +482,8 @@ class ShipyardNeoBooter(ComputerBooter):
|
||||
async def upload_file(self, path: str, file_name: str) -> dict:
|
||||
if self._sandbox is None:
|
||||
raise RuntimeError("ShipyardNeoBooter is not initialized.")
|
||||
with open(path, "rb") as f:
|
||||
content = f.read()
|
||||
async with await anyio.open_file(path, "rb") as f:
|
||||
content = await f.read()
|
||||
remote_path = file_name.lstrip("/")
|
||||
await self._sandbox.filesystem.upload(remote_path, content)
|
||||
logger.info(
|
||||
@@ -500,9 +502,9 @@ class ShipyardNeoBooter(ComputerBooter):
|
||||
content = await self._sandbox.filesystem.download(remote_path.lstrip("/"))
|
||||
local_dir = os.path.dirname(local_path)
|
||||
if local_dir:
|
||||
os.makedirs(local_dir, exist_ok=True)
|
||||
with open(local_path, "wb") as f:
|
||||
f.write(cast(bytes, content))
|
||||
await anyio.Path(local_dir).mkdir(parents=True, exist_ok=True)
|
||||
async with await anyio.open_file(local_path, "wb") as f:
|
||||
await f.write(cast(bytes, content))
|
||||
logger.info(
|
||||
"[Computer] file_download booter=shipyard_neo remote_path=%s local_path=%s",
|
||||
remote_path,
|
||||
|
||||
@@ -141,14 +141,15 @@ async def parse_webchat_message_parts(
|
||||
continue
|
||||
|
||||
file_path = Path(str(path))
|
||||
if verify_media_path_exists and not file_path.exists():
|
||||
if verify_media_path_exists and not await anyio.Path(file_path).exists():
|
||||
if strict:
|
||||
raise ValueError(f"file not found: {file_path!s}")
|
||||
continue
|
||||
|
||||
file_path_str = (
|
||||
str(file_path.resolve()) if verify_media_path_exists else str(file_path)
|
||||
)
|
||||
if verify_media_path_exists:
|
||||
file_path_str = str(await anyio.Path(file_path).resolve())
|
||||
else:
|
||||
file_path_str = str(file_path)
|
||||
has_content = True
|
||||
if part_type == "image":
|
||||
components.append(Image.fromFileSystem(file_path_str))
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import asyncio
|
||||
import base64
|
||||
import json
|
||||
import os
|
||||
@@ -6,6 +5,7 @@ import traceback
|
||||
import uuid
|
||||
|
||||
import aiohttp
|
||||
import anyio
|
||||
|
||||
from astrbot import logger
|
||||
from astrbot.core.utils.astrbot_path import get_astrbot_temp_path
|
||||
@@ -100,11 +100,8 @@ class ProviderVolcengineTTS(TTSProvider):
|
||||
f"volcengine_tts_{uuid.uuid4()}.mp3",
|
||||
)
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
await loop.run_in_executor(
|
||||
None,
|
||||
lambda: open(file_path, "wb").write(audio_data),
|
||||
)
|
||||
async with await anyio.open_file(file_path, "wb") as audio_file:
|
||||
await audio_file.write(audio_data)
|
||||
|
||||
return file_path
|
||||
error_msg = resp_data.get("message", "未知错误")
|
||||
|
||||
@@ -7,7 +7,8 @@ import asyncio
|
||||
import os
|
||||
import subprocess
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
import anyio
|
||||
|
||||
from astrbot import logger
|
||||
from astrbot.core.utils.astrbot_path import get_astrbot_temp_path
|
||||
@@ -78,7 +79,7 @@ async def convert_audio_to_opus(audio_path: str, output_path: str | None = None)
|
||||
# 生成输出文件路径
|
||||
if output_path is None:
|
||||
temp_dir = get_astrbot_temp_path()
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
await anyio.Path(temp_dir).mkdir(parents=True, exist_ok=True)
|
||||
output_path = os.path.join(temp_dir, f"media_audio_{uuid.uuid4().hex}.opus")
|
||||
|
||||
try:
|
||||
@@ -108,9 +109,9 @@ async def convert_audio_to_opus(audio_path: str, output_path: str | None = None)
|
||||
|
||||
if process.returncode != 0:
|
||||
# 清理可能已生成但无效的临时文件
|
||||
if output_path and os.path.exists(output_path):
|
||||
if output_path and await anyio.Path(output_path).exists():
|
||||
try:
|
||||
os.remove(output_path)
|
||||
await anyio.Path(output_path).unlink()
|
||||
logger.debug(
|
||||
f"[Media Utils] 已清理失败的opus输出文件: {output_path}"
|
||||
)
|
||||
@@ -157,7 +158,7 @@ async def convert_video_format(
|
||||
# 生成输出文件路径
|
||||
if output_path is None:
|
||||
temp_dir = get_astrbot_temp_path()
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
await anyio.Path(temp_dir).mkdir(parents=True, exist_ok=True)
|
||||
output_path = os.path.join(
|
||||
temp_dir,
|
||||
f"media_video_{uuid.uuid4().hex}.{output_format}",
|
||||
@@ -183,9 +184,9 @@ async def convert_video_format(
|
||||
|
||||
if process.returncode != 0:
|
||||
# 清理可能已生成但无效的临时文件
|
||||
if output_path and os.path.exists(output_path):
|
||||
if output_path and await anyio.Path(output_path).exists():
|
||||
try:
|
||||
os.remove(output_path)
|
||||
await anyio.Path(output_path).unlink()
|
||||
logger.debug(
|
||||
f"[Media Utils] 已清理失败的{output_format}输出文件: {output_path}"
|
||||
)
|
||||
@@ -230,8 +231,8 @@ async def convert_audio_format(
|
||||
return audio_path
|
||||
|
||||
if output_path is None:
|
||||
temp_dir = Path(get_astrbot_temp_path())
|
||||
temp_dir.mkdir(parents=True, exist_ok=True)
|
||||
temp_dir = anyio.Path(get_astrbot_temp_path())
|
||||
await temp_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = str(temp_dir / f"media_audio_{uuid.uuid4().hex}.{output_format}")
|
||||
|
||||
args = ["ffmpeg", "-y", "-i", audio_path]
|
||||
@@ -249,9 +250,9 @@ async def convert_audio_format(
|
||||
)
|
||||
_, stderr = await process.communicate()
|
||||
if process.returncode != 0:
|
||||
if output_path and os.path.exists(output_path):
|
||||
if output_path and await anyio.Path(output_path).exists():
|
||||
try:
|
||||
os.remove(output_path)
|
||||
await anyio.Path(output_path).unlink()
|
||||
except OSError as e:
|
||||
logger.warning(f"[Media Utils] 清理失败的音频输出文件时出错: {e}")
|
||||
error_msg = stderr.decode() if stderr else "未知错误"
|
||||
@@ -286,8 +287,8 @@ async def extract_video_cover(
|
||||
) -> str:
|
||||
"""从视频中提取封面图(JPG)。"""
|
||||
if output_path is None:
|
||||
temp_dir = Path(get_astrbot_temp_path())
|
||||
temp_dir.mkdir(parents=True, exist_ok=True)
|
||||
temp_dir = anyio.Path(get_astrbot_temp_path())
|
||||
await temp_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = str(temp_dir / f"media_cover_{uuid.uuid4().hex}.jpg")
|
||||
|
||||
try:
|
||||
@@ -306,9 +307,9 @@ async def extract_video_cover(
|
||||
)
|
||||
_, stderr = await process.communicate()
|
||||
if process.returncode != 0:
|
||||
if output_path and os.path.exists(output_path):
|
||||
if output_path and await anyio.Path(output_path).exists():
|
||||
try:
|
||||
os.remove(output_path)
|
||||
await anyio.Path(output_path).unlink()
|
||||
except OSError as e:
|
||||
logger.warning(f"[Media Utils] 清理失败的视频封面文件时出错: {e}")
|
||||
error_msg = stderr.decode() if stderr else "未知错误"
|
||||
|
||||
@@ -6,6 +6,8 @@ import tempfile
|
||||
import wave
|
||||
from io import BytesIO
|
||||
|
||||
import anyio
|
||||
|
||||
from astrbot.core import logger
|
||||
from astrbot.core.utils.astrbot_path import get_astrbot_temp_path
|
||||
|
||||
@@ -13,8 +15,8 @@ from astrbot.core.utils.astrbot_path import get_astrbot_temp_path
|
||||
async def tencent_silk_to_wav(silk_path: str, output_path: str) -> str:
|
||||
import pysilk
|
||||
|
||||
with open(silk_path, "rb") as f:
|
||||
input_data = f.read()
|
||||
async with await anyio.open_file(silk_path, "rb") as f:
|
||||
input_data = await f.read()
|
||||
if input_data.startswith(b"\x02"):
|
||||
input_data = input_data[1:]
|
||||
input_io = BytesIO(input_data)
|
||||
@@ -97,7 +99,10 @@ async def convert_to_pcm_wav(input_path: str, output_path: str) -> str:
|
||||
logger.debug(f"[FFmpeg] stderr: {stderr.decode().strip()}")
|
||||
logger.info(f"[FFmpeg] return code: {p.returncode}")
|
||||
|
||||
if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
|
||||
if (
|
||||
await anyio.Path(output_path).exists()
|
||||
and (await anyio.Path(output_path).stat()).st_size > 0
|
||||
):
|
||||
return output_path
|
||||
raise RuntimeError("生成的WAV文件不存在或为空")
|
||||
|
||||
@@ -118,7 +123,7 @@ async def audio_to_tencent_silk_base64(audio_path: str) -> tuple[str, float]:
|
||||
raise Exception("未安装 pilk: pip install pilk") from e
|
||||
|
||||
temp_dir = get_astrbot_temp_path()
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
await anyio.Path(temp_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 是否需要转换为 WAV
|
||||
ext = os.path.splitext(audio_path)[1].lower()
|
||||
@@ -132,7 +137,7 @@ async def audio_to_tencent_silk_base64(audio_path: str) -> tuple[str, float]:
|
||||
if ext != ".wav":
|
||||
await convert_to_pcm_wav(audio_path, temp_wav)
|
||||
# 删除原文件
|
||||
os.remove(audio_path)
|
||||
await anyio.Path(audio_path).unlink()
|
||||
wav_path = temp_wav
|
||||
else:
|
||||
wav_path = audio_path
|
||||
@@ -156,13 +161,13 @@ async def audio_to_tencent_silk_base64(audio_path: str) -> tuple[str, float]:
|
||||
tencent=True,
|
||||
)
|
||||
|
||||
with open(silk_path, "rb") as f:
|
||||
silk_bytes = await asyncio.to_thread(f.read)
|
||||
async with await anyio.open_file(silk_path, "rb") as f:
|
||||
silk_bytes = await f.read()
|
||||
silk_b64 = base64.b64encode(silk_bytes).decode("utf-8")
|
||||
|
||||
return silk_b64, duration # 已是秒
|
||||
finally:
|
||||
if os.path.exists(wav_path) and wav_path != audio_path:
|
||||
os.remove(wav_path)
|
||||
if os.path.exists(silk_path):
|
||||
os.remove(silk_path)
|
||||
if await anyio.Path(wav_path).exists() and wav_path != audio_path:
|
||||
await anyio.Path(wav_path).unlink()
|
||||
if await anyio.Path(silk_path).exists():
|
||||
await anyio.Path(silk_path).unlink()
|
||||
|
||||
@@ -10,8 +10,8 @@ import traceback
|
||||
import uuid
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import anyio
|
||||
import jwt
|
||||
from quart import request, send_file
|
||||
|
||||
@@ -240,7 +240,7 @@ class BackupRoute(Route):
|
||||
if upload_id in self.upload_sessions:
|
||||
session = self.upload_sessions[upload_id]
|
||||
chunk_dir = session.get("chunk_dir")
|
||||
if chunk_dir and os.path.exists(chunk_dir):
|
||||
if chunk_dir and await anyio.Path(chunk_dir).exists():
|
||||
try:
|
||||
shutil.rmtree(chunk_dir)
|
||||
except Exception as e:
|
||||
@@ -283,7 +283,7 @@ class BackupRoute(Route):
|
||||
page_size = request.args.get("page_size", 20, type=int)
|
||||
|
||||
# 确保备份目录存在
|
||||
Path(self.backup_dir).mkdir(parents=True, exist_ok=True)
|
||||
await anyio.Path(self.backup_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 获取所有备份文件
|
||||
backup_files = []
|
||||
@@ -293,7 +293,7 @@ class BackupRoute(Route):
|
||||
continue
|
||||
|
||||
file_path = os.path.join(self.backup_dir, filename)
|
||||
if not os.path.isfile(file_path):
|
||||
if not await anyio.Path(file_path).is_file():
|
||||
continue
|
||||
|
||||
# 读取 manifest.json 获取备份信息
|
||||
@@ -403,7 +403,7 @@ class BackupRoute(Route):
|
||||
result={
|
||||
"filename": os.path.basename(zip_path),
|
||||
"path": zip_path,
|
||||
"size": os.path.getsize(zip_path),
|
||||
"size": (await anyio.Path(zip_path).stat()).st_size,
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -437,7 +437,7 @@ class BackupRoute(Route):
|
||||
unique_filename = generate_unique_filename(safe_filename)
|
||||
|
||||
# 保存上传的文件
|
||||
Path(self.backup_dir).mkdir(parents=True, exist_ok=True)
|
||||
await anyio.Path(self.backup_dir).mkdir(parents=True, exist_ok=True)
|
||||
zip_path = os.path.join(self.backup_dir, unique_filename)
|
||||
await file.save(zip_path)
|
||||
|
||||
@@ -451,7 +451,7 @@ class BackupRoute(Route):
|
||||
{
|
||||
"filename": unique_filename,
|
||||
"original_filename": file.filename,
|
||||
"size": os.path.getsize(zip_path),
|
||||
"size": (await anyio.Path(zip_path).stat()).st_size,
|
||||
}
|
||||
)
|
||||
.__dict__
|
||||
@@ -499,7 +499,7 @@ class BackupRoute(Route):
|
||||
|
||||
# 创建分片存储目录
|
||||
chunk_dir = os.path.join(self.chunks_dir, upload_id)
|
||||
Path(chunk_dir).mkdir(parents=True, exist_ok=True)
|
||||
await anyio.Path(chunk_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 清洗文件名
|
||||
safe_filename = secure_filename(filename)
|
||||
@@ -685,22 +685,24 @@ class BackupRoute(Route):
|
||||
chunk_dir = session["chunk_dir"]
|
||||
filename = session["filename"]
|
||||
|
||||
Path(self.backup_dir).mkdir(parents=True, exist_ok=True)
|
||||
await anyio.Path(self.backup_dir).mkdir(parents=True, exist_ok=True)
|
||||
output_path = os.path.join(self.backup_dir, filename)
|
||||
|
||||
try:
|
||||
with open(output_path, "wb") as outfile:
|
||||
async with await anyio.open_file(output_path, "wb") as outfile:
|
||||
for i in range(total):
|
||||
chunk_path = os.path.join(chunk_dir, f"{i}.part")
|
||||
with open(chunk_path, "rb") as chunk_file:
|
||||
async with await anyio.open_file(
|
||||
chunk_path, "rb"
|
||||
) as chunk_file:
|
||||
# 分块读取,避免内存溢出
|
||||
while True:
|
||||
data_block = chunk_file.read(8192)
|
||||
data_block = await chunk_file.read(8192)
|
||||
if not data_block:
|
||||
break
|
||||
outfile.write(data_block)
|
||||
await outfile.write(data_block)
|
||||
|
||||
file_size = os.path.getsize(output_path)
|
||||
file_size = (await anyio.Path(output_path).stat()).st_size
|
||||
|
||||
# 标记备份为上传来源(修改 manifest.json 中的 origin 字段)
|
||||
self._mark_backup_as_uploaded(output_path)
|
||||
@@ -725,8 +727,8 @@ class BackupRoute(Route):
|
||||
)
|
||||
except Exception as e:
|
||||
# 如果合并失败,删除不完整的文件
|
||||
if os.path.exists(output_path):
|
||||
os.remove(output_path)
|
||||
if await anyio.Path(output_path).exists():
|
||||
await anyio.Path(output_path).unlink()
|
||||
raise e
|
||||
|
||||
except Exception as e:
|
||||
@@ -787,7 +789,7 @@ class BackupRoute(Route):
|
||||
return Response().error("无效的文件名").__dict__
|
||||
|
||||
zip_path = os.path.join(self.backup_dir, filename)
|
||||
if not os.path.exists(zip_path):
|
||||
if not await anyio.Path(zip_path).exists():
|
||||
return Response().error(f"备份文件不存在: {filename}").__dict__
|
||||
|
||||
# 获取知识库管理器(用于构造 importer)
|
||||
@@ -841,7 +843,7 @@ class BackupRoute(Route):
|
||||
return Response().error("无效的文件名").__dict__
|
||||
|
||||
zip_path = os.path.join(self.backup_dir, filename)
|
||||
if not os.path.exists(zip_path):
|
||||
if not await anyio.Path(zip_path).exists():
|
||||
return Response().error(f"备份文件不存在: {filename}").__dict__
|
||||
|
||||
# 生成任务ID
|
||||
@@ -998,7 +1000,7 @@ class BackupRoute(Route):
|
||||
return Response().error("无效的文件名").__dict__
|
||||
|
||||
file_path = os.path.join(self.backup_dir, filename)
|
||||
if not os.path.exists(file_path):
|
||||
if not await anyio.Path(file_path).exists():
|
||||
return Response().error("备份文件不存在").__dict__
|
||||
|
||||
return await send_file(
|
||||
@@ -1029,10 +1031,10 @@ class BackupRoute(Route):
|
||||
return Response().error("无效的文件名").__dict__
|
||||
|
||||
file_path = os.path.join(self.backup_dir, filename)
|
||||
if not os.path.exists(file_path):
|
||||
if not await anyio.Path(file_path).exists():
|
||||
return Response().error("备份文件不存在").__dict__
|
||||
|
||||
os.remove(file_path)
|
||||
await anyio.Path(file_path).unlink()
|
||||
return Response().ok(message="删除备份成功").__dict__
|
||||
except Exception as e:
|
||||
logger.error(f"删除备份失败: {e}")
|
||||
@@ -1077,12 +1079,12 @@ class BackupRoute(Route):
|
||||
|
||||
# 检查原文件是否存在
|
||||
old_path = os.path.join(self.backup_dir, filename)
|
||||
if not os.path.exists(old_path):
|
||||
if not await anyio.Path(old_path).exists():
|
||||
return Response().error("备份文件不存在").__dict__
|
||||
|
||||
# 检查新文件名是否已存在
|
||||
new_path = os.path.join(self.backup_dir, new_filename)
|
||||
if os.path.exists(new_path):
|
||||
if await anyio.Path(new_path).exists():
|
||||
return Response().error(f"文件名 '{new_filename}' 已存在").__dict__
|
||||
|
||||
# 执行重命名
|
||||
|
||||
@@ -7,6 +7,7 @@ import uuid
|
||||
from typing import Any
|
||||
|
||||
import aiofiles
|
||||
import anyio
|
||||
from quart import request
|
||||
|
||||
from astrbot.core import logger
|
||||
@@ -729,8 +730,8 @@ class KnowledgeBaseRoute(Route):
|
||||
)
|
||||
finally:
|
||||
# 清理临时文件
|
||||
if os.path.exists(temp_file_path):
|
||||
os.remove(temp_file_path)
|
||||
if await anyio.Path(temp_file_path).exists():
|
||||
await anyio.Path(temp_file_path).unlink()
|
||||
|
||||
# 获取知识库
|
||||
kb_helper = await kb_manager.get_kb(kb_id)
|
||||
|
||||
@@ -7,6 +7,7 @@ import uuid
|
||||
import wave
|
||||
from typing import Any
|
||||
|
||||
import anyio
|
||||
import jwt
|
||||
from quart import websocket
|
||||
|
||||
@@ -86,7 +87,7 @@ class LiveChatSession:
|
||||
|
||||
self.temp_audio_path = audio_path
|
||||
logger.info(
|
||||
f"[Live Chat] 音频文件已保存: {audio_path}, 大小: {os.path.getsize(audio_path)} bytes"
|
||||
f"[Live Chat] 音频文件已保存: {audio_path}, 大小: {(await anyio.Path(audio_path).stat()).st_size} bytes"
|
||||
)
|
||||
return audio_path, time.time() - start_time
|
||||
|
||||
@@ -96,9 +97,9 @@ class LiveChatSession:
|
||||
|
||||
def cleanup(self) -> None:
|
||||
"""清理临时文件"""
|
||||
if self.temp_audio_path and os.path.exists(self.temp_audio_path):
|
||||
if self.temp_audio_path and await anyio.Path(self.temp_audio_path).exists():
|
||||
try:
|
||||
os.remove(self.temp_audio_path)
|
||||
await anyio.Path(self.temp_audio_path).unlink()
|
||||
logger.debug(f"[Live Chat] 已删除临时文件: {self.temp_audio_path}")
|
||||
except Exception as e:
|
||||
logger.warning(f"[Live Chat] 删除临时文件失败: {e}")
|
||||
|
||||
@@ -251,11 +251,11 @@ class PluginRoute(Route):
|
||||
|
||||
def _load_cached_md5(self, cache_file: str) -> str | None:
|
||||
"""从缓存文件中加载MD5"""
|
||||
if not os.path.exists(cache_file):
|
||||
if not await anyio.Path(cache_file).exists():
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(cache_file, encoding="utf-8") as f:
|
||||
async with await anyio.open_file(cache_file, encoding="utf-8") as f:
|
||||
cache_data = json.load(f)
|
||||
return cache_data.get("md5")
|
||||
except Exception as e:
|
||||
@@ -311,8 +311,8 @@ class PluginRoute(Route):
|
||||
def _load_plugin_cache(self, cache_file: str):
|
||||
"""加载本地缓存的插件市场数据"""
|
||||
try:
|
||||
if os.path.exists(cache_file):
|
||||
with open(cache_file, encoding="utf-8") as f:
|
||||
if await anyio.Path(cache_file).exists():
|
||||
async with await anyio.open_file(cache_file, encoding="utf-8") as f:
|
||||
cache_data = json.load(f)
|
||||
# 检查缓存是否有效
|
||||
if "data" in cache_data and "timestamp" in cache_data:
|
||||
@@ -336,7 +336,7 @@ class PluginRoute(Route):
|
||||
"md5": md5 or "",
|
||||
}
|
||||
|
||||
with open(cache_file, "w", encoding="utf-8") as f:
|
||||
async with await anyio.open_file(cache_file, "w", encoding="utf-8") as f:
|
||||
json.dump(cache_data, f, ensure_ascii=False, indent=2)
|
||||
logger.debug(f"插件市场数据已缓存到: {cache_file}, MD5: {md5}")
|
||||
except Exception as e:
|
||||
@@ -771,13 +771,13 @@ class PluginRoute(Route):
|
||||
plugin_obj.root_dir_name,
|
||||
)
|
||||
|
||||
if not os.path.isdir(plugin_dir):
|
||||
if not await anyio.Path(plugin_dir).is_dir():
|
||||
logger.warning(f"无法找到插件目录: {plugin_dir}")
|
||||
return Response().error(f"无法找到插件 {plugin_name} 的目录").__dict__
|
||||
|
||||
readme_path = os.path.join(plugin_dir, "README.md")
|
||||
|
||||
if not os.path.isfile(readme_path):
|
||||
if not await anyio.Path(readme_path).is_file():
|
||||
logger.warning(f"插件 {plugin_name} 没有README文件")
|
||||
return Response().error(f"插件 {plugin_name} 没有README文件").__dict__
|
||||
|
||||
@@ -832,7 +832,7 @@ class PluginRoute(Route):
|
||||
plugin_obj.root_dir_name,
|
||||
)
|
||||
|
||||
if not os.path.isdir(plugin_dir):
|
||||
if not await anyio.Path(plugin_dir).is_dir():
|
||||
logger.warning(f"无法找到插件目录: {plugin_dir}")
|
||||
return Response().error(f"无法找到插件 {plugin_name} 的目录").__dict__
|
||||
|
||||
@@ -840,7 +840,7 @@ class PluginRoute(Route):
|
||||
changelog_names = ["CHANGELOG.md", "changelog.md", "CHANGELOG", "changelog"]
|
||||
for name in changelog_names:
|
||||
changelog_path = os.path.join(plugin_dir, name)
|
||||
if os.path.isfile(changelog_path):
|
||||
if await anyio.Path(changelog_path).is_file():
|
||||
try:
|
||||
async with await anyio.open_file(
|
||||
changelog_path, encoding="utf-8"
|
||||
|
||||
@@ -7,6 +7,7 @@ from collections.abc import Awaitable, Callable
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import anyio
|
||||
from quart import request, send_file
|
||||
|
||||
from astrbot.core import DEMO_MODE, logger
|
||||
@@ -184,9 +185,9 @@ class SkillsRoute(Route):
|
||||
logger.error(traceback.format_exc())
|
||||
return Response().error(str(e)).__dict__
|
||||
finally:
|
||||
if temp_path and os.path.exists(temp_path):
|
||||
if temp_path and await anyio.Path(temp_path).exists():
|
||||
try:
|
||||
os.remove(temp_path)
|
||||
await anyio.Path(temp_path).unlink()
|
||||
except Exception:
|
||||
logger.warning(f"Failed to remove temp skill file: {temp_path}")
|
||||
|
||||
@@ -239,9 +240,9 @@ class SkillsRoute(Route):
|
||||
except Exception as e:
|
||||
failed.append({"filename": filename, "error": str(e)})
|
||||
finally:
|
||||
if temp_path and os.path.exists(temp_path):
|
||||
if temp_path and await anyio.Path(temp_path).exists():
|
||||
try:
|
||||
os.remove(temp_path)
|
||||
await anyio.Path(temp_path).unlink()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user