139 lines
4.2 KiB
Python
139 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from app.database.chat import (
|
|
ChannelType,
|
|
ChatChannel,
|
|
ChatChannelResp,
|
|
)
|
|
from app.database.lazer_user import User, UserResp
|
|
from app.dependencies.database import get_db, get_redis
|
|
from app.dependencies.user import get_current_user
|
|
from app.router.v2 import api_v2_router as router
|
|
|
|
from .server import server
|
|
|
|
from fastapi import Depends, HTTPException, Query, Security
|
|
from pydantic import BaseModel, Field
|
|
from redis.asyncio import Redis
|
|
from sqlmodel import select
|
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
|
|
|
|
|
class UpdateResponse(BaseModel):
|
|
presence: list[ChatChannelResp] = Field(default_factory=list)
|
|
silences: list[Any] = Field(default_factory=list)
|
|
|
|
|
|
@router.get("/chat/updates", response_model=UpdateResponse)
|
|
async def get_update(
|
|
history_since: int | None = Query(None),
|
|
since: int | None = Query(None),
|
|
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
|
session: AsyncSession = Depends(get_db),
|
|
includes: list[str] = Query(["presence"], alias="includes[]"),
|
|
redis: Redis = Depends(get_redis),
|
|
):
|
|
resp = UpdateResponse()
|
|
if "presence" in includes:
|
|
channel_ids = server.get_user_joined_channel(current_user.id)
|
|
for channel_id in channel_ids:
|
|
channel = await ChatChannel.get(channel_id, session)
|
|
if channel:
|
|
resp.presence.append(
|
|
await ChatChannelResp.from_db(
|
|
channel,
|
|
session,
|
|
server.channels.get(channel_id, []),
|
|
current_user,
|
|
redis,
|
|
)
|
|
)
|
|
return resp
|
|
|
|
|
|
@router.put("/chat/channels/{channel}/users/{user}", response_model=ChatChannelResp)
|
|
async def join_channel(
|
|
channel: str,
|
|
user: str,
|
|
current_user: User = Security(get_current_user, scopes=["chat.write_manage"]),
|
|
session: AsyncSession = Depends(get_db),
|
|
):
|
|
db_channel = await ChatChannel.get(channel, session)
|
|
|
|
if db_channel is None:
|
|
raise HTTPException(status_code=404, detail="Channel not found")
|
|
return await server.join_channel(current_user, db_channel, session)
|
|
|
|
|
|
@router.delete(
|
|
"/chat/channels/{channel}/users/{user}",
|
|
status_code=204,
|
|
)
|
|
async def leave_channel(
|
|
channel: str,
|
|
user: str,
|
|
current_user: User = Security(get_current_user, scopes=["chat.write_manage"]),
|
|
session: AsyncSession = Depends(get_db),
|
|
):
|
|
db_channel = await ChatChannel.get(channel, session)
|
|
|
|
if db_channel is None:
|
|
raise HTTPException(status_code=404, detail="Channel not found")
|
|
await server.leave_channel(current_user, db_channel, session)
|
|
return
|
|
|
|
|
|
@router.get("/chat/channels")
|
|
async def get_channel_list(
|
|
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
|
session: AsyncSession = Depends(get_db),
|
|
redis: Redis = Depends(get_redis),
|
|
):
|
|
channels = (
|
|
await session.exec(
|
|
select(ChatChannel).where(ChatChannel.type == ChannelType.PUBLIC)
|
|
)
|
|
).all()
|
|
results = []
|
|
for channel in channels:
|
|
assert channel.channel_id is not None
|
|
results.append(
|
|
await ChatChannelResp.from_db(
|
|
channel,
|
|
session,
|
|
server.channels.get(channel.channel_id, []),
|
|
current_user,
|
|
redis,
|
|
)
|
|
)
|
|
return results
|
|
|
|
|
|
class GetChannelResp(BaseModel):
|
|
channel: ChatChannelResp
|
|
users: list[UserResp] = Field(default_factory=list)
|
|
|
|
|
|
@router.get("/chat/channels/{channel}")
|
|
async def get_channel(
|
|
channel: str,
|
|
current_user: User = Security(get_current_user, scopes=["chat.read"]),
|
|
session: AsyncSession = Depends(get_db),
|
|
redis: Redis = Depends(get_redis),
|
|
):
|
|
db_channel = await ChatChannel.get(channel, session)
|
|
if db_channel is None:
|
|
raise HTTPException(status_code=404, detail="Channel not found")
|
|
assert db_channel.channel_id is not None
|
|
return GetChannelResp(
|
|
channel=await ChatChannelResp.from_db(
|
|
db_channel,
|
|
session,
|
|
server.channels.get(db_channel.channel_id, []),
|
|
current_user,
|
|
redis,
|
|
)
|
|
)
|