feat(multiplayer): support add/edit/remove playlist item

This commit is contained in:
MingxuanGame
2025-08-02 01:56:54 +00:00
parent 884a3f1cc2
commit 86e2313c50
5 changed files with 441 additions and 15 deletions

View File

@@ -16,7 +16,10 @@ from sqlmodel import (
ForeignKey,
Relationship,
SQLModel,
func,
select,
)
from sqlmodel.ext.asyncio.session import AsyncSession
if TYPE_CHECKING:
from .room import Room
@@ -59,9 +62,20 @@ class Playlist(PlaylistBase, table=True):
room: "Room" = Relationship()
@classmethod
async def from_hub(cls, playlist: PlaylistItem, room_id: int) -> "Playlist":
async def get_next_id_for_room(cls, room_id: int, session: AsyncSession) -> int:
stmt = select(func.coalesce(func.max(cls.id), -1) + 1).where(
cls.room_id == room_id
)
result = await session.exec(stmt)
return result.one()
@classmethod
async def from_hub(
cls, playlist: PlaylistItem, room_id: int, session: AsyncSession
) -> "Playlist":
next_id = await cls.get_next_id_for_room(room_id, session=session)
return cls(
id=playlist.id,
id=next_id,
owner_id=playlist.owner_id,
ruleset_id=playlist.ruleset_id,
beatmap_id=playlist.beatmap_id,
@@ -74,6 +88,50 @@ class Playlist(PlaylistBase, table=True):
room_id=room_id,
)
@classmethod
async def update(cls, playlist: PlaylistItem, room_id: int, session: AsyncSession):
db_playlist = await session.exec(
select(cls).where(cls.id == playlist.id, cls.room_id == room_id)
)
db_playlist = db_playlist.first()
if db_playlist is None:
raise ValueError("Playlist item not found")
db_playlist.owner_id = playlist.owner_id
db_playlist.ruleset_id = playlist.ruleset_id
db_playlist.beatmap_id = playlist.beatmap_id
db_playlist.required_mods = [
msgpack_to_apimod(mod) for mod in playlist.required_mods
]
db_playlist.allowed_mods = [
msgpack_to_apimod(mod) for mod in playlist.allowed_mods
]
db_playlist.expired = playlist.expired
db_playlist.playlist_order = playlist.order
db_playlist.played_at = playlist.played_at
db_playlist.freestyle = playlist.freestyle
await session.commit()
@classmethod
async def add_to_db(
cls, playlist: PlaylistItem, room_id: int, session: AsyncSession
):
db_playlist = await cls.from_hub(playlist, room_id, session)
session.add(db_playlist)
await session.commit()
await session.refresh(db_playlist)
playlist.id = db_playlist.id
@classmethod
async def delete_item(cls, item_id: int, room_id: int, session: AsyncSession):
db_playlist = await session.exec(
select(cls).where(cls.id == item_id, cls.room_id == room_id)
)
db_playlist = db_playlist.first()
if db_playlist is None:
raise ValueError("Playlist item not found")
await session.delete(db_playlist)
await session.commit()
class PlaylistResp(PlaylistBase):
beatmap: BeatmapResp | None = None