ForcePilot/backend/package/yuxi/channel/extensions/nextcloud_talk/conversation.py

291 lines
7.0 KiB
Python
Raw Normal View History

from __future__ import annotations
import base64
import logging
from urllib.parse import urljoin
import httpx
logger = logging.getLogger(__name__)
OCS_ROOM_PATH = "/ocs/v2.php/apps/spreed/api/v4/room"
OCS_ROOM_TOKEN_PATH = "/ocs/v2.php/apps/spreed/api/v4/room/{token}"
DEFAULT_TIMEOUT = 30.0
def _auth_headers(api_user: str, api_password: str) -> dict:
auth = base64.b64encode(f"{api_user}:{api_password}".encode()).decode()
return {
"Authorization": f"Basic {auth}",
"OCS-APIRequest": "true",
"Accept": "application/json",
}
async def list_conversations(
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> list[dict]:
url = urljoin(base_url.rstrip("/") + "/", OCS_ROOM_PATH)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.get(
url,
headers=_auth_headers(api_user, api_password),
)
if resp.status_code != 200:
logger.warning("Nextcloud Talk list conversations failed: HTTP %s", resp.status_code)
return []
data = resp.json()
return data.get("ocs", {}).get("data", [])
async def create_conversation(
base_url: str,
api_user: str,
api_password: str,
*,
room_type: int,
invite: str | None = None,
room_name: str | None = None,
timeout: float = DEFAULT_TIMEOUT,
) -> dict | None:
url = urljoin(base_url.rstrip("/") + "/", OCS_ROOM_PATH)
body: dict = {"roomType": room_type}
if invite:
body["invite"] = invite
if room_name:
body["roomName"] = room_name
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.post(
url,
json=body,
headers=_auth_headers(api_user, api_password),
)
if resp.status_code != 200:
logger.warning("Nextcloud Talk create conversation failed: HTTP %s", resp.status_code)
return None
data = resp.json()
return data.get("ocs", {}).get("data")
async def delete_conversation(
room_token: str,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
OCS_ROOM_TOKEN_PATH.format(token=room_token),
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.delete(
url,
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def rename_conversation(
room_token: str,
room_name: str,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
OCS_ROOM_TOKEN_PATH.format(token=room_token),
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.put(
url,
json={"roomName": room_name},
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def set_conversation_description(
room_token: str,
description: str,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
f"/ocs/v2.php/apps/spreed/api/v4/room/{room_token}/description",
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.put(
url,
json={"description": description},
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def set_conversation_password(
room_token: str,
password: str,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
f"/ocs/v2.php/apps/spreed/api/v4/room/{room_token}/password",
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.put(
url,
json={"password": password},
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def remove_conversation_password(
room_token: str,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
f"/ocs/v2.php/apps/spreed/api/v4/room/{room_token}/password",
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.delete(
url,
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def set_read_only(
room_token: str,
state: int,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
f"/ocs/v2.php/apps/spreed/api/v4/room/{room_token}/read-only",
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.put(
url,
json={"state": state},
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def set_message_expiration(
room_token: str,
seconds: int,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
f"/ocs/v2.php/apps/spreed/api/v4/room/{room_token}/message-expiration",
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.post(
url,
json={"seconds": seconds},
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def set_favorite(
room_token: str,
base_url: str,
api_user: str,
api_password: str,
*,
favorite: bool = True,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
action = "favorite" if favorite else "unfavorite"
url = urljoin(
base_url.rstrip("/") + "/",
f"/ocs/v2.php/apps/spreed/api/v4/room/{room_token}/{action}",
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.post(
url,
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200
async def set_notification_level(
room_token: str,
level: int,
base_url: str,
api_user: str,
api_password: str,
*,
timeout: float = DEFAULT_TIMEOUT,
) -> bool:
url = urljoin(
base_url.rstrip("/") + "/",
f"/ocs/v2.php/apps/spreed/api/v4/room/{room_token}/notify",
)
async with httpx.AsyncClient(timeout=timeout) as client:
resp = await client.post(
url,
json={"level": level},
headers=_auth_headers(api_user, api_password),
)
return resp.status_code == 200