ForcePilot/backend/package/yuxi/channel/extensions/confluence/attachments.py

107 lines
3.7 KiB
Python
Raw Normal View History

import logging
from pathlib import Path
from yuxi.channel.extensions.confluence.gateway import ConfluenceGateway
from yuxi.channel.extensions.confluence.types import OutboundResult
logger = logging.getLogger(__name__)
class ConfluenceAttachmentManager:
def __init__(self, gateway: ConfluenceGateway):
self._gateway = gateway
async def list_attachments(
self, page_id: str, account_id: str = "default",
) -> list[dict]:
client = self._gateway.get_client(account_id)
if client is None:
return []
try:
result = await client._request(
"GET", f"/wiki/api/v2/pages/{page_id}/attachments",
)
return result.get("results", [])
except Exception as e:
logger.error("Failed to list attachments for page %s: %s", page_id, e)
return []
async def get_attachment(
self, attachment_id: str, account_id: str = "default",
) -> dict | None:
client = self._gateway.get_client(account_id)
if client is None:
return None
try:
return await client._request(
"GET", f"/wiki/api/v2/attachments/{attachment_id}",
)
except Exception as e:
logger.error("Failed to get attachment %s: %s", attachment_id, e)
return None
async def upload_attachment(
self,
page_id: str,
file_path: str,
filename: str | None = None,
account_id: str = "default",
) -> OutboundResult:
client = self._gateway.get_client(account_id)
if client is None:
return OutboundResult(success=False, error="Client not found")
path = Path(file_path)
if not path.exists():
return OutboundResult(success=False, error=f"File not found: {file_path}")
fname = filename or path.name
try:
result = await client._request(
"POST",
f"/wiki/api/v2/pages/{page_id}/attachments",
files={"file": (fname, path.read_bytes(), "application/octet-stream")},
)
return OutboundResult(success=True, comment_id=result.get("id", ""))
except Exception as e:
logger.error("Failed to upload attachment to page %s: %s", page_id, e)
return OutboundResult(success=False, error=str(e))
async def download_attachment(
self,
page_id: str,
filename: str,
save_path: str,
account_id: str = "default",
) -> str | None:
client = self._gateway.get_client(account_id)
if client is None:
return None
try:
url = f"/download/attachments/{page_id}/{filename}"
if client._http is None:
raise RuntimeError("Client not initialized")
resp = await client._http.get(url)
resp.raise_for_status()
Path(save_path).write_bytes(resp.content)
return save_path
except Exception as e:
logger.error("Failed to download attachment %s: %s", filename, e)
return None
async def delete_attachment(
self, attachment_id: str, account_id: str = "default",
) -> OutboundResult:
client = self._gateway.get_client(account_id)
if client is None:
return OutboundResult(success=False, error="Client not found")
try:
await client._request(
"DELETE", f"/wiki/api/v2/attachments/{attachment_id}",
)
return OutboundResult(success=True, comment_id=attachment_id)
except Exception as e:
logger.error("Failed to delete attachment %s: %s", attachment_id, e)
return OutboundResult(success=False, error=str(e))