fix(playcount): show the sum of all users' playcount in BeatmapResp/BeatmapsetResp

This commit is contained in:
MingxuanGame
2025-10-04 10:50:33 +00:00
parent 38671cd471
commit 6f522847ec
4 changed files with 72 additions and 6 deletions

View File

@@ -193,11 +193,9 @@ class BeatmapResp(BeatmapBase):
if session: if session:
beatmap_["playcount"] = ( beatmap_["playcount"] = (
await session.exec( await session.exec(
select(func.count()) select(func.sum(BeatmapPlaycounts.playcount)).where(BeatmapPlaycounts.beatmap_id == beatmap.id)
.select_from(BeatmapPlaycounts)
.where(BeatmapPlaycounts.beatmap_id == beatmap.id)
) )
).one() ).first() or 0
beatmap_["passcount"] = ( beatmap_["passcount"] = (
await session.exec( await session.exec(
select(func.count()) select(func.count())

View File

@@ -2,6 +2,7 @@ from datetime import datetime
from typing import TYPE_CHECKING, NotRequired, Self, TypedDict from typing import TYPE_CHECKING, NotRequired, Self, TypedDict
from app.config import settings from app.config import settings
from app.database.beatmap_playcounts import BeatmapPlaycounts
from app.models.beatmap import BeatmapRankStatus, Genre, Language from app.models.beatmap import BeatmapRankStatus, Genre, Language
from app.models.score import GameMode from app.models.score import GameMode
@@ -74,7 +75,6 @@ class BeatmapsetBase(SQLModel):
covers: BeatmapCovers | None = Field(sa_column=Column(JSON)) covers: BeatmapCovers | None = Field(sa_column=Column(JSON))
creator: str = Field(index=True) creator: str = Field(index=True)
nsfw: bool = Field(default=False, sa_column=Column(Boolean)) nsfw: bool = Field(default=False, sa_column=Column(Boolean))
play_count: int = Field(index=True)
preview_url: str preview_url: str
source: str = Field(default="") source: str = Field(default="")
@@ -204,6 +204,7 @@ class BeatmapsetResp(BeatmapsetBase):
has_favourited: bool = False has_favourited: bool = False
favourite_count: int = 0 favourite_count: int = 0
recent_favourites: list[UserResp] = Field(default_factory=list) recent_favourites: list[UserResp] = Field(default_factory=list)
play_count: int = 0
@field_validator( @field_validator(
"nsfw", "nsfw",
@@ -240,7 +241,7 @@ class BeatmapsetResp(BeatmapsetBase):
session: AsyncSession | None = None, session: AsyncSession | None = None,
user: User | None = None, user: User | None = None,
) -> "BeatmapsetResp": ) -> "BeatmapsetResp":
from .beatmap import BeatmapResp from .beatmap import Beatmap, BeatmapResp
from .favourite_beatmapset import FavouriteBeatmapset from .favourite_beatmapset import FavouriteBeatmapset
update = { update = {
@@ -331,6 +332,14 @@ class BeatmapsetResp(BeatmapsetBase):
.where(FavouriteBeatmapset.beatmapset_id == beatmapset.id) .where(FavouriteBeatmapset.beatmapset_id == beatmapset.id)
) )
).one() ).one()
update["play_count"] = (
await session.exec(
select(func.sum(BeatmapPlaycounts.playcount)).where(
col(BeatmapPlaycounts.beatmap).has(col(Beatmap.beatmapset_id) == beatmapset.id)
)
)
).first() or 0
return cls.model_validate( return cls.model_validate(
update, update,
) )

View File

@@ -14,6 +14,7 @@ from app.calculator import (
pre_fetch_and_calculate_pp, pre_fetch_and_calculate_pp,
) )
from app.config import settings from app.config import settings
from app.database.beatmap_playcounts import BeatmapPlaycounts
from app.database.team import TeamMember from app.database.team import TeamMember
from app.dependencies.database import get_redis from app.dependencies.database import get_redis
from app.log import log from app.log import log
@@ -1206,6 +1207,9 @@ async def _process_statistics(
statistics.play_count += 1 statistics.play_count += 1
mouthly_playcount.count += 1 mouthly_playcount.count += 1
statistics.play_time += playtime statistics.play_time += playtime
await _process_beatmap_playcount(session, score.beatmap_id, user.id)
logger.debug( logger.debug(
"Recorded playtime {playtime}s for score {score_id} (user {user_id})", "Recorded playtime {playtime}s for score {score_id} (user {user_id})",
playtime=playtime, playtime=playtime,
@@ -1254,6 +1258,33 @@ async def _process_statistics(
) )
async def _process_beatmap_playcount(session: AsyncSession, beatmap_id: int, user_id: int):
beatmap_playcount = (
await session.exec(
select(BeatmapPlaycounts).where(
BeatmapPlaycounts.beatmap_id == beatmap_id,
BeatmapPlaycounts.user_id == user_id,
)
)
).first()
if beatmap_playcount is None:
beatmap_playcount = BeatmapPlaycounts(beatmap_id=beatmap_id, user_id=user_id, playcount=1)
session.add(beatmap_playcount)
logger.debug(
"Created beatmap playcount record for user {user_id} on beatmap {beatmap_id}",
user_id=user_id,
beatmap_id=beatmap_id,
)
else:
beatmap_playcount.playcount += 1
logger.debug(
"Incremented beatmap playcount for user {user_id} on beatmap {beatmap_id} to {count}",
user_id=user_id,
beatmap_id=beatmap_id,
count=beatmap_playcount.playcount,
)
async def process_user( async def process_user(
session: AsyncSession, session: AsyncSession,
redis: Redis, redis: Redis,

View File

@@ -0,0 +1,28 @@
"""beatmapset: remove play_count
Revision ID: ee13ad926584
Revises: 9556cd2ec11f
Create Date: 2025-10-04 10:48:00.985529
"""
from collections.abc import Sequence
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "ee13ad926584"
down_revision: str | Sequence[str] | None = "9556cd2ec11f"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Upgrade schema."""
op.drop_column("beatmapsets", "play_count")
def downgrade() -> None:
"""Downgrade schema."""
op.add_column("beatmapsets", sa.Column("play_count", sa.Integer(), nullable=False))