feat(chat): support public channel chat
This commit is contained in:
138
app/router/chat/channel.py
Normal file
138
app/router/chat/channel.py
Normal file
@@ -0,0 +1,138 @@
|
||||
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,
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user