refactor(scores): rename models of score to match with filename
This commit is contained in:
@@ -12,7 +12,7 @@ from .beatmapset import (
|
|||||||
BeatmapsetResp,
|
BeatmapsetResp,
|
||||||
)
|
)
|
||||||
from .beatmapset_ratings import BeatmapRating
|
from .beatmapset_ratings import BeatmapRating
|
||||||
from .best_scores import PPBestScore
|
from .best_scores import BestScore
|
||||||
from .chat import (
|
from .chat import (
|
||||||
ChannelType,
|
ChannelType,
|
||||||
ChatChannel,
|
ChatChannel,
|
||||||
@@ -56,7 +56,7 @@ from .statistics import (
|
|||||||
UserStatisticsResp,
|
UserStatisticsResp,
|
||||||
)
|
)
|
||||||
from .team import Team, TeamMember, TeamRequest
|
from .team import Team, TeamMember, TeamRequest
|
||||||
from .total_score_best_scores import BestScore
|
from .total_score_best_scores import TotalScoreBestScore
|
||||||
from .user import (
|
from .user import (
|
||||||
MeResp,
|
MeResp,
|
||||||
User,
|
User,
|
||||||
@@ -105,7 +105,6 @@ __all__ = [
|
|||||||
"Notification",
|
"Notification",
|
||||||
"OAuthClient",
|
"OAuthClient",
|
||||||
"OAuthToken",
|
"OAuthToken",
|
||||||
"PPBestScore",
|
|
||||||
"PasswordReset",
|
"PasswordReset",
|
||||||
"Playlist",
|
"Playlist",
|
||||||
"PlaylistAggregateScore",
|
"PlaylistAggregateScore",
|
||||||
@@ -131,6 +130,7 @@ __all__ = [
|
|||||||
"Team",
|
"Team",
|
||||||
"TeamMember",
|
"TeamMember",
|
||||||
"TeamRequest",
|
"TeamRequest",
|
||||||
|
"TotalScoreBestScore",
|
||||||
"TotpKeys",
|
"TotpKeys",
|
||||||
"TrustedDevice",
|
"TrustedDevice",
|
||||||
"TrustedDeviceResp",
|
"TrustedDeviceResp",
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
|
|||||||
from .score import Score
|
from .score import Score
|
||||||
|
|
||||||
|
|
||||||
class PPBestScore(SQLModel, table=True):
|
class BestScore(SQLModel, table=True):
|
||||||
__tablename__: str = "best_scores"
|
__tablename__: str = "best_scores"
|
||||||
user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True))
|
user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True))
|
||||||
score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True))
|
score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True))
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ from app.utils import utcnow
|
|||||||
|
|
||||||
from .beatmap import Beatmap, BeatmapResp
|
from .beatmap import Beatmap, BeatmapResp
|
||||||
from .beatmapset import BeatmapsetResp
|
from .beatmapset import BeatmapsetResp
|
||||||
from .best_scores import PPBestScore
|
from .best_scores import BestScore
|
||||||
from .counts import MonthlyPlaycounts
|
from .counts import MonthlyPlaycounts
|
||||||
from .events import Event, EventType
|
from .events import Event, EventType
|
||||||
from .playlist_best_score import PlaylistBestScore
|
from .playlist_best_score import PlaylistBestScore
|
||||||
@@ -47,7 +47,7 @@ from .relationship import (
|
|||||||
RelationshipType,
|
RelationshipType,
|
||||||
)
|
)
|
||||||
from .score_token import ScoreToken
|
from .score_token import ScoreToken
|
||||||
from .total_score_best_scores import BestScore
|
from .total_score_best_scores import TotalScoreBestScore
|
||||||
from .user import User, UserResp
|
from .user import User, UserResp
|
||||||
|
|
||||||
from pydantic import BaseModel, field_serializer, field_validator
|
from pydantic import BaseModel, field_serializer, field_validator
|
||||||
@@ -195,13 +195,13 @@ class Score(ScoreBase, table=True):
|
|||||||
# optional
|
# optional
|
||||||
beatmap: Mapped[Beatmap] = Relationship()
|
beatmap: Mapped[Beatmap] = Relationship()
|
||||||
user: Mapped[User] = Relationship(sa_relationship_kwargs={"lazy": "joined"})
|
user: Mapped[User] = Relationship(sa_relationship_kwargs={"lazy": "joined"})
|
||||||
best_score: Mapped[BestScore | None] = Relationship(
|
best_score: Mapped[TotalScoreBestScore | None] = Relationship(
|
||||||
back_populates="score",
|
back_populates="score",
|
||||||
sa_relationship_kwargs={
|
sa_relationship_kwargs={
|
||||||
"cascade": "all, delete-orphan",
|
"cascade": "all, delete-orphan",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
ranked_score: Mapped[PPBestScore | None] = Relationship(
|
ranked_score: Mapped[BestScore | None] = Relationship(
|
||||||
back_populates="score",
|
back_populates="score",
|
||||||
sa_relationship_kwargs={
|
sa_relationship_kwargs={
|
||||||
"cascade": "all, delete-orphan",
|
"cascade": "all, delete-orphan",
|
||||||
@@ -481,10 +481,10 @@ class ScoreAround(SQLModel):
|
|||||||
async def get_best_id(session: AsyncSession, score_id: int) -> int | None:
|
async def get_best_id(session: AsyncSession, score_id: int) -> int | None:
|
||||||
rownum = (
|
rownum = (
|
||||||
func.row_number()
|
func.row_number()
|
||||||
.over(partition_by=(col(PPBestScore.user_id), col(PPBestScore.gamemode)), order_by=col(PPBestScore.pp).desc())
|
.over(partition_by=(col(BestScore.user_id), col(BestScore.gamemode)), order_by=col(BestScore.pp).desc())
|
||||||
.label("rn")
|
.label("rn")
|
||||||
)
|
)
|
||||||
subq = select(PPBestScore, rownum).subquery()
|
subq = select(BestScore, rownum).subquery()
|
||||||
stmt = select(subq.c.rn).where(subq.c.score_id == score_id)
|
stmt = select(subq.c.rn).where(subq.c.score_id == score_id)
|
||||||
result = await session.exec(stmt)
|
result = await session.exec(stmt)
|
||||||
return result.one_or_none()
|
return result.one_or_none()
|
||||||
@@ -498,8 +498,8 @@ async def _score_where(
|
|||||||
user: User | None = None,
|
user: User | None = None,
|
||||||
) -> list[ColumnElement[bool] | TextClause] | None:
|
) -> list[ColumnElement[bool] | TextClause] | None:
|
||||||
wheres: list[ColumnElement[bool] | TextClause] = [
|
wheres: list[ColumnElement[bool] | TextClause] = [
|
||||||
col(BestScore.beatmap_id) == beatmap,
|
col(TotalScoreBestScore.beatmap_id) == beatmap,
|
||||||
col(BestScore.gamemode) == mode,
|
col(TotalScoreBestScore.gamemode) == mode,
|
||||||
]
|
]
|
||||||
|
|
||||||
if type == LeaderboardType.FRIENDS:
|
if type == LeaderboardType.FRIENDS:
|
||||||
@@ -512,19 +512,21 @@ async def _score_where(
|
|||||||
)
|
)
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
wheres.append(col(BestScore.user_id).in_(select(subq.c.target_id)))
|
wheres.append(col(TotalScoreBestScore.user_id).in_(select(subq.c.target_id)))
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
elif type == LeaderboardType.COUNTRY:
|
elif type == LeaderboardType.COUNTRY:
|
||||||
if user and user.is_supporter:
|
if user and user.is_supporter:
|
||||||
wheres.append(col(BestScore.user).has(col(User.country_code) == user.country_code))
|
wheres.append(col(TotalScoreBestScore.user).has(col(User.country_code) == user.country_code))
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
elif type == LeaderboardType.TEAM and user:
|
elif type == LeaderboardType.TEAM and user:
|
||||||
team_membership = await user.awaitable_attrs.team_membership
|
team_membership = await user.awaitable_attrs.team_membership
|
||||||
if team_membership:
|
if team_membership:
|
||||||
team_id = team_membership.team_id
|
team_id = team_membership.team_id
|
||||||
wheres.append(col(BestScore.user).has(col(User.team_membership).has(TeamMember.team_id == team_id)))
|
wheres.append(
|
||||||
|
col(TotalScoreBestScore.user).has(col(User.team_membership).has(TeamMember.team_id == team_id))
|
||||||
|
)
|
||||||
if mods:
|
if mods:
|
||||||
if user and user.is_supporter:
|
if user and user.is_supporter:
|
||||||
wheres.append(
|
wheres.append(
|
||||||
@@ -558,10 +560,10 @@ async def get_leaderboard(
|
|||||||
max_score = sys.maxsize
|
max_score = sys.maxsize
|
||||||
while limit > 0:
|
while limit > 0:
|
||||||
query = (
|
query = (
|
||||||
select(BestScore)
|
select(TotalScoreBestScore)
|
||||||
.where(*wheres, BestScore.total_score < max_score)
|
.where(*wheres, TotalScoreBestScore.total_score < max_score)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.order_by(col(BestScore.total_score).desc())
|
.order_by(col(TotalScoreBestScore.total_score).desc())
|
||||||
)
|
)
|
||||||
extra_need = 0
|
extra_need = 0
|
||||||
for s in await session.exec(query):
|
for s in await session.exec(query):
|
||||||
@@ -580,13 +582,13 @@ async def get_leaderboard(
|
|||||||
user_score = None
|
user_score = None
|
||||||
if user:
|
if user:
|
||||||
self_query = (
|
self_query = (
|
||||||
select(BestScore)
|
select(TotalScoreBestScore)
|
||||||
.where(BestScore.user_id == user.id)
|
.where(TotalScoreBestScore.user_id == user.id)
|
||||||
.where(
|
.where(
|
||||||
col(BestScore.beatmap_id) == beatmap,
|
col(TotalScoreBestScore.beatmap_id) == beatmap,
|
||||||
col(BestScore.gamemode) == mode,
|
col(TotalScoreBestScore.gamemode) == mode,
|
||||||
)
|
)
|
||||||
.order_by(col(BestScore.total_score).desc())
|
.order_by(col(TotalScoreBestScore.total_score).desc())
|
||||||
.limit(1)
|
.limit(1)
|
||||||
)
|
)
|
||||||
if mods:
|
if mods:
|
||||||
@@ -619,14 +621,14 @@ async def get_score_position_by_user(
|
|||||||
func.row_number()
|
func.row_number()
|
||||||
.over(
|
.over(
|
||||||
partition_by=(
|
partition_by=(
|
||||||
col(BestScore.beatmap_id),
|
col(TotalScoreBestScore.beatmap_id),
|
||||||
col(BestScore.gamemode),
|
col(TotalScoreBestScore.gamemode),
|
||||||
),
|
),
|
||||||
order_by=col(BestScore.total_score).desc(),
|
order_by=col(TotalScoreBestScore.total_score).desc(),
|
||||||
)
|
)
|
||||||
.label("row_number")
|
.label("row_number")
|
||||||
)
|
)
|
||||||
subq = select(BestScore, rownum).join(Beatmap).where(*wheres).subquery()
|
subq = select(TotalScoreBestScore, rownum).join(Beatmap).where(*wheres).subquery()
|
||||||
stmt = select(subq.c.row_number).where(subq.c.user_id == user.id)
|
stmt = select(subq.c.row_number).where(subq.c.user_id == user.id)
|
||||||
result = await session.exec(stmt)
|
result = await session.exec(stmt)
|
||||||
s = result.first()
|
s = result.first()
|
||||||
@@ -649,14 +651,14 @@ async def get_score_position_by_id(
|
|||||||
func.row_number()
|
func.row_number()
|
||||||
.over(
|
.over(
|
||||||
partition_by=(
|
partition_by=(
|
||||||
col(BestScore.beatmap_id),
|
col(TotalScoreBestScore.beatmap_id),
|
||||||
col(BestScore.gamemode),
|
col(TotalScoreBestScore.gamemode),
|
||||||
),
|
),
|
||||||
order_by=col(BestScore.total_score).desc(),
|
order_by=col(TotalScoreBestScore.total_score).desc(),
|
||||||
)
|
)
|
||||||
.label("row_number")
|
.label("row_number")
|
||||||
)
|
)
|
||||||
subq = select(BestScore, rownum).join(Beatmap).where(*wheres).subquery()
|
subq = select(TotalScoreBestScore, rownum).join(Beatmap).where(*wheres).subquery()
|
||||||
stmt = select(subq.c.row_number).where(subq.c.score_id == score_id)
|
stmt = select(subq.c.row_number).where(subq.c.score_id == score_id)
|
||||||
result = await session.exec(stmt)
|
result = await session.exec(stmt)
|
||||||
s = result.one_or_none()
|
s = result.one_or_none()
|
||||||
@@ -668,16 +670,16 @@ async def get_user_best_score_in_beatmap(
|
|||||||
beatmap: int,
|
beatmap: int,
|
||||||
user: int,
|
user: int,
|
||||||
mode: GameMode | None = None,
|
mode: GameMode | None = None,
|
||||||
) -> BestScore | None:
|
) -> TotalScoreBestScore | None:
|
||||||
return (
|
return (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(BestScore)
|
select(TotalScoreBestScore)
|
||||||
.where(
|
.where(
|
||||||
BestScore.gamemode == mode if mode is not None else true(),
|
TotalScoreBestScore.gamemode == mode if mode is not None else true(),
|
||||||
BestScore.beatmap_id == beatmap,
|
TotalScoreBestScore.beatmap_id == beatmap,
|
||||||
BestScore.user_id == user,
|
TotalScoreBestScore.user_id == user,
|
||||||
)
|
)
|
||||||
.order_by(col(BestScore.total_score).desc())
|
.order_by(col(TotalScoreBestScore.total_score).desc())
|
||||||
)
|
)
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
@@ -688,32 +690,32 @@ async def get_user_best_score_with_mod_in_beatmap(
|
|||||||
user: int,
|
user: int,
|
||||||
mod: list[str],
|
mod: list[str],
|
||||||
mode: GameMode | None = None,
|
mode: GameMode | None = None,
|
||||||
) -> BestScore | None:
|
) -> TotalScoreBestScore | None:
|
||||||
return (
|
return (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(BestScore)
|
select(TotalScoreBestScore)
|
||||||
.where(
|
.where(
|
||||||
BestScore.gamemode == mode if mode is not None else True,
|
TotalScoreBestScore.gamemode == mode if mode is not None else True,
|
||||||
BestScore.beatmap_id == beatmap,
|
TotalScoreBestScore.beatmap_id == beatmap,
|
||||||
BestScore.user_id == user,
|
TotalScoreBestScore.user_id == user,
|
||||||
text(
|
text(
|
||||||
"JSON_CONTAINS(total_score_best_scores.mods, :w)"
|
"JSON_CONTAINS(total_score_best_scores.mods, :w)"
|
||||||
" AND JSON_CONTAINS(:w, total_score_best_scores.mods)"
|
" AND JSON_CONTAINS(:w, total_score_best_scores.mods)"
|
||||||
).params(w=json.dumps(mod)),
|
).params(w=json.dumps(mod)),
|
||||||
)
|
)
|
||||||
.order_by(col(BestScore.total_score).desc())
|
.order_by(col(TotalScoreBestScore.total_score).desc())
|
||||||
)
|
)
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
|
|
||||||
async def get_user_first_scores(
|
async def get_user_first_scores(
|
||||||
session: AsyncSession, user_id: int, mode: GameMode, limit: int = 5, offset: int = 0
|
session: AsyncSession, user_id: int, mode: GameMode, limit: int = 5, offset: int = 0
|
||||||
) -> list[BestScore]:
|
) -> list[TotalScoreBestScore]:
|
||||||
rownum = (
|
rownum = (
|
||||||
func.row_number()
|
func.row_number()
|
||||||
.over(
|
.over(
|
||||||
partition_by=(col(BestScore.beatmap_id), col(BestScore.gamemode)),
|
partition_by=(col(TotalScoreBestScore.beatmap_id), col(TotalScoreBestScore.gamemode)),
|
||||||
order_by=col(BestScore.total_score).desc(),
|
order_by=col(TotalScoreBestScore.total_score).desc(),
|
||||||
)
|
)
|
||||||
.label("rn")
|
.label("rn")
|
||||||
)
|
)
|
||||||
@@ -721,11 +723,11 @@ async def get_user_first_scores(
|
|||||||
# Step 1: Fetch top score_ids in Python
|
# Step 1: Fetch top score_ids in Python
|
||||||
subq = (
|
subq = (
|
||||||
select(
|
select(
|
||||||
col(BestScore.score_id).label("score_id"),
|
col(TotalScoreBestScore.score_id).label("score_id"),
|
||||||
col(BestScore.user_id).label("user_id"),
|
col(TotalScoreBestScore.user_id).label("user_id"),
|
||||||
rownum,
|
rownum,
|
||||||
)
|
)
|
||||||
.where(col(BestScore.gamemode) == mode)
|
.where(col(TotalScoreBestScore.gamemode) == mode)
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -734,7 +736,11 @@ async def get_user_first_scores(
|
|||||||
top_ids = await session.exec(top_ids_stmt)
|
top_ids = await session.exec(top_ids_stmt)
|
||||||
top_ids = list(top_ids)
|
top_ids = list(top_ids)
|
||||||
|
|
||||||
stmt = select(BestScore).where(col(BestScore.score_id).in_(top_ids)).order_by(col(BestScore.total_score).desc())
|
stmt = (
|
||||||
|
select(TotalScoreBestScore)
|
||||||
|
.where(col(TotalScoreBestScore.score_id).in_(top_ids))
|
||||||
|
.order_by(col(TotalScoreBestScore.total_score).desc())
|
||||||
|
)
|
||||||
|
|
||||||
result = await session.exec(stmt)
|
result = await session.exec(stmt)
|
||||||
return list(result.all())
|
return list(result.all())
|
||||||
@@ -744,18 +750,18 @@ async def get_user_first_score_count(session: AsyncSession, user_id: int, mode:
|
|||||||
rownum = (
|
rownum = (
|
||||||
func.row_number()
|
func.row_number()
|
||||||
.over(
|
.over(
|
||||||
partition_by=(col(BestScore.beatmap_id), col(BestScore.gamemode)),
|
partition_by=(col(TotalScoreBestScore.beatmap_id), col(TotalScoreBestScore.gamemode)),
|
||||||
order_by=col(BestScore.total_score).desc(),
|
order_by=col(TotalScoreBestScore.total_score).desc(),
|
||||||
)
|
)
|
||||||
.label("rn")
|
.label("rn")
|
||||||
)
|
)
|
||||||
subq = (
|
subq = (
|
||||||
select(
|
select(
|
||||||
col(BestScore.score_id).label("score_id"),
|
col(TotalScoreBestScore.score_id).label("score_id"),
|
||||||
col(BestScore.user_id).label("user_id"),
|
col(TotalScoreBestScore.user_id).label("user_id"),
|
||||||
rownum,
|
rownum,
|
||||||
)
|
)
|
||||||
.where(col(BestScore.gamemode) == mode)
|
.where(col(TotalScoreBestScore.gamemode) == mode)
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
count_stmt = select(func.count()).where(subq.c.rn == 1, subq.c.user_id == user_id)
|
count_stmt = select(func.count()).where(subq.c.rn == 1, subq.c.user_id == user_id)
|
||||||
@@ -769,13 +775,13 @@ async def get_user_best_pp_in_beatmap(
|
|||||||
beatmap: int,
|
beatmap: int,
|
||||||
user: int,
|
user: int,
|
||||||
mode: GameMode,
|
mode: GameMode,
|
||||||
) -> PPBestScore | None:
|
) -> BestScore | None:
|
||||||
return (
|
return (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(PPBestScore).where(
|
select(BestScore).where(
|
||||||
PPBestScore.beatmap_id == beatmap,
|
BestScore.beatmap_id == beatmap,
|
||||||
PPBestScore.user_id == user,
|
BestScore.user_id == user,
|
||||||
PPBestScore.gamemode == mode,
|
BestScore.gamemode == mode,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).first()
|
).first()
|
||||||
@@ -800,12 +806,12 @@ async def get_user_best_pp(
|
|||||||
user: int,
|
user: int,
|
||||||
mode: GameMode,
|
mode: GameMode,
|
||||||
limit: int = 1000,
|
limit: int = 1000,
|
||||||
) -> Sequence[PPBestScore]:
|
) -> Sequence[BestScore]:
|
||||||
return (
|
return (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(PPBestScore)
|
select(BestScore)
|
||||||
.where(PPBestScore.user_id == user, PPBestScore.gamemode == mode)
|
.where(BestScore.user_id == user, BestScore.gamemode == mode)
|
||||||
.order_by(col(PPBestScore.pp).desc())
|
.order_by(col(BestScore.pp).desc())
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
)
|
)
|
||||||
).all()
|
).all()
|
||||||
@@ -936,7 +942,7 @@ async def _process_score_pp(score: Score, session: AsyncSession, redis: Redis, f
|
|||||||
beatmap_id = score.beatmap_id
|
beatmap_id = score.beatmap_id
|
||||||
previous_pp_best = await get_user_best_pp_in_beatmap(session, beatmap_id, user_id, score.gamemode)
|
previous_pp_best = await get_user_best_pp_in_beatmap(session, beatmap_id, user_id, score.gamemode)
|
||||||
if previous_pp_best is None or score.pp > previous_pp_best.pp:
|
if previous_pp_best is None or score.pp > previous_pp_best.pp:
|
||||||
best_score = PPBestScore(
|
best_score = BestScore(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
score_id=score.id,
|
score_id=score.id,
|
||||||
beatmap_id=beatmap_id,
|
beatmap_id=beatmap_id,
|
||||||
@@ -1010,12 +1016,12 @@ async def _process_score_events(score: Score, session: AsyncSession):
|
|||||||
if rank_global == 1:
|
if rank_global == 1:
|
||||||
displaced_score = (
|
displaced_score = (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(BestScore)
|
select(TotalScoreBestScore)
|
||||||
.where(
|
.where(
|
||||||
BestScore.beatmap_id == score.beatmap_id,
|
TotalScoreBestScore.beatmap_id == score.beatmap_id,
|
||||||
BestScore.gamemode == score.gamemode,
|
TotalScoreBestScore.gamemode == score.gamemode,
|
||||||
)
|
)
|
||||||
.order_by(col(BestScore.total_score).desc())
|
.order_by(col(TotalScoreBestScore.total_score).desc())
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.offset(1)
|
.offset(1)
|
||||||
)
|
)
|
||||||
@@ -1139,7 +1145,7 @@ async def _process_statistics(
|
|||||||
# 情况2: 有最佳分数记录但没有该mod组合的记录,添加新记录
|
# 情况2: 有最佳分数记录但没有该mod组合的记录,添加新记录
|
||||||
if previous_score_best is None or previous_score_best_mod is None:
|
if previous_score_best is None or previous_score_best_mod is None:
|
||||||
session.add(
|
session.add(
|
||||||
BestScore(
|
TotalScoreBestScore(
|
||||||
user_id=user.id,
|
user_id=user.id,
|
||||||
beatmap_id=score.beatmap_id,
|
beatmap_id=score.beatmap_id,
|
||||||
gamemode=score.gamemode,
|
gamemode=score.gamemode,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|||||||
from .score import Score
|
from .score import Score
|
||||||
|
|
||||||
|
|
||||||
class BestScore(SQLModel, table=True):
|
class TotalScoreBestScore(SQLModel, table=True):
|
||||||
__tablename__: str = "total_score_best_scores"
|
__tablename__: str = "total_score_best_scores"
|
||||||
user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True))
|
user_id: int = Field(sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True))
|
||||||
score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True))
|
score_id: int = Field(sa_column=Column(BigInteger, ForeignKey("scores.id"), primary_key=True))
|
||||||
@@ -41,7 +41,7 @@ class BestScore(SQLModel, table=True):
|
|||||||
user: User = Relationship()
|
user: User = Relationship()
|
||||||
score: "Score" = Relationship(
|
score: "Score" = Relationship(
|
||||||
sa_relationship_kwargs={
|
sa_relationship_kwargs={
|
||||||
"foreign_keys": "[BestScore.score_id]",
|
"foreign_keys": "[TotalScoreBestScore.score_id]",
|
||||||
"lazy": "joined",
|
"lazy": "joined",
|
||||||
},
|
},
|
||||||
back_populates="best_score",
|
back_populates="best_score",
|
||||||
@@ -75,7 +75,7 @@ class BestScore(SQLModel, table=True):
|
|||||||
await session.exec(
|
await session.exec(
|
||||||
select(func.max(Score.max_combo)).where(
|
select(func.max(Score.max_combo)).where(
|
||||||
Score.user_id == self.user_id,
|
Score.user_id == self.user_id,
|
||||||
col(Score.id).in_(select(BestScore.score_id)),
|
col(Score.id).in_(select(TotalScoreBestScore.score_id)),
|
||||||
Score.gamemode == self.gamemode,
|
Score.gamemode == self.gamemode,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -259,11 +259,11 @@ class UserResp(UserBase):
|
|||||||
) -> "UserResp":
|
) -> "UserResp":
|
||||||
from app.dependencies.database import get_redis
|
from app.dependencies.database import get_redis
|
||||||
|
|
||||||
from .best_scores import PPBestScore
|
from .best_scores import BestScore
|
||||||
from .favourite_beatmapset import FavouriteBeatmapset
|
from .favourite_beatmapset import FavouriteBeatmapset
|
||||||
from .relationship import Relationship, RelationshipResp, RelationshipType
|
from .relationship import Relationship, RelationshipResp, RelationshipType
|
||||||
from .score import Score, get_user_first_score_count
|
from .score import Score, get_user_first_score_count
|
||||||
from .total_score_best_scores import BestScore
|
from .total_score_best_scores import TotalScoreBestScore
|
||||||
|
|
||||||
ruleset = ruleset or obj.playmode
|
ruleset = ruleset or obj.playmode
|
||||||
|
|
||||||
@@ -284,9 +284,9 @@ class UserResp(UserBase):
|
|||||||
u.scores_best_count = (
|
u.scores_best_count = (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(func.count())
|
select(func.count())
|
||||||
.select_from(BestScore)
|
.select_from(TotalScoreBestScore)
|
||||||
.where(
|
.where(
|
||||||
BestScore.user_id == obj.id,
|
TotalScoreBestScore.user_id == obj.id,
|
||||||
)
|
)
|
||||||
.limit(200)
|
.limit(200)
|
||||||
)
|
)
|
||||||
@@ -391,10 +391,10 @@ class UserResp(UserBase):
|
|||||||
u.scores_best_count = (
|
u.scores_best_count = (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(func.count())
|
select(func.count())
|
||||||
.select_from(PPBestScore)
|
.select_from(BestScore)
|
||||||
.where(
|
.where(
|
||||||
PPBestScore.user_id == obj.id,
|
BestScore.user_id == obj.id,
|
||||||
PPBestScore.gamemode == ruleset,
|
BestScore.gamemode == ruleset,
|
||||||
)
|
)
|
||||||
.limit(200)
|
.limit(200)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Annotated, Literal
|
from typing import Annotated, Literal
|
||||||
|
|
||||||
from app.database.best_scores import PPBestScore
|
from app.database.best_scores import BestScore
|
||||||
from app.database.score import Score, get_leaderboard
|
from app.database.score import Score, get_leaderboard
|
||||||
from app.dependencies.database import Database
|
from app.dependencies.database import Database
|
||||||
from app.models.mods import int_to_mods, mod_to_save, mods_to_int
|
from app.models.mods import int_to_mods, mod_to_save, mods_to_int
|
||||||
@@ -79,7 +79,7 @@ async def get_user_best(
|
|||||||
.where(
|
.where(
|
||||||
Score.user_id == user if type == "id" or user.isdigit() else col(Score.user).has(username=user),
|
Score.user_id == user if type == "id" or user.isdigit() else col(Score.user).has(username=user),
|
||||||
Score.gamemode == GameMode.from_int_extra(ruleset_id),
|
Score.gamemode == GameMode.from_int_extra(ruleset_id),
|
||||||
exists().where(col(PPBestScore.score_id) == Score.id),
|
exists().where(col(BestScore.score_id) == Score.id),
|
||||||
)
|
)
|
||||||
.order_by(col(Score.pp).desc())
|
.order_by(col(Score.pp).desc())
|
||||||
.options(joinedload(Score.beatmap))
|
.options(joinedload(Score.beatmap))
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from app.database import (
|
|||||||
User,
|
User,
|
||||||
UserResp,
|
UserResp,
|
||||||
)
|
)
|
||||||
from app.database.best_scores import PPBestScore
|
from app.database.best_scores import BestScore
|
||||||
from app.database.events import Event
|
from app.database.events import Event
|
||||||
from app.database.score import LegacyScoreResp, Score, ScoreResp, get_user_first_scores
|
from app.database.score import LegacyScoreResp, Score, ScoreResp, get_user_first_scores
|
||||||
from app.database.user import SEARCH_INCLUDED
|
from app.database.user import SEARCH_INCLUDED
|
||||||
@@ -392,7 +392,7 @@ async def get_user_scores(
|
|||||||
where_clause &= Score.pinned_order > 0
|
where_clause &= Score.pinned_order > 0
|
||||||
order_by = col(Score.pinned_order).asc()
|
order_by = col(Score.pinned_order).asc()
|
||||||
elif type == "best":
|
elif type == "best":
|
||||||
where_clause &= exists().where(col(PPBestScore.score_id) == Score.id)
|
where_clause &= exists().where(col(BestScore.score_id) == Score.id)
|
||||||
order_by = col(Score.pp).desc()
|
order_by = col(Score.pp).desc()
|
||||||
elif type == "recent":
|
elif type == "recent":
|
||||||
where_clause &= Score.ended_at > utcnow() - timedelta(hours=24)
|
where_clause &= Score.ended_at > utcnow() - timedelta(hours=24)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import json
|
|||||||
from app.calculator import calculate_pp
|
from app.calculator import calculate_pp
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
from app.database.beatmap import BannedBeatmaps, Beatmap
|
from app.database.beatmap import BannedBeatmaps, Beatmap
|
||||||
from app.database.best_scores import PPBestScore
|
from app.database.best_scores import BestScore
|
||||||
from app.database.score import Score, calculate_user_pp
|
from app.database.score import Score, calculate_user_pp
|
||||||
from app.database.statistics import UserStatistics
|
from app.database.statistics import UserStatistics
|
||||||
from app.dependencies.database import get_redis, with_db
|
from app.dependencies.database import get_redis, with_db
|
||||||
@@ -35,7 +35,7 @@ async def recalculate_banned_beatmap():
|
|||||||
unbanned_beatmaps = [b for b in last_banned_beatmaps if b not in current_banned]
|
unbanned_beatmaps = [b for b in last_banned_beatmaps if b not in current_banned]
|
||||||
for i in new_banned_beatmaps:
|
for i in new_banned_beatmaps:
|
||||||
last_banned_beatmaps.add(i)
|
last_banned_beatmaps.add(i)
|
||||||
await session.execute(delete(PPBestScore).where(col(PPBestScore.beatmap_id) == i))
|
await session.execute(delete(BestScore).where(col(BestScore.beatmap_id) == i))
|
||||||
scores = (await session.exec(select(Score).where(Score.beatmap_id == i, Score.pp > 0))).all()
|
scores = (await session.exec(select(Score).where(Score.beatmap_id == i, Score.pp > 0))).all()
|
||||||
for score in scores:
|
for score in scores:
|
||||||
score.pp = 0
|
score.pp = 0
|
||||||
@@ -58,7 +58,7 @@ async def recalculate_banned_beatmap():
|
|||||||
logger.exception(f"Failed to query scores for unbanned beatmap {beatmap_id}")
|
logger.exception(f"Failed to query scores for unbanned beatmap {beatmap_id}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
prev: dict[tuple[int, int], PPBestScore] = {}
|
prev: dict[tuple[int, int], BestScore] = {}
|
||||||
for score in scores:
|
for score in scores:
|
||||||
attempts = 3
|
attempts = 3
|
||||||
while attempts > 0:
|
while attempts > 0:
|
||||||
@@ -90,7 +90,7 @@ async def recalculate_banned_beatmap():
|
|||||||
continue
|
continue
|
||||||
key = (score.beatmap_id, score.user_id)
|
key = (score.beatmap_id, score.user_id)
|
||||||
if key not in prev or prev[key].pp < pp:
|
if key not in prev or prev[key].pp < pp:
|
||||||
best_score = PPBestScore(
|
best_score = BestScore(
|
||||||
user_id=score.user_id,
|
user_id=score.user_id,
|
||||||
beatmap_id=beatmap_id,
|
beatmap_id=beatmap_id,
|
||||||
acc=score.accuracy,
|
acc=score.accuracy,
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ from app.calculator import (
|
|||||||
)
|
)
|
||||||
from app.config import settings
|
from app.config import settings
|
||||||
from app.const import BANCHOBOT_ID
|
from app.const import BANCHOBOT_ID
|
||||||
from app.database import BestScore, UserStatistics
|
from app.database import TotalScoreBestScore, UserStatistics
|
||||||
from app.database.beatmap import Beatmap
|
from app.database.beatmap import Beatmap
|
||||||
from app.database.best_scores import PPBestScore
|
from app.database.best_scores import BestScore
|
||||||
from app.database.score import Score, calculate_playtime, calculate_user_pp
|
from app.database.score import Score, calculate_playtime, calculate_user_pp
|
||||||
from app.dependencies.database import engine, get_redis
|
from app.dependencies.database import engine, get_redis
|
||||||
from app.dependencies.fetcher import get_fetcher
|
from app.dependencies.fetcher import get_fetcher
|
||||||
@@ -42,8 +42,8 @@ async def recalculate():
|
|||||||
fetcher = await get_fetcher()
|
fetcher = await get_fetcher()
|
||||||
redis = get_redis()
|
redis = get_redis()
|
||||||
for mode in GameMode:
|
for mode in GameMode:
|
||||||
await session.execute(delete(PPBestScore).where(col(PPBestScore.gamemode) == mode))
|
|
||||||
await session.execute(delete(BestScore).where(col(BestScore.gamemode) == mode))
|
await session.execute(delete(BestScore).where(col(BestScore.gamemode) == mode))
|
||||||
|
await session.execute(delete(TotalScoreBestScore).where(col(TotalScoreBestScore.gamemode) == mode))
|
||||||
await session.commit()
|
await session.commit()
|
||||||
logger.info(f"Recalculating for mode: {mode}")
|
logger.info(f"Recalculating for mode: {mode}")
|
||||||
statistics_list = (
|
statistics_list = (
|
||||||
@@ -63,7 +63,7 @@ async def recalculate():
|
|||||||
)
|
)
|
||||||
await run_in_batches(
|
await run_in_batches(
|
||||||
[
|
[
|
||||||
_recalculate_best_score(statistics.user_id, statistics.mode, session)
|
_recalculate_total_score_best_score(statistics.user_id, statistics.mode, session)
|
||||||
for statistics in statistics_list
|
for statistics in statistics_list
|
||||||
],
|
],
|
||||||
batch_size=200,
|
batch_size=200,
|
||||||
@@ -97,7 +97,7 @@ async def _recalculate_pp(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
).all()
|
).all()
|
||||||
prev: dict[int, PPBestScore] = {}
|
prev: dict[int, BestScore] = {}
|
||||||
|
|
||||||
async def cal(score: Score):
|
async def cal(score: Score):
|
||||||
time = 10
|
time = 10
|
||||||
@@ -120,7 +120,7 @@ async def _recalculate_pp(
|
|||||||
return
|
return
|
||||||
score.pp = pp
|
score.pp = pp
|
||||||
if score.beatmap_id not in prev or prev[score.beatmap_id].pp < pp:
|
if score.beatmap_id not in prev or prev[score.beatmap_id].pp < pp:
|
||||||
best_score = PPBestScore(
|
best_score = BestScore(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
beatmap_id=beatmap_id,
|
beatmap_id=beatmap_id,
|
||||||
acc=score.accuracy,
|
acc=score.accuracy,
|
||||||
@@ -153,13 +153,13 @@ async def _recalculate_pp(
|
|||||||
session.add(best_score)
|
session.add(best_score)
|
||||||
|
|
||||||
|
|
||||||
async def _recalculate_best_score(
|
async def _recalculate_total_score_best_score(
|
||||||
user_id: int,
|
user_id: int,
|
||||||
gamemode: GameMode,
|
gamemode: GameMode,
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
):
|
):
|
||||||
async with SEMAPHORE:
|
async with SEMAPHORE:
|
||||||
beatmap_best_score: dict[int, list[BestScore]] = {}
|
beatmap_best_score: dict[int, list[TotalScoreBestScore]] = {}
|
||||||
scores = (
|
scores = (
|
||||||
await session.exec(
|
await session.exec(
|
||||||
select(Score).where(
|
select(Score).where(
|
||||||
@@ -176,7 +176,7 @@ async def _recalculate_best_score(
|
|||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
mod_for_save = mod_to_save(score.mods)
|
mod_for_save = mod_to_save(score.mods)
|
||||||
bs = BestScore(
|
bs = TotalScoreBestScore(
|
||||||
user_id=score.user_id,
|
user_id=score.user_id,
|
||||||
score_id=score.id,
|
score_id=score.id,
|
||||||
beatmap_id=score.beatmap_id,
|
beatmap_id=score.beatmap_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user