290 lines
9.4 KiB
Python
290 lines
9.4 KiB
Python
from __future__ import annotations
|
||
|
||
import logging
|
||
|
||
from yuxi.channel.extensions.feishu.client import get_client
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
FEISHU_DRIVE_TOOLS = [
|
||
{
|
||
"name": "feishu_drive_list",
|
||
"description": "列出飞书云盘文件和文件夹",
|
||
"parameters": {"folder_token": "文件夹 token(可选,默认根目录)"},
|
||
},
|
||
{
|
||
"name": "feishu_drive_info",
|
||
"description": "获取飞书云盘文件信息",
|
||
"parameters": {"file_token": "文件 token"},
|
||
},
|
||
{
|
||
"name": "feishu_drive_create_folder",
|
||
"description": "创建飞书云盘文件夹",
|
||
"parameters": {"name": "文件夹名称", "folder_token": "父文件夹 token"},
|
||
},
|
||
{
|
||
"name": "feishu_drive_upload",
|
||
"description": "上传文件到飞书云盘",
|
||
"parameters": {"file_path": "本地文件路径", "parent_token": "目标文件夹 token(可选)"},
|
||
},
|
||
{
|
||
"name": "feishu_drive_download",
|
||
"description": "下载飞书云盘文件",
|
||
"parameters": {"file_token": "文件 token", "save_path": "本地保存路径(可选)"},
|
||
},
|
||
{
|
||
"name": "feishu_drive_delete",
|
||
"description": "删除飞书云盘文件或文件夹",
|
||
"parameters": {"file_token": "文件 token", "file_type": "文件类型(file/folder,默认 file)"},
|
||
},
|
||
{
|
||
"name": "feishu_drive_move",
|
||
"description": "移动飞书云盘文件到指定文件夹",
|
||
"parameters": {"file_token": "文件 token", "target_folder_token": "目标文件夹 token"},
|
||
},
|
||
]
|
||
|
||
|
||
async def list_drive_files(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
folder_token: str = "",
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.drive.v1.ListFileRequest(
|
||
folder_token=folder_token if folder_token else None,
|
||
page_size=50,
|
||
)
|
||
resp = await client.drive.v1.file.list_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
files = getattr(resp.data, "files", []) or []
|
||
return {
|
||
"success": True,
|
||
"files": [
|
||
{
|
||
"token": getattr(f, "token", ""),
|
||
"name": getattr(f, "name", ""),
|
||
"type": getattr(f, "type", ""),
|
||
"parent_token": getattr(f, "parent_token", ""),
|
||
}
|
||
for f in files
|
||
],
|
||
"has_more": getattr(resp.data, "has_more", False),
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu list_drive_files error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def get_drive_file_info(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
file_token: str,
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.drive.v1.GetFileRequest(file_token=file_token)
|
||
resp = await client.drive.v1.file.get_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
f = resp.data
|
||
return {
|
||
"success": True,
|
||
"file": {
|
||
"token": getattr(f, "token", ""),
|
||
"name": getattr(f, "name", ""),
|
||
"type": getattr(f, "type", ""),
|
||
"size": getattr(f, "size", 0),
|
||
"url": getattr(f, "url", ""),
|
||
},
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu get_drive_file_info error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def create_drive_folder(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
name: str,
|
||
folder_token: str,
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.drive.v1.CreateFolderFileRequest(
|
||
request_body=lark_oapi.drive.v1.CreateFolderFileRequestBody(
|
||
name=name,
|
||
folder_token=folder_token,
|
||
),
|
||
)
|
||
resp = await client.drive.v1.file.create_folder_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
return {
|
||
"success": True,
|
||
"token": getattr(resp.data, "token", ""),
|
||
"url": getattr(resp.data, "url", ""),
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu create_drive_folder error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def upload_drive_file(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
file_path: str,
|
||
parent_token: str = "",
|
||
file_name: str = "",
|
||
http_timeout_ms: int = 60000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
|
||
with open(file_path, "rb") as f:
|
||
req = lark_oapi.drive.v1.UploadAllMediaRequest(
|
||
request_body=lark_oapi.drive.v1.UploadAllMediaRequestBody(
|
||
file_name=file_name or file_path.rsplit("\\", 1)[-1].rsplit("/", 1)[-1],
|
||
parent_type="explorer",
|
||
parent_node=parent_token if parent_token else None,
|
||
size=str(len(f.read())),
|
||
file=f,
|
||
),
|
||
)
|
||
f.seek(0)
|
||
resp = await client.drive.v1.media.upload_all_async(req)
|
||
|
||
if resp.success() and resp.data:
|
||
return {
|
||
"success": True,
|
||
"file_token": getattr(resp.data, "file_token", ""),
|
||
"url": getattr(resp.data, "url", ""),
|
||
}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu upload_drive_file error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def download_drive_file(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
file_token: str,
|
||
save_path: str = "",
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.drive.v1.DownloadMediaRequest(file_token=file_token)
|
||
resp = await client.drive.v1.media.download_async(req)
|
||
|
||
if resp.success():
|
||
result = {"success": True, "file_token": file_token}
|
||
if resp.file and save_path:
|
||
with open(save_path, "wb") as f:
|
||
f.write(resp.file.read())
|
||
result["saved_to"] = save_path
|
||
return result
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu download_drive_file error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def delete_drive_file(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
file_token: str,
|
||
file_type: str = "file",
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.drive.v1.DeleteFileRequest(
|
||
file_token=file_token,
|
||
type=file_type,
|
||
)
|
||
resp = await client.drive.v1.file.delete_async(req)
|
||
|
||
if resp.success():
|
||
return {"success": True}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu delete_drive_file error")
|
||
return {"success": False, "error": "Internal error"}
|
||
|
||
|
||
async def move_drive_file(
|
||
app_id: str,
|
||
app_secret: str,
|
||
domain: str,
|
||
file_token: str,
|
||
target_folder_token: str,
|
||
http_timeout_ms: int = 30000,
|
||
) -> dict:
|
||
try:
|
||
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
||
|
||
import lark_oapi
|
||
req = lark_oapi.drive.v1.MoveFileRequest(
|
||
file_token=file_token,
|
||
request_body=lark_oapi.drive.v1.MoveFileRequestBody(
|
||
target_parent_token=target_folder_token,
|
||
),
|
||
)
|
||
resp = await client.drive.v1.file.move_async(req)
|
||
|
||
if resp.success():
|
||
return {"success": True}
|
||
else:
|
||
return {"success": False, "error": getattr(resp, "msg", "")}
|
||
except ImportError:
|
||
return {"success": False, "error": "lark-oapi SDK not installed"}
|
||
except Exception:
|
||
logger.exception("Feishu move_drive_file error")
|
||
return {"success": False, "error": "Internal error"}
|