Files
MoviePilot/app/agent/tools/impl/delete_transfer_history.py
T

94 lines
3.9 KiB
Python

"""删除整理历史记录工具"""
import asyncio
from typing import Optional, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool
from app.agent.tools.tags import ToolTag
from app.chain.storage import StorageChain
from app.application.agentdata import TransferHistoryPort as TransferHistoryOper
from app.runtime.log import logger
from app.schemas.workflow import FileItem
class DeleteTransferHistoryInput(BaseModel):
"""删除整理历史记录工具的输入参数模型"""
history_id: int = Field(
..., description="The ID of the transfer history record to delete"
)
def _delete_history_destination_file(fileitem: FileItem) -> tuple[bool, bool]:
"""在存储 worker 内完成旧目标检查和删除,保持历史删除前的顺序。"""
storage_chain = StorageChain()
if not storage_chain.exists(fileitem):
return False, False
return True, bool(storage_chain.delete_media_file(fileitem))
class DeleteTransferHistoryTool(MoviePilotTool):
name: str = "delete_transfer_history"
tags: list[str] = [
ToolTag.Write,
ToolTag.Transfer,
ToolTag.Admin,
]
description: str = (
"Delete a specific transfer history record by its ID. For non-successful-move records with an old "
"destination file, the tool removes that media-library file before deleting the history record. This is "
"useful before retrying or re-organizing because the system skips files that already have transfer history."
)
args_schema: Type[BaseModel] = DeleteTransferHistoryInput
require_admin: bool = True
def get_tool_message(self, **kwargs) -> Optional[str]:
"""根据参数生成友好的提示消息"""
history_id = kwargs.get("history_id")
return f"删除整理历史记录: ID={history_id}"
async def run(self, history_id: int, **kwargs) -> str:
logger.info(f"执行工具: {self.name}, 参数: history_id={history_id}")
try:
transferhis = TransferHistoryOper()
history = await transferhis.async_get(history_id)
if not history:
return f"错误:整理历史记录不存在,ID={history_id}"
title = history.title or "未知"
src = history.src or "未知"
status = "成功" if history.status else "失败"
deleted_dest = False
if history.dest_fileitem and not (history.status and history.mode == "move"):
dest_fileitem = FileItem(**history.dest_fileitem)
try:
destination_exists, destination_deleted = await self.run_blocking(
"storage",
_delete_history_destination_file,
dest_fileitem,
)
except asyncio.CancelledError:
logger.warning(
"删除整理历史的旧媒体文件等待已取消,底层文件操作可能仍在继续,"
"请确认实际状态后再重试,历史记录尚未删除,path=%s",
dest_fileitem.path,
)
raise
if destination_exists:
if not destination_deleted:
return f"错误:旧媒体库文件删除失败,路径={dest_fileitem.path}"
deleted_dest = True
await transferhis.async_delete(history_id)
message = (
f"已删除整理历史记录:ID={history_id},标题={title},源路径={src},状态={status}"
)
if deleted_dest:
message += ",已删除旧媒体库文件"
return message
except Exception as e:
logger.error(f"删除整理历史记录失败: {e}", exc_info=True)
return f"删除整理历史记录时发生错误: {str(e)}"